feat: implement thumbnail generation and management

- Remove unused image dependencies from Cargo.lock.
- Update API to handle thumbnail generation and checkup processes.
- Introduce new routes for rebuilding and regenerating thumbnails.
- Enhance job tracking with progress indicators for thumbnail jobs.
- Update front-end components to display thumbnail job status and progress.
- Add backend logic for managing thumbnail jobs and integrating with the API.
- Refactor existing code to accommodate new thumbnail functionalities.
This commit is contained in:
2026-03-08 20:55:12 +01:00
parent c93a7d5d29
commit e64848a216
21 changed files with 625 additions and 254 deletions

View File

@@ -351,25 +351,29 @@ pub async fn get_thumbnail(
State(state): State<AppState>,
Path(book_id): Path<Uuid>,
) -> Result<impl IntoResponse, ApiError> {
let row = sqlx::query(
"SELECT thumbnail_path FROM books WHERE id = $1"
)
.bind(book_id)
.fetch_optional(&state.pool)
.await
.map_err(|e| ApiError::internal(e.to_string()))?;
let row = sqlx::query("SELECT thumbnail_path FROM books WHERE id = $1")
.bind(book_id)
.fetch_optional(&state.pool)
.await
.map_err(|e| ApiError::internal(e.to_string()))?;
let row = row.ok_or_else(|| ApiError::not_found("book not found"))?;
let thumbnail_path: Option<String> = row.get("thumbnail_path");
let path = thumbnail_path.ok_or_else(|| ApiError::not_found("thumbnail not found"))?;
let data = std::fs::read(&path)
.map_err(|e| ApiError::internal(format!("cannot read thumbnail: {}", e)))?;
let data = if let Some(ref path) = thumbnail_path {
std::fs::read(path)
.map_err(|e| ApiError::internal(format!("cannot read thumbnail: {}", e)))?
} else {
// Fallback: render page 1 on the fly (same as pages logic)
crate::pages::render_book_page_1(&state, book_id, 300, 80).await?
};
let mut headers = HeaderMap::new();
headers.insert(header::CONTENT_TYPE, HeaderValue::from_static("image/webp"));
headers.insert(header::CACHE_CONTROL, HeaderValue::from_static("public, max-age=31536000, immutable"));
headers.insert(
header::CACHE_CONTROL,
HeaderValue::from_static("public, max-age=31536000, immutable"),
);
Ok((StatusCode::OK, headers, Body::from(data)))
}