from __future__ import annotations from pathlib import Path from fastapi import APIRouter, Response from fastapi.responses import FileResponse, RedirectResponse from ..web.scripts import ADMIN_TABLES_JS, CLIPBOARD_JS, THEME_JS, VISITOR_IP_JS from ..web.styles import ADMIN_CSS, BASE_CSS ASSET_DIR = Path(__file__).parents[1] / "assets" router = APIRouter(include_in_schema=False) ASSET_CACHE_HEADERS = {"Cache-Control": "public, max-age=31536000, immutable"} def _minify_css(css: str) -> str: return " ".join(css.split()).replace(" {", "{").replace("{ ", "{").replace("; ", ";").replace(": ", ":").replace(", ", ",").replace(" }", "}").replace(";}", "}") MINIFIED_BASE_CSS = _minify_css(BASE_CSS) MINIFIED_ADMIN_CSS = _minify_css(ADMIN_CSS) @router.get("/favicon.ico") def favicon() -> FileResponse: return FileResponse(ASSET_DIR / "favicon.ico", media_type="image/x-icon", headers=ASSET_CACHE_HEADERS) @router.get("/bootstrap-subset.css") def bootstrap_subset_css() -> FileResponse: return FileResponse(ASSET_DIR / "bootstrap-subset.css", media_type="text/css", headers=ASSET_CACHE_HEADERS) @router.get("/favicon-16x16.png") def favicon_16_png() -> FileResponse: return FileResponse(ASSET_DIR / "favicon-16x16.png", media_type="image/png", headers=ASSET_CACHE_HEADERS) @router.get("/favicon-32x32.png") def favicon_32_png() -> FileResponse: return FileResponse(ASSET_DIR / "favicon-32x32.png", media_type="image/png", headers=ASSET_CACHE_HEADERS) @router.get("/apple-touch-icon.png") def apple_touch_icon_png() -> FileResponse: return FileResponse(ASSET_DIR / "apple-touch-icon.png", media_type="image/png", headers=ASSET_CACHE_HEADERS) @router.get("/logo.png") def logo_png() -> FileResponse: return FileResponse(ASSET_DIR / "logo.png", media_type="image/png", headers=ASSET_CACHE_HEADERS) @router.get("/logo.webp") def logo_webp() -> FileResponse: return FileResponse(ASSET_DIR / "logo.webp", media_type="image/webp", headers=ASSET_CACHE_HEADERS) @router.get("/logo-nav.webp") def logo_nav_webp() -> FileResponse: return FileResponse(ASSET_DIR / "logo-nav.webp", media_type="image/webp", headers=ASSET_CACHE_HEADERS) @router.get("/logo-192.png") def logo_192_png() -> FileResponse: return FileResponse(ASSET_DIR / "logo-192.png", media_type="image/png", headers=ASSET_CACHE_HEADERS) @router.get("/logo-512.png") def logo_512_png() -> FileResponse: return FileResponse(ASSET_DIR / "logo-512.png", media_type="image/png", headers=ASSET_CACHE_HEADERS) @router.get("/social-preview.png") def social_preview_png() -> FileResponse: return FileResponse(ASSET_DIR / "social-preview.png", media_type="image/png", headers=ASSET_CACHE_HEADERS) @router.get("/social-preview.webp") def social_preview_webp() -> FileResponse: return FileResponse(ASSET_DIR / "social-preview.webp", media_type="image/webp", headers=ASSET_CACHE_HEADERS) @router.get("/site.webmanifest") def site_webmanifest() -> Response: return Response( """ { "name": "KarlDNS", "short_name": "KarlDNS", "description": "Private update links for routers.", "start_url": "/", "scope": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#ffffff", "icons": [ {"src": "/logo-192.png", "sizes": "192x192", "type": "image/png"}, {"src": "/logo-512.png", "sizes": "512x512", "type": "image/png"} ] } """.strip(), media_type="application/manifest+json", headers=ASSET_CACHE_HEADERS, ) @router.get("/theme.js") def theme_js() -> Response: return Response(THEME_JS, media_type="application/javascript", headers=ASSET_CACHE_HEADERS) @router.get("/clipboard.js") def clipboard_js() -> Response: return Response(CLIPBOARD_JS, media_type="application/javascript", headers=ASSET_CACHE_HEADERS) @router.get("/admin-tables.js") def admin_tables_js() -> Response: return Response(ADMIN_TABLES_JS, media_type="application/javascript", headers=ASSET_CACHE_HEADERS) @router.get("/visitor-ip.js") def visitor_ip_js() -> Response: return Response(VISITOR_IP_JS, media_type="application/javascript", headers=ASSET_CACHE_HEADERS) @router.get("/app.css") def app_css() -> Response: return Response(MINIFIED_BASE_CSS, media_type="text/css", headers=ASSET_CACHE_HEADERS) @router.get("/admin.css") def admin_css() -> Response: return Response(MINIFIED_ADMIN_CSS, media_type="text/css", headers=ASSET_CACHE_HEADERS) @router.get("/install.sh") def install_sh() -> RedirectResponse: return RedirectResponse( "https://raw.githubusercontent.com/StasonJatham/karldns.de/main/scripts/install-linux.sh", status_code=302, ) @router.get("/uninstall.sh") def uninstall_sh() -> RedirectResponse: return RedirectResponse( "https://raw.githubusercontent.com/StasonJatham/karldns.de/main/scripts/uninstall-linux.sh", status_code=302, ) @router.get("/karldns-update.sh") def karldns_update_sh() -> RedirectResponse: return RedirectResponse( "https://raw.githubusercontent.com/StasonJatham/karldns.de/main/scripts/karldns-update.sh", status_code=302, )