generated from hjess/PythonTemplateProject
Lets see what lighthouse says
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Has been cancelled
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Has been cancelled
This commit is contained in:
@@ -5,9 +5,9 @@ from fastapi.staticfiles import StaticFiles
|
|||||||
from app.controllers.route_to_web import RouteToWeb
|
from app.controllers.route_to_web import RouteToWeb
|
||||||
from app.services.markdown_processor import MarkdownProcessor
|
from app.services.markdown_processor import MarkdownProcessor
|
||||||
from app.services.metadata_processor import MetadataProcessor
|
from app.services.metadata_processor import MetadataProcessor
|
||||||
from app.controllers.dynamic_controller import DynamicController
|
|
||||||
from app.controllers.category_controller import CategoryController
|
from app.controllers.category_controller import CategoryController
|
||||||
from fastapi.middleware.gzip import GZipMiddleware
|
from fastapi.middleware.gzip import GZipMiddleware
|
||||||
|
from app.services.image_controller import ImageHandler
|
||||||
|
|
||||||
|
|
||||||
class Application:
|
class Application:
|
||||||
@@ -46,11 +46,13 @@ class Application:
|
|||||||
route_to_web = RouteToWeb(self.app)
|
route_to_web = RouteToWeb(self.app)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.app.include_router( category_controller.router )
|
self.app.include_router( category_controller.router )
|
||||||
#self.app.include_router( dynamic_controller.router )
|
#self.app.include_router( dynamic_controller.router )
|
||||||
self.app.include_router(route_to_web.router)
|
self.app.include_router(route_to_web.router)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _include_middelware(self):
|
def _include_middelware(self):
|
||||||
self.app.add_middleware( GZipMiddleware, minimum_size = 500 )
|
self.app.add_middleware( GZipMiddleware, minimum_size = 500 )
|
||||||
|
|
||||||
|
|||||||
72
app/services/image_controller.py
Normal file
72
app/services/image_controller.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import os
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
class ImageHandler:
|
||||||
|
def __init__(self, base_dir: str):
|
||||||
|
"""
|
||||||
|
Initialize the ImageHandler.
|
||||||
|
|
||||||
|
:param base_dir: Base directory for storing and retrieving images.
|
||||||
|
"""
|
||||||
|
self.base_dir = base_dir
|
||||||
|
|
||||||
|
def get_image_path(self, filename: str) -> str:
|
||||||
|
"""
|
||||||
|
Construct the full path for a given image file.
|
||||||
|
|
||||||
|
:param filename: Relative filename of the image.
|
||||||
|
:return: Full path to the image.
|
||||||
|
"""
|
||||||
|
return os.path.join(self.base_dir, filename)
|
||||||
|
|
||||||
|
def get_resized_image_path(self, filename: str, width: int, height: int) -> str:
|
||||||
|
"""
|
||||||
|
Construct the path for a resized image.
|
||||||
|
|
||||||
|
:param filename: Original image filename.
|
||||||
|
:param width: Desired width.
|
||||||
|
:param height: Desired height.
|
||||||
|
:return: Path to the resized image.
|
||||||
|
"""
|
||||||
|
return os.path.join(self.base_dir, f"resized_{width}x{height}_{filename}")
|
||||||
|
|
||||||
|
def resize_and_save(self, original_path: str, resized_path: str, width: int, height: int):
|
||||||
|
"""
|
||||||
|
Resize and save the image if it doesn't already exist.
|
||||||
|
|
||||||
|
:param original_path: Path to the original image file.
|
||||||
|
:param resized_path: Path to save the resized image.
|
||||||
|
:param width: Desired width.
|
||||||
|
:param height: Desired height.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(resized_path):
|
||||||
|
with Image.open(original_path) as img:
|
||||||
|
img_resized = img.resize((width, height))
|
||||||
|
img_resized.save(resized_path, format="JPEG")
|
||||||
|
|
||||||
|
def generate_image_tag(self, src: str, width: int, height: int, css_class: str = "", alt: str = "") -> str:
|
||||||
|
"""
|
||||||
|
Generate an HTML <img> tag and ensure the image exists with the specified dimensions.
|
||||||
|
|
||||||
|
:param src: Relative path to the original image.
|
||||||
|
:param width: Desired width of the image.
|
||||||
|
:param height: Desired height of the image.
|
||||||
|
:param css_class: Optional CSS class to add to the <img> tag.
|
||||||
|
:param alt: Alternative text for the image.
|
||||||
|
:return: HTML <img> tag.
|
||||||
|
"""
|
||||||
|
original_path = self.get_image_path(src)
|
||||||
|
if not os.path.isfile(original_path):
|
||||||
|
raise FileNotFoundError(f"Image not found: {src}")
|
||||||
|
|
||||||
|
# Construct resized image path
|
||||||
|
resized_filename = f"resized_{width}x{height}_{os.path.basename(src)}"
|
||||||
|
resized_path = self.get_resized_image_path(src, width, height)
|
||||||
|
|
||||||
|
# Resize and save the image if necessary
|
||||||
|
self.resize_and_save(original_path, resized_path, width, height)
|
||||||
|
|
||||||
|
# Return the <img> tag
|
||||||
|
class_attr = f' class="{css_class}"' if css_class else ""
|
||||||
|
alt_attr = f' alt="{alt}"' if alt else ""
|
||||||
|
return f'<img src="/{resized_path}" width="{width}" height="{height}"{alt_attr}{class_attr}>'
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import markdown
|
import markdown
|
||||||
from jinja2 import Environment, DictLoader
|
from jinja2 import Environment, DictLoader
|
||||||
|
from .image_controller import ImageHandler
|
||||||
# Define Jinja2 custom functions
|
# Define Jinja2 custom functions
|
||||||
def img_left_overlay(src):
|
def img_left_overlay(src):
|
||||||
"""Render an image with overlay."""
|
"""Render an image with overlay."""
|
||||||
@@ -82,6 +82,8 @@ def slider(options, images):
|
|||||||
def create_jinja_environment():
|
def create_jinja_environment():
|
||||||
"""Create and configure the Jinja2 environment."""
|
"""Create and configure the Jinja2 environment."""
|
||||||
env = Environment(loader=DictLoader({"base_template": "{{ content | safe }}"}))
|
env = Environment(loader=DictLoader({"base_template": "{{ content | safe }}"}))
|
||||||
|
image_handler = ImageHandler(base_dir="static/images")
|
||||||
|
|
||||||
env.globals.update({
|
env.globals.update({
|
||||||
"img_left_overlay": img_left_overlay,
|
"img_left_overlay": img_left_overlay,
|
||||||
"box": box,
|
"box": box,
|
||||||
@@ -89,6 +91,8 @@ def create_jinja_environment():
|
|||||||
"warning": warning,
|
"warning": warning,
|
||||||
"link_to": link_to,
|
"link_to": link_to,
|
||||||
"slider": slider,
|
"slider": slider,
|
||||||
|
"image": image_handler.generate_image_tag, # Add image handler function
|
||||||
|
|
||||||
})
|
})
|
||||||
return env
|
return env
|
||||||
|
|
||||||
@@ -113,11 +117,7 @@ def render_markdown_with_jinja(markdown_content: str):
|
|||||||
template = env.get_template("base_template")
|
template = env.get_template("base_template")
|
||||||
final_html = template.render(content=intermediate_html)
|
final_html = template.render(content=intermediate_html)
|
||||||
|
|
||||||
#Step 3: Re-render final_html in Jinja2 for embedded tags like {{ box(...) }}
|
# Step 3: Re-render final_html in Jinja2 for embedded tags like {{ image(...) }}
|
||||||
|
final_output = env.from_string(final_html).render()
|
||||||
try:
|
|
||||||
final_output = env.from_string(final_html).render()
|
|
||||||
except:
|
|
||||||
print(final_html)
|
|
||||||
|
|
||||||
return final_output, metadata
|
return final_output, metadata
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ Lissabon føles på mange måder som København – med fokus på kultur, kvalit
|
|||||||
|
|
||||||
Samtidig er mange oplevelser billigere end i København, og her er en atmosfære, der er svær at finde nordpå: Lissabon har en unik blanding af tradition og modernitet, som gør den til en by, der bliver ved med at fascinere.
|
Samtidig er mange oplevelser billigere end i København, og her er en atmosfære, der er svær at finde nordpå: Lissabon har en unik blanding af tradition og modernitet, som gør den til en by, der bliver ved med at fascinere.
|
||||||
|
|
||||||
|
{{ image("pic11.jpg", 200, 150, "thumbnail", "Example Image") }}
|
||||||
|
|
||||||
### Lidt billeder
|
### Lidt billeder
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Markdown==3.7
|
|||||||
markdown-it-py==3.0.0
|
markdown-it-py==3.0.0
|
||||||
MarkupSafe==3.0.2
|
MarkupSafe==3.0.2
|
||||||
mdurl==0.1.2
|
mdurl==0.1.2
|
||||||
|
pillow==11.0.0
|
||||||
pydantic==2.10.3
|
pydantic==2.10.3
|
||||||
pydantic_core==2.27.1
|
pydantic_core==2.27.1
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
|
@import 'open_sans.css';
|
||||||
|
@import "roboto-slab.css";
|
||||||
@import 'fontawesome-all.min.css';
|
@import 'fontawesome-all.min.css';
|
||||||
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,600,400italic,600italic|Roboto+Slab:400,700");
|
|
||||||
/*
|
/*
|
||||||
Editorial by HTML5 UP
|
Editorial by HTML5 UP
|
||||||
html5up.net | @ajlkn
|
html5up.net | @ajlkn
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
<span class="image main">
|
<span class="image main">
|
||||||
<img src="static/images/pic11.jpg" alt="Portugal" width="500" height="200" class="responsive-image" />
|
<img src="static/images/pic11.jpg" alt="Portugal" width="500" height="200" class="responsive-image" />
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<hr class="major" />
|
<hr class="major" />
|
||||||
|
|||||||
Reference in New Issue
Block a user