From 60f2f1ea866e581cfed6dbbc580a45bc564f7034 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 2 Jun 2023 07:54:15 +1000 Subject: [PATCH] Report files (#4946) * Adds more report tags - uploaded_file: Load qualified path for a media file - encode_svg_image: Encode an svg image as base64 data * Docs updates --- InvenTree/report/templatetags/report.py | 35 +++++++++++++++++++++++-- docs/docs/report/helpers.md | 13 +++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/InvenTree/report/templatetags/report.py b/InvenTree/report/templatetags/report.py index 4f293eb81d..5f90ff807f 100644 --- a/InvenTree/report/templatetags/report.py +++ b/InvenTree/report/templatetags/report.py @@ -1,5 +1,6 @@ """Custom template tags for report generation.""" +import base64 import logging import os @@ -98,12 +99,13 @@ def asset(filename): @register.simple_tag() -def uploaded_image(filename, replace_missing=True, replacement_file='blank_image.png'): +def uploaded_image(filename, replace_missing=True, replacement_file='blank_image.png', validate=True): """Return a fully-qualified path for an 'uploaded' image. Arguments: filename: The filename of the image relative to the MEDIA_ROOT directory replace_missing: Optionally return a placeholder image if the provided filename does not exist + validate: Optionally validate that the file is a valid image file (default = True) Returns: A fully qualified path to the image @@ -126,7 +128,7 @@ def uploaded_image(filename, replace_missing=True, replacement_file='blank_image except Exception: exists = False - if exists and not InvenTree.helpers.TestIfImage(full_path): + if exists and validate and not InvenTree.helpers.TestIfImage(full_path): logger.warning(f"File '{filename}' is not a valid image") exists = False @@ -149,6 +151,35 @@ def uploaded_image(filename, replace_missing=True, replacement_file='blank_image return f"file://{path}" +@register.simple_tag() +def encode_svg_image(filename): + """Return a base64-encoded svg image data string""" + + if type(filename) is SafeString: + # Prepend an empty string to enforce 'stringiness' + filename = '' + filename + + # Check if the file exists + if not filename: + exists = False + else: + try: + full_path = settings.MEDIA_ROOT.joinpath(filename).resolve() + exists = full_path.exists() and full_path.is_file() + except Exception: + exists = False + + if not exists: + raise FileNotFoundError(f"Image file '{filename}' not found") + + # Read the file data + with open(full_path, 'rb') as f: + data = f.read() + + # Return the base64-encoded data + return "data:image/svg+xml;charset=utf-8;base64," + base64.b64encode(data).decode('utf-8') + + @register.simple_tag() def part_image(part): """Return a fully-qualified path for a part image. diff --git a/docs/docs/report/helpers.md b/docs/docs/report/helpers.md index 8a0c1fa948..e2253f2737 100644 --- a/docs/docs/report/helpers.md +++ b/docs/docs/report/helpers.md @@ -148,6 +148,19 @@ You can access an uploaded image file if you know the *path* of the image, relat !!! warning "Invalid Image" If the supplied file is not a valid image, it will be replaced with a placeholder image file + +### SVG Images + +SVG images need to be handled in a slightly different manner. When embedding an uploaded SVG image, use the `{% raw %}{% encode_svg_image ... %}{% endraw %}` tag: + +```html +{% raw %} + +{% load report %} + +{% endraw %} +``` + ### Part images A shortcut function is provided for rendering an image associated with a Part instance. You can render the image of the part using the `{% raw %}{% part_image ... %}{% endraw %}` template tag: