commit a54bbe96ac476ed4e2dfcce65076a1a658598dcb
parent a9369939a62e73fe3b9579a14f3190f090b911ba
Author: Amit Dutta <mail@amit.is-a.dev>
Date: Thu, 3 Sep 2026 19:14:48 +0530
Merge pull request #7 from notamitgamer/patch
Implement in-memory caching for file checks and listings
Diffstat:
3 files changed, 70 insertions(+), 12 deletions(-)
diff --git a/app/main.py b/app/main.py
@@ -19,6 +19,14 @@ RAW_DOMAIN = os.getenv("RAW_DOMAIN", "raw.cdn.amit.is-a.dev")
RAW_BASE_URL = os.getenv("RAW_BASE_URL", f"https://{RAW_DOMAIN}")
RAW_PREFIX = "raw/"
+@app.exception_handler(404)
+async def not_found_handler(request: Request, exc: HTTPException):
+ # Keep the raw subdomain returning plain text errors
+ if request.url.hostname == RAW_DOMAIN:
+ return PlainTextResponse("404: File Not Found", status_code=404)
+ # Render UI 404 page for the main CDN domain
+ return templates.TemplateResponse(request, "index.html", {"page": "404"}, status_code=404)
+
async def stream_raw(path: str):
hf_url = f"https://huggingface.co/datasets/{HF_REPO_ID}/resolve/main/{path}"
client = httpx.AsyncClient(follow_redirects=True)
diff --git a/app/storage.py b/app/storage.py
@@ -1,4 +1,5 @@
import os
+import time
import uuid
import httpx
from huggingface_hub import HfApi
@@ -9,17 +10,43 @@ HF_TOKEN = os.getenv("HF_TOKEN")
api = HfApi(token=HF_TOKEN)
+# --- SPEED OPTIMIZATION: IN-MEMORY CACHE ---
+_cache = {}
+CACHE_TTL = 60 # Cache folder layouts for 60 seconds to make navigation instant
+
+def _get_cache(key):
+ if key in _cache and _cache[key][0] > time.time():
+ return _cache[key][1]
+ return None
+
+def _set_cache(key, value):
+ _cache[key] = (time.time() + CACHE_TTL, value)
+# -------------------------------------------
+
async def is_file(path: str) -> bool:
"""Check if a path in the HF dataset is a file using a quick HEAD request."""
if not path:
return False
+
+ cache_key = f"is_file_{path}"
+ cached = _get_cache(cache_key)
+ if cached is not None:
+ return cached
+
hf_url = f"https://huggingface.co/datasets/{HF_REPO_ID}/resolve/main/{path}"
async with httpx.AsyncClient() as client:
r = await client.head(hf_url)
- return r.status_code == 200
+ result = r.status_code == 200
+ _set_cache(cache_key, result)
+ return result
def list_directory(path: str):
"""Returns list of dicts for items in directory, sorted folders first."""
+ cache_key = f"list_dir_{path}"
+ cached = _get_cache(cache_key)
+ if cached is not None:
+ return cached
+
try:
items = list(api.list_repo_tree(repo_id=HF_REPO_ID, path_in_repo=path, repo_type="dataset"))
except Exception:
@@ -48,6 +75,8 @@ def list_directory(path: str):
})
files_and_folders.sort(key=lambda x: (not x["is_dir"], x["name"].lower()))
+
+ _set_cache(cache_key, files_and_folders)
return files_and_folders
def upload_temp_file(temp_path: str, filename: str) -> str:
@@ -63,4 +92,7 @@ def upload_temp_file(temp_path: str, filename: str) -> str:
repo_type="dataset",
token=HF_TOKEN
)
- return hf_path-
\ No newline at end of file
+
+ # Clear cache so the newly uploaded file is immediately visible in directories
+ _cache.clear()
+ return hf_path
diff --git a/app/templates/index.html b/app/templates/index.html
@@ -4,10 +4,14 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CDN | {{ page | capitalize }}</title>
+
+ <!-- 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>
+
<style>
:root {
- --bg: #0d1117;
- --surface: #161b22;
+ --bg: #050505;
+ --surface: #121212;
--text-main: #c9d1d9;
--text-dim: #8b949e;
--accent-pink: #ffb4ab;
@@ -25,7 +29,7 @@
margin: 0;
padding: 3rem 1.5rem;
line-height: 1.6;
- font-size: 0.9rem;
+ font-size: 1rem;
}
.container {
@@ -177,6 +181,12 @@
.file-row.done { border-color: #2ea043; }
.file-row.error { border-color: var(--danger); }
+ /* ADD THIS: Style the Turbo progress bar to match your theme */
+ .turbo-progress-bar {
+ height: 3px;
+ background-color: var(--accent-pink);
+ }
+
footer {
margin-top: 4rem;
padding-top: 1rem;
@@ -247,14 +257,15 @@
<a href="/{{ item.path }}">{{ item.name }}/</a>
{% else %}
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>
- <!-- Updated to link directly to the new raw subdomain -->
- <a href="{{ raw_base_url }}/{{ item.path }}">{{ item.name }}</a>
+ <!-- ADD data-turbo="false" so clicking raw files doesn't trigger the SPA router -->
+ <a href="{{ raw_base_url }}/{{ item.path }}" data-turbo="false">{{ item.name }}</a>
{% endif %}
</div>
<div class="item-meta">
{% if not item.is_dir %}
<span>{{ item.size_str }}</span>
- <a href="/api/download/{{ item.path }}" class="download-icon" title="Download">
+ <!-- ADD data-turbo="false" to download links -->
+ <a href="/api/download/{{ item.path }}" class="download-icon" title="Download" data-turbo="false">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 15V3"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/></svg>
</a>
{% endif %}
@@ -293,14 +304,22 @@
<p style="color: var(--text-dim); margin-bottom: 2rem; font-size: 0.85rem; word-break: break-all;">{{ path }}</p>
<div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
- <a href="/api/download/{{ path }}" class="btn">Download</a>
- <!-- Updated links to utilize raw_base_url -->
- <a href="{{ raw_base_url }}/{{ path }}" class="btn">Open Raw</a>
+ <!-- ADD data-turbo="false" to these action buttons -->
+ <a href="/api/download/{{ path }}" class="btn" data-turbo="false">Download</a>
+ <a href="{{ raw_base_url }}/{{ path }}" class="btn" data-turbo="false">Open Raw</a>
<button onclick="copyToClipboard(window.location.origin + '/' + '{{ path }}')" class="btn">Copy Link</button>
<button onclick="copyToClipboard('{{ raw_base_url }}/{{ path }}')" class="btn">Copy Raw Link</button>
</div>
</div>
+ {% elif page == '404' %}
+ <div class="list-container" style="padding: 4rem 1.5rem; text-align: center;">
+ <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="var(--danger)" stroke-width="1.5" style="margin-bottom: 1rem;"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
+ <h2 style="margin: 0 0 0.5rem 0; font-weight: normal; color: var(--danger);">404 - Not Found</h2>
+ <p style="color: var(--text-dim); margin-bottom: 2rem;">The file or directory you're looking for doesn't exist.</p>
+ <a href="/" class="btn">Go to Root</a>
+ </div>
+
{% elif page == 'upload' %}
<blockquote>
If you do not remember the link, go to the <a href="/uploads">uploads folder</a> to find your file.