cdn

Log | Files | Refs | Activity

commit 68314d3ba6a0e677161b98d99fc414970f3bec9f
parent cd177267820be381098cf18c8c71917c10a86010
Author: Amit Dutta <mail@amit.is-a.dev>
Date:   Fri,  4 Sep 2026 07:14:26 +0530

Merge pull request #9 from notamitgamer/feat/favicon-logo-pwa-manifest

Add favicon, logo, and installable PWA manifest (no-cache)
Diffstat:
Mapp/main.py | 39++++++++++++++++++++++++++++++++++++++-
Aapp/static/favicon.ico | 0
Aapp/static/icons/apple-touch-icon.png | 0
Aapp/static/icons/favicon-16x16.png | 0
Aapp/static/icons/favicon-32x32.png | 0
Aapp/static/icons/icon-192.png | 0
Aapp/static/icons/icon-512.png | 0
Aapp/static/icons/icon-maskable-192.png | 0
Aapp/static/icons/icon-maskable-512.png | 0
Aapp/static/icons/logo.svg | 20++++++++++++++++++++
Aapp/static/icons/og-logo.png | 0
Aapp/static/manifest.json | 48++++++++++++++++++++++++++++++++++++++++++++++++
Aapp/static/sw.js | 27+++++++++++++++++++++++++++
Mapp/templates/index.html | 37++++++++++++++++++++++++++++++++++++-
14 files changed, 169 insertions(+), 2 deletions(-)

diff --git a/app/main.py b/app/main.py @@ -3,8 +3,9 @@ import shutil import uuid import mimetypes import httpx +from pathlib import Path from fastapi import FastAPI, Request, File, UploadFile, Depends, HTTPException -from fastapi.responses import StreamingResponse, HTMLResponse, PlainTextResponse, RedirectResponse +from fastapi.responses import StreamingResponse, HTMLResponse, PlainTextResponse, RedirectResponse, FileResponse from fastapi.templating import Jinja2Templates from .storage import is_file, list_directory, upload_temp_file, HF_REPO_ID @@ -14,6 +15,42 @@ app = FastAPI() templates = Jinja2Templates(directory="app/templates") +STATIC_DIR = Path(__file__).parent / "static" + +# manifest.json and the service worker must always be fetched fresh — +# the app can change at any time and we never want a stale PWA shell +# or a stale install prompt. Icons are safe to cache normally. +_NO_STORE_FILES = {"manifest.json", "sw.js"} + +@app.get("/static/{filename}") +async def static_no_cache_root(filename: str): + if filename not in _NO_STORE_FILES: + raise HTTPException(status_code=404) + file_path = STATIC_DIR / filename + if not file_path.is_file(): + raise HTTPException(status_code=404) + return FileResponse( + file_path, + headers={"Cache-Control": "no-store, no-cache, must-revalidate, max-age=0"}, + ) + +@app.get("/static/icons/{filename}") +async def static_icons(filename: str): + file_path = STATIC_DIR / "icons" / filename + if not file_path.is_file(): + raise HTTPException(status_code=404) + return FileResponse( + file_path, + headers={"Cache-Control": "public, max-age=86400"}, + ) + +@app.get("/favicon.ico") +async def favicon(): + return FileResponse( + STATIC_DIR / "favicon.ico", + headers={"Cache-Control": "public, max-age=86400"}, + ) + CDN_BASE_URL = os.getenv("CDN_BASE_URL", "https://cdn-zt7p.onrender.com") RAW_DOMAIN = os.getenv("RAW_DOMAIN", "raw.cdn.amit.is-a.dev") RAW_BASE_URL = os.getenv("RAW_BASE_URL", f"https://{RAW_DOMAIN}") diff --git a/app/static/favicon.ico b/app/static/favicon.ico Binary files differ. diff --git a/app/static/icons/apple-touch-icon.png b/app/static/icons/apple-touch-icon.png Binary files differ. diff --git a/app/static/icons/favicon-16x16.png b/app/static/icons/favicon-16x16.png Binary files differ. diff --git a/app/static/icons/favicon-32x32.png b/app/static/icons/favicon-32x32.png Binary files differ. diff --git a/app/static/icons/icon-192.png b/app/static/icons/icon-192.png Binary files differ. diff --git a/app/static/icons/icon-512.png b/app/static/icons/icon-512.png Binary files differ. diff --git a/app/static/icons/icon-maskable-192.png b/app/static/icons/icon-maskable-192.png Binary files differ. diff --git a/app/static/icons/icon-maskable-512.png b/app/static/icons/icon-maskable-512.png Binary files differ. diff --git a/app/static/icons/logo.svg b/app/static/icons/logo.svg @@ -0,0 +1,20 @@ +<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"> + <rect width="512" height="512" rx="112" fill="#050505"/> + <rect x="30" y="30" width="452" height="452" rx="92" fill="none" stroke="#21262d" stroke-width="2"/> + + <!-- Terminal caret / bracket mark echoing the monospace theme --> + <g fill="none" stroke-linecap="round" stroke-linejoin="round"> + <path d="M180 150 L110 256 L180 362" stroke="#5eead4" stroke-width="34"/> + <path d="M332 150 L402 256 L332 362" stroke="#fca5a5" stroke-width="34"/> + </g> + + <!-- center slash / cursor, echoing directory listing dash --> + <rect x="243" y="150" width="26" height="212" rx="8" fill="#ffffff" transform="rotate(14 256 256)"/> + + <!-- three-color accent dash at the bottom, matches site's .top-accent gradient --> + <g> + <rect x="176" y="410" width="52" height="10" rx="5" fill="#5eead4"/> + <rect x="230" y="410" width="52" height="10" rx="5" fill="#fca5a5"/> + <rect x="284" y="410" width="52" height="10" rx="5" fill="#ffffff"/> + </g> +</svg> diff --git a/app/static/icons/og-logo.png b/app/static/icons/og-logo.png Binary files differ. diff --git a/app/static/manifest.json b/app/static/manifest.json @@ -0,0 +1,48 @@ +{ + "name": "amit's CDN", + "short_name": "CDN", + "description": "Personal CDN for browsing, uploading, and linking hosted assets.", + "start_url": "/", + "scope": "/", + "display": "standalone", + "background_color": "#050505", + "theme_color": "#050505", + "orientation": "any", + "lang": "en", + "icons": [ + { + "src": "/static/icons/favicon-16x16.png", + "sizes": "16x16", + "type": "image/png" + }, + { + "src": "/static/icons/favicon-32x32.png", + "sizes": "32x32", + "type": "image/png" + }, + { + "src": "/static/icons/icon-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/static/icons/icon-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/static/icons/icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/static/icons/icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/app/static/sw.js b/app/static/sw.js @@ -0,0 +1,27 @@ +// This service worker intentionally does NOT cache anything. +// It exists only so the site satisfies PWA "installability" requirements +// (Add to Home Screen / desktop install) while every request still goes +// straight to the network. Directory listings and files here can change +// at any time, so nothing is ever served from a cache. + +self.addEventListener("install", (event) => { + // Activate the new worker immediately, don't wait for old tabs to close. + self.skipWaiting(); +}); + +self.addEventListener("activate", (event) => { + event.waitUntil( + (async () => { + // Defensive cleanup: if a cache was ever created by a previous + // version of this worker, delete it so nothing stale lingers. + const keys = await caches.keys(); + await Promise.all(keys.map((key) => caches.delete(key))); + await self.clients.claim(); + })() + ); +}); + +self.addEventListener("fetch", (event) => { + // Always hit the network. No cache.match, no cache.put — ever. + event.respondWith(fetch(event.request)); +}); diff --git a/app/templates/index.html b/app/templates/index.html @@ -4,7 +4,30 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CDN | {{ page | capitalize }}</title> - + <meta name="description" content="Personal CDN for browsing, uploading, and linking hosted assets."> + + <!-- Favicon --> + <link rel="icon" href="/favicon.ico" sizes="any"> + <link rel="icon" type="image/png" sizes="32x32" href="/static/icons/favicon-32x32.png"> + <link rel="icon" type="image/png" sizes="16x16" href="/static/icons/favicon-16x16.png"> + <link rel="icon" type="image/svg+xml" href="/static/icons/logo.svg"> + <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/apple-touch-icon.png"> + + <!-- PWA manifest (fetched with no-store, see /static/manifest.json route) --> + <link rel="manifest" href="/static/manifest.json"> + <meta name="theme-color" content="#050505"> + <meta name="color-scheme" content="dark"> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> + <meta name="apple-mobile-web-app-title" content="CDN"> + + <!-- Social preview --> + <meta property="og:title" content="CDN | {{ page | capitalize }}"> + <meta property="og:description" content="Personal CDN for browsing, uploading, and linking hosted assets."> + <meta property="og:image" content="/static/icons/og-logo.png"> + <meta property="og:type" content="website"> + <meta name="twitter:card" content="summary"> + <!-- ADD THIS: Turbo to make the site a Single Page App --> <script type="module" src="https://cdn.jsdelivr.net/npm/@hotwired/turbo@8.0.4/dist/turbo.es2017-esm.js"></script> @@ -475,6 +498,18 @@ console.error('failed to copy: ', err); }); } + + // Registers a service worker so the site is installable as a PWA. + // The worker (see /static/sw.js) does NOT cache anything — it only + // passes requests straight through to the network, since this CDN's + // listings and files can change at any time and must never be stale. + if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/static/sw.js').catch(err => { + console.error('service worker registration failed:', err); + }); + }); + } </script> </body> </html>
© notamitgamer • Site Built: 2026-09-05 01:53:16 UTC • git-mirror commit: c170d72 [view raw info]
Originally created with stagit • modified by notamitgamer
Forked from github.com/notamitgamer/git-mirror