From 1206d7103d61cd3669219a87bff22e5d5f0ac6a6 Mon Sep 17 00:00:00 2001 From: TheGeneralist <180094941+thegeneralist01@users.noreply.github.com> Date: Wed, 24 Jun 2026 19:16:21 +0200 Subject: [PATCH] feat(server): add GET /entries/:uid/favicon endpoint --- crates/archivr-server/src/routes.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/crates/archivr-server/src/routes.rs b/crates/archivr-server/src/routes.rs index f856c48..3441f5e 100644 --- a/crates/archivr-server/src/routes.rs +++ b/crates/archivr-server/src/routes.rs @@ -67,6 +67,10 @@ pub fn app(registry: ServerRegistry) -> Router { "/api/archives/:archive_id/entries/:entry_uid/artifacts/:artifact_index", get(serve_artifact), ) + .route( + "/api/archives/:archive_id/entries/:entry_uid/favicon", + get(serve_entry_favicon), + ) .route("/api/archives/:archive_id/runs", get(list_runs)) .route("/api/archives/:archive_id/captures", post(capture_handler)) .route("/api/archives/:archive_id/tags", get(list_tags).post(create_tag_handler)) @@ -162,6 +166,29 @@ async fn serve_artifact( .into_response()) } +async fn serve_entry_favicon( + State(state): State, + Path((archive_id, entry_uid)): Path<(String, String)>, + req: Request, +) -> Result { + let mounted = mounted_archive(&state, &archive_id)?; + let paths = archive::read_archive_paths(&mounted.archive_path)?; + let conn = database::open_or_initialize(&mounted.archive_path)?; + let detail = archive::get_entry_detail(&conn, &entry_uid)? + .ok_or(ApiError::not_found("entry not found"))?; + let artifact = detail + .artifacts + .iter() + .find(|a| a.artifact_role == "favicon") + .ok_or(ApiError::not_found("no favicon for this entry"))?; + let file_path = archive::resolve_artifact_path(&paths.store_path, artifact)?; + Ok(ServeFile::new(&file_path) + .oneshot(req) + .await + .unwrap() + .into_response()) +} + #[derive(Debug, serde::Deserialize)] struct CreateTagBody { path: String,