diff --git a/server.py b/server.py index bab876f..46b0aa4 100644 --- a/server.py +++ b/server.py @@ -796,7 +796,7 @@ async def run_detail(run_id: str, request: Request): media_html += f'''
''' @@ -813,14 +813,14 @@ async def run_detail(run_id: str, request: Request): media_html += f''' ''' media_html += '' # Build inputs list - inputs_html = ''.join([f'{inp}' for inp in run.inputs]) + inputs_html = ''.join([f'{inp}' for inp in run.inputs]) # Infrastructure section infra_html = "" @@ -888,7 +888,7 @@ async def run_detail(run_id: str, request: Request): if run.output_hash: output_link = f'''''' completed_html = "" @@ -1654,8 +1654,179 @@ async def ui_discard_recipe(recipe_id: str, request: Request): @app.get("/cache/{content_hash}") -async def get_cached(content_hash: str): - """Get cached content by hash.""" +async def get_cached(content_hash: str, request: Request): + """Get cached content by hash. Content negotiation: HTML for browsers, JSON for APIs, file for downloads.""" + ctx = get_user_context_from_cookie(request) + cache_path = get_cache_path(content_hash) + + if not cache_path: + if wants_html(request): + content = f'Content not found: {content_hash}
' + return HTMLResponse(render_page("Not Found", content, ctx.actor_id if ctx else None, active_tab="media"), status_code=404) + raise HTTPException(404, f"Content {content_hash} not in cache") + + # JSON response for API clients + accept = request.headers.get("accept", "") + if "application/json" in accept: + meta = await database.load_item_metadata(content_hash, ctx.actor_id if ctx else None) + cache_item = await database.get_cache_item(content_hash) + ipfs_cid = cache_item.get("ipfs_cid") if cache_item else None + file_size = cache_path.stat().st_size + media_type = detect_media_type(cache_path) + return { + "content_hash": content_hash, + "size": file_size, + "media_type": media_type, + "ipfs_cid": ipfs_cid, + "meta": meta + } + + # HTML response for browsers - show detail page + if wants_html(request): + if not ctx: + content = 'Login via L2 to view cached content.
' + return HTMLResponse(render_page("Login Required", content, None, active_tab="media"), status_code=401) + + # Check user has access + user_hashes = await get_user_cache_hashes(ctx.username, ctx.actor_id) + if content_hash not in user_hashes: + content = 'Access denied.
' + return HTMLResponse(render_page("Access Denied", content, ctx.actor_id, active_tab="media"), status_code=403) + + media_type = detect_media_type(cache_path) + file_size = cache_path.stat().st_size + size_str = f"{file_size:,} bytes" + if file_size > 1024*1024: + size_str = f"{file_size/(1024*1024):.1f} MB" + elif file_size > 1024: + size_str = f"{file_size/1024:.1f} KB" + + # Get IPFS CID from database + cache_item = await database.get_cache_item(content_hash) + ipfs_cid = cache_item.get("ipfs_cid") if cache_item else None + + # Build media display HTML + if media_type == "video": + video_src = video_src_for_request(content_hash, request) + media_html = f'' + elif media_type == "image": + media_html = f'Unknown file type. Download file
' + + content = f''' + + + Back to media + + +Content not found: {content_hash}
' - return HTMLResponse(render_page("Not Found", content, ctx.actor_id if ctx else None, active_tab="media"), status_code=404) - raise HTTPException(404, f"Content {content_hash} not in cache") - - if wants_html(request): - if not ctx: - content = 'Login via L2 to view cached content.
' - return HTMLResponse(render_page("Login Required", content, None, active_tab="media"), status_code=401) - - # Check user has access - user_hashes = await get_user_cache_hashes(ctx.username, ctx.actor_id) - if content_hash not in user_hashes: - content = 'Access denied.
' - return HTMLResponse(render_page("Access Denied", content, ctx.actor_id, active_tab="media"), status_code=403) - - media_type = detect_media_type(cache_path) - file_size = cache_path.stat().st_size - size_str = f"{file_size:,} bytes" - if file_size > 1024*1024: - size_str = f"{file_size/(1024*1024):.1f} MB" - elif file_size > 1024: - size_str = f"{file_size/1024:.1f} KB" - - # Get IPFS CID from database - cache_item = await database.get_cache_item(content_hash) - ipfs_cid = cache_item.get("ipfs_cid") if cache_item else None - - # Build media display HTML - if media_type == "video": - video_src = video_src_for_request(content_hash, request) - media_html = f'' - elif media_type == "image": - media_html = f'Unknown file type. Download file
' - - content = f''' - - - Back to media - - -