Frontend now uses hashes so images are bookmarkable

This commit is contained in:
Timothy Farrell 2026-03-09 09:08:07 +00:00
parent 7c0d33282a
commit 5387ce070c
2 changed files with 26 additions and 24 deletions

View File

@ -11,11 +11,19 @@
</style> </style>
</head> </head>
<body> <body>
<img id="random-img" src="/random" alt="Random image"> <img id="random-img" alt="Random image">
<script> <script>
function loadNewImage() { function loadImage(hash) {
document.getElementById('random-img').src = '/random?' + Date.now(); document.getElementById('random-img').src = '/' + hash;
history.replaceState(null, '', '#' + hash);
} }
async function loadNewImage() {
const response = await fetch('/random?' + Date.now());
const data = await response.json();
loadImage(data.img);
}
document.getElementById('random-img').addEventListener('click', loadNewImage); document.getElementById('random-img').addEventListener('click', loadNewImage);
document.addEventListener('keydown', function(e) { document.addEventListener('keydown', function(e) {
if (e.code === 'Space') { if (e.code === 'Space') {
@ -23,6 +31,13 @@
loadNewImage(); loadNewImage();
} }
}); });
const hash = window.location.hash.slice(1);
if (hash) {
loadImage(hash);
} else {
loadNewImage();
}
</script> </script>
</body> </body>
</html> </html>

29
main.py
View File

@ -110,28 +110,12 @@ async def root():
@app.get("/random") @app.get("/random")
async def get_random_file(): async def get_random_file():
"""Serve a random file from the mapping""" """Get a random file hash from the mapping"""
if not indexer.file_mapping: if not indexer.file_mapping:
raise HTTPException(status_code=404, detail="No files indexed") raise HTTPException(status_code=404, detail="No files indexed")
random_hash = random.choice(list(indexer.file_mapping.keys())) random_hash = random.choice(list(indexer.file_mapping.keys()))
return {"img": random_hash}
filename = indexer.get_filename_by_hash(random_hash)
content_type, _ = mimetypes.guess_type(filename)
if not content_type:
content_type = "application/octet-stream"
buffer = indexer.get_file_by_hash(random_hash)
response = StreamingResponse(
buffer,
media_type=content_type,
headers={
"Content-Disposition": f"inline; filename={os.path.basename(filename)}",
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0",
},
)
return response
@app.get("/{file_hash}") @app.get("/{file_hash}")
@ -140,13 +124,16 @@ async def get_file_by_hash(file_hash: str):
if file_hash not in indexer.file_mapping: if file_hash not in indexer.file_mapping:
raise HTTPException(status_code=404, detail="File not found") raise HTTPException(status_code=404, detail="File not found")
file_path, content_type, buffer = indexer.get_file_by_hash(file_hash) filename = indexer.get_filename_by_hash(file_hash)
content_type, _ = mimetypes.guess_type(filename)
if not content_type:
content_type = "application/octet-stream"
return StreamingResponse( return StreamingResponse(
buffer, indexer.get_file_by_hash(file_hash),
media_type=content_type, media_type=content_type,
headers={ headers={
"Content-Disposition": f"inline; filename={os.path.basename(file_path)}", "Content-Disposition": f"inline; filename={os.path.basename(filename)}",
}, },
) )