#!/usr/bin/python # -*- coding: utf-8 -*- # backend/main.py from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates import uvicorn from pathlib import Path app = FastAPI() # Mount static folder to serve images, PDFs, JS if needed app.mount("/static", StaticFiles(directory="static"), name="static") # Set up template rendering templates = Jinja2Templates(directory="templates") # Sample map data MapsFolder = Path('./static/maps') maps = [ { "id": 2, "name": "DaisyRevedins", "latitude": 44.480829598869185, "longitude": 11.352026314262476, 'stem': 'San Mamolo-JoNotte', "description": "From the grass to the church while visiting the Hospital" }, { "id": 3, "name": "CastelWeak", "latitude": 44.49959787027563, "longitude": 11.27473782212433, 'stem': 'Casteldebole_2024_05_15', "description": "Totally Flat" }, { "id": 4, "name": "Golinelli", "latitude": 44.50847170695366, "longitude": 11.308195638402232, "stem": "Norwegian Sprint", "description": "Jo Noche" }, { "id": 5, "name": "SwordVille", "latitude": 44.49119622583157, "longitude": 11.308122673834362, "stem": "A3-Pellegrino", "description": "San Pellegrino night" }, { "id": 5, "name": "Small Heaven", "latitude": 44.375066657656234, "longitude": 11.247854195489277, "stem": "Piccolo Paradiso_small", "description": "Fucked Dogs & Owners" }, { "id": 6, "name": "Marzab8", "latitude": 44.340876557519195, "longitude": 11.208385117204514, "stem": "Marzabotto-O-Training", "description": "Marzabotto Greto Fiume" }, { "id": 7, "name": "Bazzano", "latitude": 44.506688577284855, "longitude": 11.084856756615434, 'stem': 'Pro Mel', "description": "Bazzano Pro Mel" }, { "id": 8, "name": "Battindarno", 'coord': (44.495505920730935, 11.288849376526782), 'stem': 'JoNotte.2022.1', "description": "Battindarno 2022-1" }, { "id": 9, "name": "Daisy Gardens", "latitude": 44.480829598869185, "longitude": 11.3525, 'stem': 'Revedinmargherita', "description": "Giardini e Revedin" }, { "id": 10, "name": "Pontecchio", "coord": (44.431200464913914, 11.269902531675038), 'stem': 'Pontecchio_night bo 2020', "description": "Occhio al custode di villa Grifone" }, { "id": 11, "name": "Sasso Marconi", "coord": (44.398978299870166, 11.25642430653767), 'stem': 'night_bo_13_02_20', "description": "Cà de Testi e Sasso" }, { "id": 12, "name": "Croce e Funivia", "coord": (44.48620778951313, 11.283029683468458), 'stem': '1802', "description": "Da Casalatch alla Funivia" }, { "id": 13, "name": "CastelWeakRiverBank", "coord": (44.50400435370321, 11.283098136577783), 'stem': '11 febbraio', "description": "Casteldebole e lungo fiume" }, { "id": 14, "name": "ZanardiPark", "coord": (44.48890188652948, 11.28842972160338), 'stem': 'ParcoZanardi', "description": "Parco Zanardi, Casalatch" }, { "id": 15, "name": "The Monster", "coord": (44.47603075768931, 11.262382357503611), 'stem': 'EremoELITE', "description": "Eremo di Tizzano / Mostro" }, { "id": 16, "name": "Villa Angeletti", "coord": (44.510693796692124, 11.333109723632031), 'stem': 'Night BO Villa Angeletti-Night 1', "description": "Villa Angeletti 2020" }, { "id": 17, "name": "Navile", "coord": (44.536246247660856, 11.354504683188482), 'stem': 'NightBO_Navile_20022020', "description": "Navile, Nightbo 2020" }, ] for m in maps: if 'stem' in m: base = m['stem'] m['pdf'] = f'/static/maps/{base}.pdf' for suffix in ('.jpg', '.png'): fn = MapsFolder / f'{base}_small{suffix}' if fn.is_file(): m['thumbnail'] = f'/static/maps/{fn.name}' fn = MapsFolder / f'{base}_big{suffix}' if fn.is_file(): m['full_size'] = f'/static/maps/{fn.name}' if 'coord' in m: lat, long = m.get('coord') m['latitude'] = lat m['longitude'] = long # Serve the main map page @app.get("/", response_class=HTMLResponse) async def index(request: Request): return templates.TemplateResponse("index.html", {"request": request}) # JSON endpoint to get map data @app.get("/api/maps") async def get_maps(): return maps # Detailed map page @app.get("/map/{map_id}", response_class=HTMLResponse) async def map_detail(request: Request, map_id: int): map_data = next((m for m in maps if m["id"] == map_id), None) if not map_data: return HTMLResponse(content="Map not found", status_code=404) return templates.TemplateResponse("map_detail.html", {"request": request, "map": map_data}) def main(): pass if __name__ == '__main__': uvicorn.run(app, host="127.0.0.1", port=8000)