from fastapi import FastAPI, Request from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi.responses import HTMLResponse from contextlib import asynccontextmanager import json import os from markdown_render import render_markdown_with_jinja class App: def __init__(self): """Initialize the FastAPI app.""" self.app = FastAPI(lifespan=self.lifespan) self.templates = Jinja2Templates(directory="templates") self.data = self.load_mock_data() # Mount directories self.app.mount("/data", StaticFiles(directory="data"), name="data") self.app.mount("/static", StaticFiles(directory="static"), name="static") # Add routes self.add_routes() # 1. Lifespan events @asynccontextmanager async def lifespan(self, app: FastAPI): print("App startup: Processing Markdown files...") self.process_markdown_files("./data", "./data") # Process all Markdown files print("Markdown processing complete!") yield # Allow the app to start print("App shutdown: Cleanup complete.") # 2. Load JSON data def load_mock_data(self): """Load mock data from a JSON file.""" with open("mock_data.json") as file: return json.load(file) # 3. Markdown processing logic @staticmethod def process_markdown_files(input_dir: str, output_dir: str): """ Recursively process all Markdown files in the input directory, render them to HTML, and save them in the output directory. """ for root, _, files in os.walk(input_dir): for file in files: if file.endswith(".md"): input_file_path = os.path.join(root, file) relative_path = os.path.relpath(input_file_path, input_dir) output_file_path = os.path.join(output_dir, os.path.splitext(relative_path)[0] + ".html") os.makedirs(os.path.dirname(output_file_path), exist_ok=True) with open(input_file_path, "r", encoding="utf-8") as md_file: markdown_content = md_file.read() print(f"Processing: {input_file_path} -> {output_file_path}") rendered_html = render_markdown_with_jinja(markdown_content) with open(output_file_path, "w", encoding="utf-8") as html_file: html_file.write(rendered_html) # 4. Routes def add_routes(self): """Add all routes to the FastAPI app.""" @self.app.get("/", response_class=HTMLResponse) async def get_index(request: Request): """Index route.""" return self.templates.TemplateResponse( "index.html", {"request": request, "data": self.data, "page_title": "Forside", "author": "Henrik"}, ) @self.app.get("/category/{category_name}", response_class=HTMLResponse) async def get_category(request: Request, category_name: str): """Category route.""" category = next((cat for cat in self.data["categories"] if cat["path"] == category_name), None) if category: category_file = f"data/{category_name}/index.html" if os.path.exists(category_file): with open(category_file) as file: category_content = file.read() return self.templates.TemplateResponse( "category.html", { "request": request, "data": self.data, "page_title": category["name"], "author": category["author"], "content": category_content, }, ) return HTMLResponse("Kategori ikke fundet", status_code=404) # Create the app instance app_instance = App() app = app_instance.app