From 0e91b5ed96b6de19fbc5e8c6bd9b754f5d6792d0 Mon Sep 17 00:00:00 2001 From: Herwin Bozet Date: Thu, 20 Feb 2025 17:24:05 +0100 Subject: [PATCH] Implemented tools as applets, Added Docker CCTV page, Fixed small issues Update app.py, uuid-generator.yml, and 47 more files... --- app.py | 94 ++++++------ data/applets/uuid-generator.yml | 8 ++ data/projects/.circuitpython-custom-fs.yml | 35 +++++ ...e-e32.yml => .circuitpython-ebyte-e32.yml} | 0 data/projects/circuitpython-custom-fs.yml | 31 ---- data/projects/docker-mini-cctv-nvr.yml | 34 +++++ data/sidebar.yml | 4 +- data/strings/en/docker-mini-cctv-nvr.yml | 72 ++++++++++ data/strings/en/uuid-generator.yml | 15 +- data/strings/fr/docker-mini-cctv-nvr.yml | 5 + data/strings/fr/uuid-generator.yml | 13 ++ ...emover.yml => .excel-password-remover.yml} | 2 +- .../tools/{svg-to-png.yml => .svg-to-png.yml} | 2 +- data/tools/uuid-generator.yml | 63 ++++---- requirements.txt | 2 +- scripts/compile-js-site.cmd | 4 +- .../uuid-generator/uuid-generator.css | 0 .../applets/uuid-generator/uuid-generator.mjs | 134 ++++++++++++++++++ .../content/docker-mini-cctv-nvr/cam.png | Bin 0 -> 91907 bytes .../content/docker-mini-cctv-nvr/home.png | Bin 0 -> 14728 bytes .../projects/circuitpython-custom-fs/draft.md | 38 +++++ .../tools/uuid-generator/uuid-generator.mjs | 61 -------- templates/applets/uuid-generator.jinja | 44 ++++++ templates/base_standalone.jinja | 3 +- templates/base_www.jinja | 5 +- templates/elements/code.jinja | 5 + templates/elements/list-ul.jinja | 9 ++ templates/elements/paragraph.jinja | 2 +- templates/pages/privacy.jinja | 22 ++- templates/pages/root.jinja | 55 +++---- .../_tool.jinja => pages/tools_page.jinja} | 14 +- templates/projects/_project.jinja | 1 + templates/projects/docker-mini-cctv-nvr.jinja | 131 +++++++++++++++++ templates/tools/uuid-generator.jinja | 38 ----- website/content/__init__.py | 125 +++++++++------- .../content/{metadata.py => dataclasses.py} | 48 +++++++ website/content/project.py | 9 -- website/content/tool.py | 16 --- website/renderers/applet.py | 29 ++++ website/renderers/code.py | 31 ++++ website/renderers/file_input.py | 3 + website/renderers/headings.py | 8 ++ website/renderers/lists.py | 11 ++ 43 files changed, 889 insertions(+), 337 deletions(-) create mode 100644 data/applets/uuid-generator.yml create mode 100644 data/projects/.circuitpython-custom-fs.yml rename data/projects/{circuitpython-ebyte-e32.yml => .circuitpython-ebyte-e32.yml} (100%) delete mode 100644 data/projects/circuitpython-custom-fs.yml create mode 100644 data/projects/docker-mini-cctv-nvr.yml create mode 100644 data/strings/en/docker-mini-cctv-nvr.yml create mode 100644 data/strings/fr/docker-mini-cctv-nvr.yml rename data/tools/{excel-password-remover.yml => .excel-password-remover.yml} (98%) rename data/tools/{svg-to-png.yml => .svg-to-png.yml} (98%) rename static/resources/NibblePoker/{tools => applets}/uuid-generator/uuid-generator.css (100%) create mode 100644 static/resources/NibblePoker/applets/uuid-generator/uuid-generator.mjs create mode 100644 static/resources/NibblePoker/images/content/docker-mini-cctv-nvr/cam.png create mode 100644 static/resources/NibblePoker/images/content/docker-mini-cctv-nvr/home.png create mode 100644 static/resources/NibblePoker/images/projects/circuitpython-custom-fs/draft.md delete mode 100644 static/resources/NibblePoker/tools/uuid-generator/uuid-generator.mjs create mode 100644 templates/applets/uuid-generator.jinja create mode 100644 templates/elements/code.jinja create mode 100644 templates/elements/list-ul.jinja rename templates/{tools/_tool.jinja => pages/tools_page.jinja} (57%) create mode 100644 templates/projects/docker-mini-cctv-nvr.jinja delete mode 100644 templates/tools/uuid-generator.jinja rename website/content/{metadata.py => dataclasses.py} (58%) delete mode 100644 website/content/project.py delete mode 100644 website/content/tool.py create mode 100644 website/renderers/applet.py create mode 100644 website/renderers/code.py create mode 100644 website/renderers/file_input.py diff --git a/app.py b/app.py index 91c9aa2..5761030 100644 --- a/app.py +++ b/app.py @@ -9,22 +9,43 @@ from flask import render_template from minify_html import minify from werkzeug.exceptions import HTTPException -from website.content import reload_content_items, get_articles, get_projects, get_tools, sanitize_input_tags +from website.content import get_articles, get_projects, get_tools, sanitize_input_tags, load_content_items, get_content, \ + get_applets from website.contributors import reload_contributors_data, get_contributors_data from website.domains import ALLOWED_DOMAINS from website.l10n.utils import get_user_lang, localize, reload_strings, l10n_url_abs, l10n_url_switch, L10N, \ DEFAULT_LANG +from website.renderers.applet import render_applet_scripts, render_applet_head from website.renderers.button import render_button -from website.renderers.headings import render_heading, render_h2, render_h1, render_h3 +from website.renderers.code import render_code_block +from website.renderers.headings import render_heading, render_h2, render_h1, render_h3, render_h4 from website.renderers.paragraph import render_paragraph +from website.renderers.lists import render_list_ul from website.renderers.splide import render_splide from website.sidebar import reload_sidebar_entries, get_sidebar_entries from website.sitemap import reload_sitemap_entries, get_sitemap_entries -# try: -# from rich import print -# except ImportError: -# pass +try: + from rich import print +except ImportError: + pass + + +if os.environ.get('NP_HTML_POST_PROCESS', "NONE") == "MINIFY": + print("Using 'minify' as HTML post-processor") + + def post_process_html(html: str) -> str: + return minify(html).replace("> <", "><") +elif os.environ.get('NP_HTML_POST_PROCESS', "NONE") == "BS4": + print("Using 'BeautifulSoup4' as HTML post-processor") + + def post_process_html(html: str) -> str: + return BeautifulSoup(html, features="html.parser").prettify() +else: + print("Using no HTML post-processor") + + def post_process_html(html: str) -> str: + return html app = Flask( @@ -72,24 +93,35 @@ def inject_processors(): domain_host=request.headers['Host'], domain_tld=request.headers['Host'].split('.')[-1] if request.headers['Host'] in ALLOWED_DOMAINS else "lu", domain_url_root=request.url_root, + # L10N l10n=localize, l10n_url_abs=l10n_url_abs, l10n_url_switch=l10n_url_switch, + # Sidebar get_sidebar_entries=get_sidebar_entries, + # Content + get_content=get_content, get_articles=get_articles, get_projects=get_projects, get_tools=get_tools, + # Renderers render_button=render_button, render_heading=render_heading, render_h1=render_h1, render_h2=render_h2, render_h3=render_h3, + render_h4=render_h4, render_paragraph=render_paragraph, + render_list_ul=render_list_ul, render_splide=render_splide, + render_applet_scripts=render_applet_scripts, + render_applet_head=render_applet_head, + render_code_block=render_code_block, + # Commons url_for=url_for, escape=escape, @@ -118,7 +150,7 @@ def route_sitemap(): @app.route('/fr/', defaults={'lang': "fr"}) def route_root(lang: Optional[str]): user_lang = get_user_lang(lang, request.headers.get("HTTP_ACCEPT_LANGUAGE")) - return minify(render_template( + return post_process_html(render_template( "pages/root.jinja", user_lang=user_lang, raw_lang=lang, @@ -132,7 +164,7 @@ def route_root(lang: Optional[str]): @app.route('/fr/contact/', defaults={'lang': "fr"}) def route_contact(lang: Optional[str]): user_lang = get_user_lang(lang, request.headers.get("HTTP_ACCEPT_LANGUAGE")) - return minify(render_template( + return post_process_html(render_template( "pages/contact.jinja", user_lang=user_lang, raw_lang=lang, @@ -152,7 +184,7 @@ def route_content(lang: Optional[str]): except ValueError: requested_tags = None - return minify(render_template( + return post_process_html(render_template( "pages/project_index.jinja", user_lang=user_lang, raw_lang=lang, @@ -178,7 +210,7 @@ def route_content_project(lang: Optional[str], project_id: str): error_code = 404 if error_key is not None: - return minify(render_template( + return post_process_html(render_template( "pages/error.jinja", user_lang=user_lang, raw_lang=lang, @@ -188,7 +220,7 @@ def route_content_project(lang: Optional[str], project_id: str): error_code=error_code, )).replace("> <", "><"), error_code else: - return minify(render_template( + return post_process_html(render_template( "projects/" + project_id + ".jinja", user_lang=user_lang, raw_lang=lang, @@ -210,7 +242,7 @@ def route_tools_index(lang: Optional[str]): except ValueError: requested_tags = None - return minify(render_template( + return post_process_html(render_template( "pages/tools_index.jinja", user_lang=user_lang, raw_lang=lang, @@ -236,7 +268,7 @@ def route_tools_page(lang: Optional[str], tool_id: str): error_code = 404 if error_key is not None: - return minify(render_template( + return post_process_html(render_template( "pages/error.jinja", user_lang=user_lang, raw_lang=lang, @@ -246,14 +278,15 @@ def route_tools_page(lang: Optional[str], tool_id: str): error_code=error_code, )).replace("> <", "><"), error_code else: - return minify(render_template( - "tools/" + tool_id + ".jinja", + return post_process_html(render_template( + "pages/tools_page.jinja", user_lang=user_lang, raw_lang=lang, request_path=request.path, standalone="standalone" in request.args, tool_data=get_tools().get(tool_id), tool_id=tool_id, + applet_data=get_applets().get(get_tools().get(tool_id).applet_id), )).replace("> <", "><") @@ -262,7 +295,7 @@ def route_tools_page(lang: Optional[str], tool_id: str): @app.route('/fr/about/', defaults={'lang': "fr"}) def route_about(lang: Optional[str]): user_lang = get_user_lang(lang, request.headers.get("HTTP_ACCEPT_LANGUAGE")) - return minify(render_template( + return post_process_html(render_template( "pages/about.jinja", user_lang=user_lang, raw_lang=lang, @@ -276,7 +309,7 @@ def route_about(lang: Optional[str]): @app.route('/fr/privacy/', defaults={'lang': "fr"}) def route_privacy(lang: Optional[str]): user_lang = get_user_lang(lang, request.headers.get("HTTP_ACCEPT_LANGUAGE")) - return minify(render_template( + return post_process_html(render_template( "pages/privacy.jinja", user_lang=user_lang, raw_lang=lang, @@ -290,7 +323,7 @@ def route_privacy(lang: Optional[str]): @app.route('/fr/links/', defaults={'lang': "fr"}) def route_links(lang: Optional[str]): user_lang = get_user_lang(lang, request.headers.get("HTTP_ACCEPT_LANGUAGE")) - return minify(render_template( + return post_process_html(render_template( "pages/links.jinja", user_lang=user_lang, raw_lang=lang, @@ -304,7 +337,7 @@ def route_links(lang: Optional[str]): @app.route('/fr/debug/', defaults={'lang': "fr"}) def route_debug(lang: Optional[str]): user_lang = get_user_lang(lang, request.headers.get("HTTP_ACCEPT_LANGUAGE")) - return minify(render_template( + return post_process_html(render_template( "pages/debug.jinja", user_lang=user_lang, raw_lang=lang, @@ -323,7 +356,7 @@ def handle_exception(e: Exception): if isinstance(e, HTTPException): error_code = e.code - return minify(render_template( + return post_process_html(render_template( "pages/error.jinja", user_lang=DEFAULT_LANG, raw_lang=DEFAULT_LANG, @@ -335,7 +368,7 @@ def handle_exception(e: Exception): if __name__ == '__main__': - reload_content_items() + load_content_items() reload_strings(os.path.join(os.getcwd(), "data/strings/")) reload_sidebar_entries(os.path.join(os.getcwd(), "data/sidebar.yml")) reload_contributors_data(os.path.join(os.getcwd(), "data/contributors.yml")) @@ -362,22 +395,3 @@ if __name__ == '__main__': #debug=False, load_dotenv=False ) - -# return BeautifulSoup(render_template( -# "pages/root.jinja", -# lang=user_lang, -# raw_lang=lang, -# request_path=request.path, -# standalone="standalone" in request.args, -# ), features="html.parser").prettify() - -# try: -# from minify_html import minify -# FORCE_NON_DEBUG = False -# except ImportError: -# from bs4 import BeautifulSoup -# FORCE_NON_DEBUG = True -# -# def minify(html): -# return BeautifulSoup(html, features="html.parser").prettify() -# debug=False if FORCE_NON_DEBUG else True, diff --git a/data/applets/uuid-generator.yml b/data/applets/uuid-generator.yml new file mode 100644 index 0000000..49d0333 --- /dev/null +++ b/data/applets/uuid-generator.yml @@ -0,0 +1,8 @@ + +applets: + - id: "uuid-generator" + resources: + scripts: + - "uuid-generator.mjs" + stylesheets: + - "uuid-generator.css" diff --git a/data/projects/.circuitpython-custom-fs.yml b/data/projects/.circuitpython-custom-fs.yml new file mode 100644 index 0000000..449fc8b --- /dev/null +++ b/data/projects/.circuitpython-custom-fs.yml @@ -0,0 +1,35 @@ + +projects: + - id: "circuitpython-custom-fs" + metadata: + head: + title_key: "meta.title" + description_key: "meta.description" + opengraph: + title_key: "meta.title" + description_key: "meta.description" + type: null + url: null + image_url: "/resources/NibblePoker/images/content/circuitpython-ebyte-e32/main.png" + image_type: null + twitter: + title_key: "meta.title" + description_key: "meta.description" + index: + priority: 105 + enable: true + title_key: "meta.title" + preamble_key: "meta.description" + image_url: "/resources/NibblePoker/images/content/circuitpython-ebyte-e32/main.png" + image_alt_key: "" + general: + icon: "fab fa-python" + title_key: "meta.title" + subtitle_key: "article.subtitle" + tags: + - "experiments" + - "electronic" + - "python" + - "circuitpython" + languages: + - "python" diff --git a/data/projects/circuitpython-ebyte-e32.yml b/data/projects/.circuitpython-ebyte-e32.yml similarity index 100% rename from data/projects/circuitpython-ebyte-e32.yml rename to data/projects/.circuitpython-ebyte-e32.yml diff --git a/data/projects/circuitpython-custom-fs.yml b/data/projects/circuitpython-custom-fs.yml deleted file mode 100644 index eb5ff87..0000000 --- a/data/projects/circuitpython-custom-fs.yml +++ /dev/null @@ -1,31 +0,0 @@ -head: - title_key: "meta.title" - description_key: "meta.description" -opengraph: - title_key: "meta.title" - description_key: "meta.description" - type: null - url: null - image_url: "/resources/NibblePoker/images/content/circuitpython-ebyte-e32/main.png" - image_type: null -twitter: - title_key: "meta.title" - description_key: "meta.description" -index: - priority: 105 - enable: true - title_key: "meta.title" - preamble_key: "meta.description" - image_url: "/resources/NibblePoker/images/content/circuitpython-ebyte-e32/main.png" - image_alt_key: "" -general: - icon: "fab fa-python" - title_key: "meta.title" - subtitle_key: "article.subtitle" - tags: - - "experiments" - - "electronic" - - "python" - - "circuitpython" - languages: - - "python" diff --git a/data/projects/docker-mini-cctv-nvr.yml b/data/projects/docker-mini-cctv-nvr.yml new file mode 100644 index 0000000..91f271c --- /dev/null +++ b/data/projects/docker-mini-cctv-nvr.yml @@ -0,0 +1,34 @@ + +projects: + - id: "docker-mini-cctv-nvr" + metadata: + head: + title_key: "meta.title" + description_key: "meta.description" + opengraph: + title_key: "meta.title" + description_key: "meta.description" + type: null + url: null + image_url: "/resources/NibblePoker/images/content/docker-mini-cctv-nvr/main.png" + image_type: null + twitter: + title_key: "meta.title" + description_key: "meta.description" + index: + priority: 105 + enable: true + title_key: "meta.title" + preamble_key: "meta.description" + image_url: "/resources/NibblePoker/images/content/docker-mini-cctv-nvr/main.png" + image_alt_key: "" + general: + icon: "fab fa-docker" + title_key: "meta.title" + subtitle_key: "article.subtitle" + tags: + - "docker" + languages: + - "docker" + - "php" + - "python" diff --git a/data/sidebar.yml b/data/sidebar.yml index 03318ba..b1bca51 100644 --- a/data/sidebar.yml +++ b/data/sidebar.yml @@ -42,13 +42,13 @@ abs_href: "/tools" icon: fad fa-toolbox active_id: tools - has_new_until_utc: 0 + has_new_until_utc: 1760986472 - title_key: text.downloads raw_href: "https://files.nibblepoker.lu/" icon: fad fa-download active_id: "" - has_new_until_utc: 1760986472 + has_new_until_utc: 0 - diff --git a/data/strings/en/docker-mini-cctv-nvr.yml b/data/strings/en/docker-mini-cctv-nvr.yml new file mode 100644 index 0000000..beb53bc --- /dev/null +++ b/data/strings/en/docker-mini-cctv-nvr.yml @@ -0,0 +1,72 @@ +# EN - Docker Mini CCTV NVR + +meta.title: "Mini Dockerized CCTV NVR" +meta.description: "Mini docker stack that allows you to easily record, clean and serve CCTV recordings made +over RSTP while using a minimal amount of system resources." + +intro.title: "Introduction" +intro.1: "A mini docker stack that allows you to easily record, clean and serve CCTV recordings made +over RSTP while using a minimal amount of system resources." +intro.2: "This stack is mainly intended to be used as a backup when other and more complete solutions crash or +need to be shutdown.This simple docker stack aims to provide you with a simple, +lightweight and robust NVR for all of your RTSP-based CCTV cameras." + +preamble.title: "Preamble" +preamble.1: "This stack records the camera's streams as-is and doesn't re-encode or compress it which uses more disk space. +See \"Usage statistics example\" for an example." +preamble.2: "If served out of your LAN, the web server should be behind a secure reverse-proxy that requires authentication." + +setup.title: "Setup" +setup.1: "All of the setup is done through environment variables in the docker-compose.yml file." +setup.2: "It should only take 2-3 minutes if you already have the RTSP URL on hand.
+If you don't have them, you should see your camera's user manual and test the URLs with VLC." + +setup.camera.title: "Cameras" +setup.camera.1: "Each recording container needs to be given a RSTP stream URL and a unique folder +into which the recordings will go." +setup.camera.2: "The URL must be given via the NP_CCTV_URL environment variable, +and the output folder via a mounted volume that is mounted as /data in the container." +setup.camera.3: "This example will use the rtsp://user:password@address:554/sub-path +URL and will put its recordings in ./recordings/cam1." + +setup.cleaner.title: "Cleaner" +setup.cleaner.1: "The cleaner script named cleaner.py only requires you to set 1 environment variable named +NP_MAX_FILE_AGE_HOURS to the max amount of hours any recording should be kept." +setup.cleaner.2: "If not set, the script will simply clean any recordings older than 72 hours." + +setup.web.title: "Web interface" +setup.web.1: "The web interface provides more customization options, but at its core, +it only requires the camera's environment variables to be set." +setup.web.2: "Each camera requires one of the following environment variable:
+  NP_CAM_<camId> = <Camera's name>" +setup.web.3: "Here is an example for cam1 if named as Camera #1:
+  NP_CAM_cam1 = Camera #1" +setup.web.vars.title: "Other variables" +setup.web.vars.description.title: "Page's title" +setup.web.vars.description.footer: "Page's footer HTML content" + +startup.title: "Startup" +startup.1: "Once you have finished setting up the stack, you can simply run the following command:" +#docker-compose up --build -d + +screenshots.title: "Screenshots" + +statistics.title: "Usage statistics example" +statistics.1: "NanoPi R4S 4GB" +statistics.1.1: "Uses 0.008 kWh / 8 Watts with other containers and USB HDD & USB SSD" +statistics.2: "4 IP Cameras" +statistics.2.1: "All H.256 4k RTSP TCP streams" +statistics.2.2: "Around 220 GB of data per day" +statistics.2.2.1: "Around 20.4 Mbit/s or 2.6 MB/s" +statistics.3: "Less than 200MB of RAM usage" +statistics.3.1: "~32 MB per recorder" +statistics.3.2: "4 MB for cleaner" +statistics.3.3: "4 MB for web server" +statistics.4: "Uses ~10% of CPU on average over 6 cores" +statistics.4.1: "Average of 15% per recorder" +statistics.4.2: "Average of 1-5% on cleaner and web server" + +license.title: "License" +license.1: "This software, as well as the Simplette CSS Stylesheet used for the web interface are both licensed under Unlicense." + +commons.example: "Example" diff --git a/data/strings/en/uuid-generator.yml b/data/strings/en/uuid-generator.yml index 2d199aa..a8e9688 100644 --- a/data/strings/en/uuid-generator.yml +++ b/data/strings/en/uuid-generator.yml @@ -1,4 +1,17 @@ # EN - UUID Generator -option.count: "UUID/GUID count" +meta.title: "UUID Generator" + +type.label: "UUID Type" + +type.uuid4: "UUID4 / GUID4" + +option.count: "UUID Count" option.hyphen: "Add hyphens" +option.guid_brackets: "Add GUID brackets" + +generate: "Generate" + +download.raw: "Raw" +download.json: "JSON" +download.yaml: "YAML" diff --git a/data/strings/fr/docker-mini-cctv-nvr.yml b/data/strings/fr/docker-mini-cctv-nvr.yml new file mode 100644 index 0000000..860f676 --- /dev/null +++ b/data/strings/fr/docker-mini-cctv-nvr.yml @@ -0,0 +1,5 @@ +# FR - Docker Mini CCTV NVR + +meta.title: "Mini Dockerized CCTV NVR" +meta.description: "Mini docker stack that allows you to easily record, clean and serve CCTV recordings made +over RSTP while using a minimal amount of system resources." diff --git a/data/strings/fr/uuid-generator.yml b/data/strings/fr/uuid-generator.yml index dcf7ed5..4764856 100644 --- a/data/strings/fr/uuid-generator.yml +++ b/data/strings/fr/uuid-generator.yml @@ -1,4 +1,17 @@ # FR - UUID Generator +meta.title: "Générateur d'UUID" + +type.label: "Type d'UUID" + +type.uuid4: "UUID4 / GUID4" + option.count: "Nombre d'UUID/GUID" option.hyphen: "Ajouter trait d'union" +option.guid_brackets: "Ajouter accolades pour GUID" + +generate: "Générer" + +download.raw: "Brut" +download.json: "JSON" +download.yaml: "YAML" diff --git a/data/tools/excel-password-remover.yml b/data/tools/.excel-password-remover.yml similarity index 98% rename from data/tools/excel-password-remover.yml rename to data/tools/.excel-password-remover.yml index 892cc5a..9f4d2e5 100644 --- a/data/tools/excel-password-remover.yml +++ b/data/tools/.excel-password-remover.yml @@ -25,6 +25,6 @@ metadata: subtitle_key: "article.subtitle" tags: - "undefined" -data: +resources: scripts: - "epr_main.js" diff --git a/data/tools/svg-to-png.yml b/data/tools/.svg-to-png.yml similarity index 98% rename from data/tools/svg-to-png.yml rename to data/tools/.svg-to-png.yml index db09100..653ad52 100644 --- a/data/tools/svg-to-png.yml +++ b/data/tools/.svg-to-png.yml @@ -25,7 +25,7 @@ metadata: subtitle_key: "article.subtitle" tags: - "undefined" -data: +resources: scripts: - "svg-to-png.mjs" stylesheets: diff --git a/data/tools/uuid-generator.yml b/data/tools/uuid-generator.yml index 4f39007..b1fa463 100644 --- a/data/tools/uuid-generator.yml +++ b/data/tools/uuid-generator.yml @@ -1,32 +1,31 @@ -metadata: - head: - title_key: "meta.title" - description_key: "meta.description" - opengraph: - title_key: "meta.title" - description_key: "meta.description" - type: null - url: null - image_url: "/resources/NibblePoker/images/tools/excel-password-remover/excel-password-remover.png" - image_type: null - twitter: - title_key: "meta.title" - description_key: "meta.description" - index: - priority: 100 - enable: true - title_key: "meta.title" - preamble_key: "meta.description" - image_url: "/resources/NibblePoker/images/tools/excel-password-remover/excel-password-remover.png" - image_alt_key: "" - general: - icon: "fab fa-python" - title_key: "meta.title" - subtitle_key: "article.subtitle" - tags: - - "undefined" -data: - scripts: - - "uuid-generator.mjs" - stylesheets: - - "uuid-generator.css" + +tools: + - id: "uuid-generator" + applet_id: "uuid-generator" + metadata: + head: + title_key: "meta.title" + description_key: "meta.description" + opengraph: + title_key: "meta.title" + description_key: "meta.description" + type: null + url: null + image_url: "/resources/NibblePoker/images/tools/excel-password-remover/excel-password-remover.png" + image_type: null + twitter: + title_key: "meta.title" + description_key: "meta.description" + index: + priority: 100 + enable: true + title_key: "meta.title" + preamble_key: "meta.description" + image_url: "/resources/NibblePoker/images/tools/excel-password-remover/excel-password-remover.png" + image_alt_key: "" + general: + icon: "fab fa-python" + title_key: "meta.title" + subtitle_key: "article.subtitle" + tags: + - "undefined" diff --git a/requirements.txt b/requirements.txt index fe9dfb9..503a550 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,4 +10,4 @@ locked-dict Werkzeug~=3.0.4 #gunicorn -waitress~=3.0.0 +waitress~=3.0.2 diff --git a/scripts/compile-js-site.cmd b/scripts/compile-js-site.cmd index 1b0cda2..89446a6 100644 --- a/scripts/compile-js-site.cmd +++ b/scripts/compile-js-site.cmd @@ -39,8 +39,8 @@ popd :js-uuidgenerator-minify echo Minifying UUID Generator pushd %CD% -cd %~dp0\..\static\resources\NibblePoker\tools\uuid-generator\ -echo ^> static\resources\NibblePoker\tools\svg-to-png\svg-to-png.mjs +cd %~dp0\..\static\resources\NibblePoker\applets\uuid-generator\ +echo ^> static\resources\NibblePoker\applets\uuid-generator\uuid-generator.mjs call "%~dp0node_modules\.bin\rollup" uuid-generator.mjs --file uuid-generator.js call "%~dp0node_modules\.bin\terser" uuid-generator.js -c -m -o uuid-generator.min.js popd diff --git a/static/resources/NibblePoker/tools/uuid-generator/uuid-generator.css b/static/resources/NibblePoker/applets/uuid-generator/uuid-generator.css similarity index 100% rename from static/resources/NibblePoker/tools/uuid-generator/uuid-generator.css rename to static/resources/NibblePoker/applets/uuid-generator/uuid-generator.css diff --git a/static/resources/NibblePoker/applets/uuid-generator/uuid-generator.mjs b/static/resources/NibblePoker/applets/uuid-generator/uuid-generator.mjs new file mode 100644 index 0000000..1fd9aef --- /dev/null +++ b/static/resources/NibblePoker/applets/uuid-generator/uuid-generator.mjs @@ -0,0 +1,134 @@ +/** + * Generates a random UUID4 and returns its string representation + * @returns {`${string}-${string}-${string}-${string}-${string}`} + */ +export function generateUUID4(addHyphens, addGuidBrackets) { + let uuid4 = crypto.randomUUID(); + if(!addHyphens) { + uuid4 = uuid4.replace(/-/g, ""); + } + if(addGuidBrackets) { + uuid4 = "{" + uuid4 + "}"; + } + return uuid4; +} + +// Tool-centric stuff +{ + /** @type {HTMLSelectElement} */ + const eOptionTypeSelect = document.querySelector("select#uuid-generator-option-type"); + + /** @type {HTMLInputElement} */ + const eOptionCountInput = document.querySelector("input#uuid-generator-option-count"); + + /** @type {HTMLInputElement} */ + const eOptionHyphenInput = document.querySelector("input#uuid-generator-option-hyphens"); + /** @type {HTMLInputElement} */ + const eOptionGuidBracketsInput = document.querySelector("input#uuid-generator-option-guid-brackets"); + + /** @type {HTMLElement} */ + const eGenerateButton = document.querySelector("#uuid-generator-generate"); + /** @type {HTMLElement} */ + const eDownloadRawButton = document.querySelector("#uuid-generator-download-raw"); + /** @type {HTMLElement} */ + const eDownloadJsonButton = document.querySelector("#uuid-generator-download-json"); + /** @type {HTMLElement} */ + const eDownloadYamlButton = document.querySelector("#uuid-generator-download-yaml"); + + /** @type {HTMLTextAreaElement} */ + const ePreviewTextArea = document.querySelector("textarea#uuid-generator-preview"); + + let lastUUIDs = []; + + /** @returns {number} */ + function getDesiredCount() { + let desiredCount = null; + try { + desiredCount = parseInt(eOptionCountInput.value); + } catch (e) { + console.error(e); + } + if(desiredCount === null) { + desiredCount = 1; + } + if(desiredCount < 1) { + desiredCount = 1; + } + if(desiredCount > 1000) { + desiredCount = 1000; + } + return desiredCount; + } + + function changeDesiredCount(difference = 0) { + if(difference !== 0) { + eOptionCountInput.value = getDesiredCount() + difference; + } + eOptionCountInput.value = getDesiredCount(); + } + + + function downloadStringAsFile(content, filename, contentType) { + const blob = new Blob([content], { type: contentType }); + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + + link.href = url; + link.download = filename; + + document.body.appendChild(link); + link.click(); + + document.body.removeChild(link); + URL.revokeObjectURL(url); + } + + window.onload = function () { + eGenerateButton.addEventListener("click", function() { + ePreviewTextArea.value = ""; + + let desiredCount = getDesiredCount(); + let uuidGenerator = generateUUID4; + + let addHyphens = eOptionHyphenInput.checked; + let addGuidBrackets = eOptionGuidBracketsInput.checked; + + lastUUIDs = []; + for(let i= 0; i < desiredCount; i++) { + lastUUIDs.push(uuidGenerator(addHyphens, addGuidBrackets)); + ePreviewTextArea.value += uuidGenerator(addHyphens, addGuidBrackets) + "\n"; + } + ePreviewTextArea.value = lastUUIDs.join("\n"); + }); + eOptionCountInput.addEventListener("change", function() { + changeDesiredCount(0); + }); + eOptionCountInput.addEventListener("mousewheel", function(e) { + // Handling wheel scroll on count field. + if(e.wheelDelta < 0) { + changeDesiredCount(-1); + } else { + changeDesiredCount(1); + } + }); + + eDownloadRawButton.addEventListener("click", function() { + if (lastUUIDs.length <= 0) { + return; + } + downloadStringAsFile(lastUUIDs.join("\n"), "uuids.txt", "text/plain"); + }); + eDownloadJsonButton.addEventListener("click", function() { + if (lastUUIDs.length <= 0) { + return; + } + downloadStringAsFile(JSON.stringify(lastUUIDs, null, 4), "uuids.json", "application/json"); + }); + eDownloadYamlButton.addEventListener("click", function() { + if (lastUUIDs.length <= 0) { + return; + } + downloadStringAsFile("- \"" + lastUUIDs.join("\"\n- \"") + "\"", "uuids.yaml", "text/yaml"); + }); + } +} diff --git a/static/resources/NibblePoker/images/content/docker-mini-cctv-nvr/cam.png b/static/resources/NibblePoker/images/content/docker-mini-cctv-nvr/cam.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5bb0ae2c413824768ee1d5d3323eb9c330e7a1 GIT binary patch literal 91907 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 1000) { - desiredCount = 1000; - } - return desiredCount; - } - - window.onload = function () { - eGenerateButton.addEventListener("click", function() { - ePreviewTextArea.value = ""; - - let desiredCount = getDesiredCount(); - let uuidGenerator = generateUUID4; - - for(let i= 0; i < desiredCount; i++) { - ePreviewTextArea.value += uuidGenerator() + "\n"; - } - }); - eDownloadButton.addEventListener("click", function() { - //eFileDropInput.click(); - }); - } -} diff --git a/templates/applets/uuid-generator.jinja b/templates/applets/uuid-generator.jinja new file mode 100644 index 0000000..3189053 --- /dev/null +++ b/templates/applets/uuid-generator.jinja @@ -0,0 +1,44 @@ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + +
+ + + diff --git a/templates/base_standalone.jinja b/templates/base_standalone.jinja index 5058f2f..f055e3e 100644 --- a/templates/base_standalone.jinja +++ b/templates/base_standalone.jinja @@ -10,7 +10,8 @@ - + + diff --git a/templates/base_www.jinja b/templates/base_www.jinja index adebbed..ad720e2 100644 --- a/templates/base_www.jinja +++ b/templates/base_www.jinja @@ -19,7 +19,8 @@ {% block extra_preloads %}{% endblock %} - + + {% block extra_stylesheets %}{% endblock %} @@ -114,4 +115,4 @@ {% block extra_scripts %}{% endblock %} - \ No newline at end of file + diff --git a/templates/elements/code.jinja b/templates/elements/code.jinja new file mode 100644 index 0000000..2bbe724 --- /dev/null +++ b/templates/elements/code.jinja @@ -0,0 +1,5 @@ + + {% for code_line in code_lines %} + {{ code_line }}
+ {% endfor %} +
diff --git a/templates/elements/list-ul.jinja b/templates/elements/list-ul.jinja new file mode 100644 index 0000000..7f49d12 --- /dev/null +++ b/templates/elements/list-ul.jinja @@ -0,0 +1,9 @@ +
    + {% for list_item in list_items %} + {% if list_item.__class__.__name__ == 'list' %} + {{ render_list_ul(list_item) }} + {% else %} +
  • {{ list_item }}
  • + {% endif %} + {% endfor %} +
diff --git a/templates/elements/paragraph.jinja b/templates/elements/paragraph.jinja index 4bf8294..e05fae6 100644 --- a/templates/elements/paragraph.jinja +++ b/templates/elements/paragraph.jinja @@ -1,3 +1,3 @@ -

+

{{ paragraph_inner_html }}

\ No newline at end of file diff --git a/templates/pages/privacy.jinja b/templates/pages/privacy.jinja index cbf402b..6c4fe5c 100644 --- a/templates/pages/privacy.jinja +++ b/templates/pages/privacy.jinja @@ -17,22 +17,20 @@ {{ render_paragraph(l10n("introduction.text.1", "privacy", user_lang)) }} {{ render_paragraph(l10n("introduction.text.2", "privacy", user_lang) + '
- - https://gdpr.eu/ -
+ https://gdpr.eu/
- - https://eur-lex.europa.eu/ - ')}} + https://eur-lex.europa.eu/')}} {{ render_h1(l10n("v2.data.title", "privacy", user_lang), "fad fa-database") }} {{ render_paragraph(l10n("v2.data.intro.1", "privacy", user_lang) + '
' + l10n("v2.data.intro.2", "privacy", user_lang)) }} {{ render_paragraph(l10n('v2.data.private.1', "privacy", user_lang) + - '
  • ' + l10n('v2.data.private_list.1', "privacy", user_lang) + - '
  • ' + l10n('v2.data.private_list.2', "privacy", user_lang) + - '
') }} + render_list_ul([ + l10n('v2.data.private_list.1', "privacy", user_lang), + l10n('v2.data.private_list.2', "privacy", user_lang), + ]) + ) }} {{ render_paragraph(l10n('v2.data.non_private.1', "privacy", user_lang) + '
  • ' + l10n('v2.data.non_private_list.1', "privacy", user_lang) + '
  • ' + l10n('v2.data.non_private_list.2', "privacy", user_lang) + @@ -167,17 +165,17 @@ {{ render_h1(l10n("contact.title", "privacy", user_lang), "fad fa-mailbox") }} {{ render_paragraph(l10n("contact.text.1", "privacy", user_lang) + - '
    herwin.bozet@gmail.com') }} + '
    herwin.bozet@gmail.com') }} {{ render_h1(l10n("complaint.title", "privacy", user_lang), "fad fa-gavel") }} {{ render_paragraph(l10n("complaint.text.1", "privacy", user_lang)) }} {{ render_paragraph(l10n('complaint.text.2', "privacy", user_lang) + '
    ' + - 'https://ec.europa.eu/' + + 'https://ec.europa.eu/' + '(' + l10n('english', "langs", user_lang) + ')' + '
    ' + - 'https://gegevensbeschermingsautoriteit.be/' + + 'https://gegevensbeschermingsautoriteit.be/' + '(' + l10n('french', "langs", user_lang) + ')' ) }} {% endblock %} diff --git a/templates/pages/root.jinja b/templates/pages/root.jinja index e7fb338..e52f5a2 100644 --- a/templates/pages/root.jinja +++ b/templates/pages/root.jinja @@ -20,34 +20,35 @@ {{ render_h2(l10n("updates.title", "home", user_lang)) }} -

    {{ l10n("updates.4.date", "home", user_lang) }}

    -
      -
    • {{ l10n("updates.4.text.1", "home", user_lang) }}
    • -
    • {{ l10n("updates.4.text.2", "home", user_lang) }}
    • -
    • {{ l10n("updates.4.text.3", "home", user_lang) }}
    • -
    • {{ l10n("updates.text.privacy", "home", user_lang) }}
    • -
    +

    {{ l10n("updates.4.date", "home", user_lang) }}

    + {{ render_list_ul([ + l10n("updates.4.text.1", "home", user_lang), + l10n("updates.4.text.2", "home", user_lang), + l10n("updates.4.text.3", "home", user_lang), + l10n("updates.text.privacy", "home", user_lang) + ]) }} -

    {{ l10n("updates.3.date", "home", user_lang) }}

    -
      -
    • {{ l10n("updates.3.text.1", "home", user_lang) }}
    • -
    • {{ l10n("updates.3.text.2", "home", user_lang) }}
    • -
    • {{ l10n("updates.3.text.3", "home", user_lang) }}
    • -
    • {{ l10n("updates.text.privacy", "home", user_lang) }}
    • -
    +

    {{ l10n("updates.3.date", "home", user_lang) }}

    + {{ render_list_ul([ + l10n("updates.3.text.1", "home", user_lang), + l10n("updates.3.text.2", "home", user_lang), + l10n("updates.3.text.3", "home", user_lang), + l10n("updates.text.privacy", "home", user_lang) + ]) }} -

    {{ l10n("updates.2.date", "home", user_lang) }}

    -
      -
    • {{ l10n("updates.2.text.1", "home", user_lang) }}
    • -
    • {{ l10n("updates.2.text.2", "home", user_lang) }}
    • -
    • {{ l10n("updates.2.text.3", "home", user_lang) }}
    • -
    • {{ l10n("updates.2.text.4", "home", user_lang) }}
    • -
    • {{ l10n("updates.text.privacy", "home", user_lang) }}
    • -
    +

    {{ l10n("updates.2.date", "home", user_lang) }}

    + {{ render_list_ul([ + l10n("updates.2.text.1", "home", user_lang), + l10n("updates.2.text.2", "home", user_lang), + l10n("updates.2.text.3", "home", user_lang), + l10n("updates.2.text.4", "home", user_lang), + l10n("updates.text.privacy", "home", user_lang) + ]) }} + +

    {{ l10n("updates.1.date", "home", user_lang) }}

    + {{ render_list_ul([ + l10n("updates.1.text.1", "home", user_lang), + l10n("updates.text.privacy", "home", user_lang) + ]) }} -

    {{ l10n("updates.1.date", "home", user_lang) }}

    -
      -
    • {{ l10n("updates.1.text.1", "home", user_lang) }}
    • -
    • {{ l10n("updates.text.privacy", "home", user_lang) }}
    • -
    {% endblock %} diff --git a/templates/tools/_tool.jinja b/templates/pages/tools_page.jinja similarity index 57% rename from templates/tools/_tool.jinja rename to templates/pages/tools_page.jinja index 0f7e83b..281ea34 100644 --- a/templates/tools/_tool.jinja +++ b/templates/pages/tools_page.jinja @@ -4,9 +4,7 @@ {% block head_description %}{{ l10n(tool_data.metadata.head.description_key, tool_id, user_lang) }}{% endblock %} {% block extra_stylesheets %} - {% for tool_stylesheet in tool_data.data.stylesheets %} - - {% endfor %} + {{ render_applet_head(applet_data) }} {% endblock %} {% block header_title %} @@ -21,16 +19,10 @@ ) }}
    - {% block tool_content %}{% endblock %} + {% include 'applets/'+applet_data.id+'.jinja' %}
    {% endblock %} {% block extra_scripts %} - {% for tool_script in tool_data.data.scripts %} - {% if tool_script.endswith(".mjs") %} - - {% else %} - - {% endif %} - {% endfor %} + {{ render_applet_scripts(applet_data) }} {% endblock %} diff --git a/templates/projects/_project.jinja b/templates/projects/_project.jinja index 130dc35..cf1d69e 100644 --- a/templates/projects/_project.jinja +++ b/templates/projects/_project.jinja @@ -38,4 +38,5 @@ + {% endblock %} diff --git a/templates/projects/docker-mini-cctv-nvr.jinja b/templates/projects/docker-mini-cctv-nvr.jinja new file mode 100644 index 0000000..f8c9b8f --- /dev/null +++ b/templates/projects/docker-mini-cctv-nvr.jinja @@ -0,0 +1,131 @@ +{% extends "projects/_project.jinja" %} + +{% block project_content %} + {{ render_h2(l10n("intro.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("intro.1", project_id, user_lang)) }} + {{ render_paragraph(l10n("intro.2", project_id, user_lang)) }} + + {{ render_h2(l10n("preamble.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("preamble.1", project_id, user_lang)) }} + {{ render_paragraph(l10n("preamble.2", project_id, user_lang)) }} + + {{ render_h2(l10n("setup.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.1", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.2", project_id, user_lang)) }} + + {{ render_h3(l10n("setup.camera.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.camera.1", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.camera.2", project_id, user_lang)) }} + {{ render_h4(l10n("commons.example", project_id, user_lang)) }} + {{ + render_code_block([ + "nvr_stack:", + " cctv_recorder_cam1:", + " container_name: cctv-recorder-cam1", + " build:", + " context: .", + " dockerfile: Dockerfile_recorder", + " environment:", + " - TZ=Europe/Brussels", + " - \"NP_CCTV_URL=rtsp://user:password@address:554/sub-path\"", + " volumes:", + " - ./recordings/cam1:/data", + " restart: unless-stopped", + ], "yaml") + }} + {{ render_paragraph(l10n("setup.camera.3", project_id, user_lang)) }} + + {{ render_h3(l10n("setup.cleaner.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.cleaner.1", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.cleaner.2", project_id, user_lang)) }} + {{ render_h4(l10n("commons.example", project_id, user_lang)) }} + {{ + render_code_block([ + "nvr_stack:", + " cctv_cleaner:", + " container_name: cctv-cleaner", + " build:", + " context: .", + " dockerfile: Dockerfile_cleaner", + " environment:", + " - TZ=Europe/Brussels", + " - \"NP_MAX_FILE_AGE_HOURS=72\"", + " volumes:", + " - ./recordings:/data", + " - ./cleaner.py:/app/app.py:ro", + " restart: unless-stopped", + ], "yaml") + }} + + {{ render_h3(l10n("setup.web.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.web.1", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.web.2", project_id, user_lang)) }} + {{ render_paragraph(l10n("setup.web.3", project_id, user_lang)) }} + {{ render_h4(l10n("commons.web.vars.title", project_id, user_lang)) }} + {{ render_h4(l10n("commons.example", project_id, user_lang)) }} + {{ + render_code_block([ + "nvr_stack:", + " cctv_web:", + " container_name: cctv-web", + " image: php:apache", + " ports:", + " - 26880:80", + " environment:", + " - TZ=Europe/Brussels", + " - \"NP_CAM_cam1=Camera #1\"", + " - \"NP_CAM_cam2=Camera #2\"", + " - \"NP_TITLE=NibblePoker's Mini CCTV NVR\"", + " - \"NP_FOOTER=Made by BOZET Herwin\"", + " volumes:", + " - ./htdocs:/var/www/html # Cannot be \":ro\" since the recordings are mounted into it.", + " - ./apache2.conf:/etc/apache2/apache2.conf:ro", + " - ./recordings:/var/www/html/data:ro", + " restart: unless-stopped", + ], "yaml") + }} + + {{ render_h2(l10n("startup.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("startup.1", project_id, user_lang)) }} + {{ + render_code_block([ + "docker-compose up --build -d", + ], "bash") + }} + + {{ render_h2(l10n("screenshots.title", project_id, user_lang)) }} + {{ render_splide([ + '', + '', + ]) }} + + {{ render_h2(l10n("statistics.title", project_id, user_lang)) }} + {{ render_list_ul([ + l10n("statistics.1", project_id, user_lang), + [ + l10n("statistics.1.1", project_id, user_lang), + ], + l10n("statistics.2", project_id, user_lang), + [ + l10n("statistics.2.1", project_id, user_lang), + l10n("statistics.2.2", project_id, user_lang), + [ + l10n("statistics.2.2.1", project_id, user_lang), + ], + ], + l10n("statistics.3", project_id, user_lang), + [ + l10n("statistics.3.1", project_id, user_lang), + l10n("statistics.3.2", project_id, user_lang), + l10n("statistics.3.3", project_id, user_lang), + ], + l10n("statistics.4", project_id, user_lang), + [ + l10n("statistics.4.1", project_id, user_lang), + l10n("statistics.4.2", project_id, user_lang), + ], + ]) }} + + {{ render_h2(l10n("license.title", project_id, user_lang)) }} + {{ render_paragraph(l10n("license.1", project_id, user_lang)) }} +{% endblock %} diff --git a/templates/tools/uuid-generator.jinja b/templates/tools/uuid-generator.jinja deleted file mode 100644 index 3b018b2..0000000 --- a/templates/tools/uuid-generator.jinja +++ /dev/null @@ -1,38 +0,0 @@ -{% extends "tools/_tool.jinja" %} - -{% block tool_content %} - -
    - - - - -
    - - - - -
    - - - - -
    - - - - -
    - - - -
    - -{% endblock %} diff --git a/website/content/__init__.py b/website/content/__init__.py index 3897f4b..d560493 100644 --- a/website/content/__init__.py +++ b/website/content/__init__.py @@ -5,31 +5,52 @@ from typing import Any from locked_dict.locked_dict import LockedDict import yaml -from .metadata import ContentMetadata -from .project import ContentProject -from .tool import ContentTool, ContentToolData +from .dataclasses import * +__CONTENT: ContentRoot = ContentRoot() + +__CONTENT_APPLETS: LockedDict[str, ContentApplet] = LockedDict() __CONTENT_ARTICLES: LockedDict = LockedDict() __CONTENT_PROJECTS: LockedDict[str, ContentProject] = LockedDict() __CONTENT_TOOLS: LockedDict[str, ContentTool] = LockedDict() +def get_content() -> ContentRoot: + return __CONTENT + + +def get_applets() -> LockedDict[str, ContentApplet]: + return __CONTENT.applets + + def get_articles() -> LockedDict: return __CONTENT_ARTICLES def get_projects() -> LockedDict[str, ContentProject]: - return __CONTENT_PROJECTS + return __CONTENT.projects def get_projects_by_tags(tags: list[str]) -> dict[Any, ContentProject]: project_obj: ContentProject return { - project_key: project_value for project_key, project_value in __CONTENT_PROJECTS.items() + project_key: project_value for project_key, project_value in __CONTENT.projects.items() if any(tag in project_value.metadata.general.tags for tag in tags) } +def get_tools() -> LockedDict[str, ContentTool]: + return __CONTENT.tools + + +def get_tools_by_tags(tags: list[str]) -> dict[Any, ContentProject]: + tool_obj: ContentProject + return { + tool_key: tool_value for tool_key, tool_value in __CONTENT.tools.items() + if any(tag in tool_value.metadata.general.tags for tag in tags) + } + + def sanitize_input_tags(input_tags: str) -> list[str]: tags: list[str] = input_tags.split(";") for tag in tags: @@ -38,34 +59,50 @@ def sanitize_input_tags(input_tags: str) -> list[str]: return tags -def get_tools() -> LockedDict: - return __CONTENT_TOOLS +def load_content_items() -> None: + global __CONTENT + __CONTENT = ContentRoot() -def get_tools_by_tags(tags: list[str]) -> dict[Any, ContentProject]: - tool_obj: ContentProject - return { - tool_key: tool_value for tool_key, tool_value in __CONTENT_TOOLS.items() - if any(tag in tool_value.metadata.general.tags for tag in tags) - } + # Loading applets definition files + for applets_file in os.listdir(os.path.join(os.getcwd(), "data/applets")): + applets_file_path = os.path.join(os.getcwd(), "data/applets", applets_file) + if not os.path.isfile(applets_file_path) or applets_file.startswith("."): + continue + applets_data = yaml.safe_load(open(applets_file_path)) + if "applets" not in applets_data: + print(f"Unable to load '{applets_file_path}' due to missing 'applets' field !") + continue -def reload_content_items() -> None: - global __CONTENT_ARTICLES - global __CONTENT_PROJECTS - global __CONTENT_TOOLS + for applet_data in applets_data["applets"]: + _applet = ContentApplet(**applet_data) + __CONTENT.applets[_applet.id] = _applet - __CONTENT_ARTICLES = LockedDict() - __CONTENT_PROJECTS = LockedDict() - __CONTENT_TOOLS = LockedDict() - - for article_folder in os.listdir(os.path.join(os.getcwd(), "data/articles")): + # Loading articles definition files + """for article_folder in os.listdir(os.path.join(os.getcwd(), "data/articles")): article_folder_path = os.path.join(os.getcwd(), "data/articles", article_folder) if not os.path.isdir(article_folder_path): continue - pass + pass""" - for project_item in os.listdir(os.path.join(os.getcwd(), "data/projects")): + # Loading projects definition files + for project_file in os.listdir(os.path.join(os.getcwd(), "data/projects")): + project_file_path = os.path.join(os.getcwd(), "data/projects", project_file) + if not os.path.isfile(project_file_path) or project_file.startswith("."): + continue + + projects_data = yaml.safe_load(open(project_file_path)) + if "projects" not in projects_data: + print(f"Unable to load '{project_file_path}' due to missing 'projects' field !") + continue + + for project_data in projects_data["projects"]: + _project = ContentProject(**project_data) + __CONTENT.projects[_project.id] = _project + print(_project) + + """for project_item in os.listdir(os.path.join(os.getcwd(), "data/projects")): project_item_path = os.path.join(os.getcwd(), "data/projects/", project_item) if not os.path.isfile(project_item_path) or project_item.startswith("."): continue @@ -87,33 +124,25 @@ def reload_content_items() -> None: print(f"Loaded project '{project_id}'") except Exception as e: print(f"Unable to load project '{project_id}' due to an exception !") - print(e) + print(e)""" - for tool_item in os.listdir(os.path.join(os.getcwd(), "data/tools")): - tool_item_path = os.path.join(os.getcwd(), "data/tools", tool_item) - if not os.path.isfile(tool_item_path) or tool_item_path.startswith("."): + for tools_file in os.listdir(os.path.join(os.getcwd(), "data/tools")): + tools_file_path = os.path.join(os.getcwd(), "data/tools", tools_file) + if not os.path.isfile(tools_file_path) or tools_file.startswith("."): continue - tool_id = Path(tool_item_path).stem - tool_page_path = os.path.join(os.getcwd(), f"templates/tools/{tool_id}.jinja") - - if not all(os.path.isfile(project_file) for project_file in - [tool_item_path, tool_page_path]): - print(f"Unable to load tool '{tool_id}' due to missing files !") + tools_data = yaml.safe_load(open(tools_file_path)) + if "tools" not in tools_data: + print(f"Unable to load '{tools_file_path}' due to missing 'tools' field !") continue - tool_data: ContentTool - try: - raw_tool_data = yaml.safe_load(open(tool_item_path)) - __CONTENT_TOOLS[tool_id] = ContentTool( - id=tool_id, - metadata=ContentMetadata(**raw_tool_data["metadata"]), - data=ContentToolData(**raw_tool_data["data"]), - ) - print(f"Loaded tool '{tool_id}'") - except Exception as e: - print(f"Unable to load tool '{tool_id}' due to an exception !") - print(e) - continue + for tool_data in tools_data["tools"]: + _tool = ContentTool(**tool_data) + __CONTENT.tools[_tool.id] = _tool + #print(_tool) - # FIXME: Check if the required files exist too ! + # FIXME: Check if the required files exist too !""" + + +def validate_content_items() -> bool: + pass diff --git a/website/content/metadata.py b/website/content/dataclasses.py similarity index 58% rename from website/content/metadata.py rename to website/content/dataclasses.py index 2cf46a8..435cdc2 100644 --- a/website/content/metadata.py +++ b/website/content/dataclasses.py @@ -1,6 +1,8 @@ from dataclasses import dataclass, field from typing import Optional +from locked_dict.locked_dict import LockedDict + @dataclass class ContentHeadMetadata: @@ -66,3 +68,49 @@ class ContentMetadata: self.general: dict self.general = ContentGeneralMetadata(**self.general) + + +@dataclass +class ContentResource: + scripts: list[str] = field(default_factory=list) + stylesheets: list[str] = field(default_factory=list) + + +@dataclass +class ContentApplet: + id: str + resources: ContentResource + + def __post_init__(self): + self.resources: dict + self.resources = ContentResource(**self.resources) + + +@dataclass +class ContentTool: + # NOTE: could extend `ContentProject` + id: str + applet_id: str + metadata: ContentMetadata + + def __post_init__(self): + self.metadata: dict + self.metadata = ContentMetadata(**self.metadata) + + +@dataclass +class ContentProject: + id: str + metadata: ContentMetadata + + def __post_init__(self): + self.metadata: dict + self.metadata = ContentMetadata(**self.metadata) + + +@dataclass +class ContentRoot: + applets: LockedDict[str, ContentApplet] = field(default_factory=LockedDict) + # articles: list[Con] = field(default_factory=list) + projects: LockedDict[str, ContentProject] = field(default_factory=LockedDict) + tools: LockedDict[str, ContentTool] = field(default_factory=LockedDict) diff --git a/website/content/project.py b/website/content/project.py deleted file mode 100644 index 4e8cdeb..0000000 --- a/website/content/project.py +++ /dev/null @@ -1,9 +0,0 @@ -from dataclasses import dataclass - -from .metadata import ContentMetadata - - -@dataclass -class ContentProject: - id: str - metadata: ContentMetadata diff --git a/website/content/tool.py b/website/content/tool.py deleted file mode 100644 index f197db2..0000000 --- a/website/content/tool.py +++ /dev/null @@ -1,16 +0,0 @@ -from dataclasses import dataclass, field - -from .metadata import ContentMetadata - - -@dataclass -class ContentToolData: - scripts: list[str] = field(default_factory=list) - stylesheets: list[str] = field(default_factory=list) - - -@dataclass -class ContentTool: - id: str - metadata: ContentMetadata - data: ContentToolData diff --git a/website/renderers/applet.py b/website/renderers/applet.py new file mode 100644 index 0000000..bf00c72 --- /dev/null +++ b/website/renderers/applet.py @@ -0,0 +1,29 @@ +from flask import url_for + +from website.content import ContentApplet + + +def render_applet_head(applet_data: ContentApplet) -> str: + applet_style_html = "" + + for applet_style in applet_data.resources.stylesheets: + applet_style_html += ("") + + return applet_style_html + + +def render_applet_scripts(applet_data: ContentApplet): + applet_script_html = "" + + for applet_script in applet_data.resources.scripts: + applet_script_html += ("") + + return applet_script_html diff --git a/website/renderers/code.py b/website/renderers/code.py new file mode 100644 index 0000000..85ae3a6 --- /dev/null +++ b/website/renderers/code.py @@ -0,0 +1,31 @@ +import html +import re +from typing import Optional + +from flask import render_template + + +def render_code_block(code_lines: list[str], language: Optional[str] = None): + _code_lines = list() + + for code_line in code_lines: + code_line = html.escape(code_line) + code_line = code_line.replace('\t', ' ' * 4) + code_line = code_line.replace(' ', ' ') + _code_lines.append(code_line) + + return render_template( + "elements/code.jinja", + code_lines=_code_lines, + code_language=language, + ) + + # return re.sub('>\s*\s*', "", + # render_template( + # "elements/code.jinja", + # code_lines=_code_lines, + # code_language=language, + # ) + # ) + # ) diff --git a/website/renderers/file_input.py b/website/renderers/file_input.py new file mode 100644 index 0000000..b9ea0aa --- /dev/null +++ b/website/renderers/file_input.py @@ -0,0 +1,3 @@ + +def render_file_input() -> str: + return "" diff --git a/website/renderers/headings.py b/website/renderers/headings.py index 7c25bc0..70c2472 100644 --- a/website/renderers/headings.py +++ b/website/renderers/headings.py @@ -35,3 +35,11 @@ def render_h3(inner_html: str, icon: Optional[str] = None, right_html: Optional[ return render_heading( inner_html, 3, icon, right_html, anchor_id, background_class ) + + +def render_h4(inner_html: str, icon: Optional[str] = None, right_html: Optional[str] = None, + anchor_id: Optional[str] = None, background_class: str = "bkgd-grid") -> str: + return render_heading( + inner_html, 4, icon, right_html, anchor_id, background_class + ) + diff --git a/website/renderers/lists.py b/website/renderers/lists.py index e69de29..90dec5b 100644 --- a/website/renderers/lists.py +++ b/website/renderers/lists.py @@ -0,0 +1,11 @@ +from typing import Union + +from flask import render_template + + +def render_list_ul(items: list[Union[str|list]]) -> str: + return render_template( + "elements/list-ul.jinja", + list_items=items, + render_list_ul=render_list_ul + )