various: remove dead code; fix skipped tests

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I9100489be899f9e9fbd32f6aca3080196a6a6964
This commit is contained in:
raf 2026-02-05 00:18:02 +03:00
commit cfdc3d0622
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
18 changed files with 1445 additions and 28 deletions

View file

@ -276,6 +276,149 @@ fn generate_heic_thumbnail(source: &Path, dest: &Path, config: &ThumbnailConfig)
}
}
/// Cover size variants for book covers
#[derive(Debug, Clone, Copy)]
pub enum CoverSize {
Tiny, // 64x64 - for map markers, timeline
Grid, // 320x320 - for library grid view
Preview, // 1024x1024 - for quick fullscreen preview
Original, // Full size - original cover
}
impl CoverSize {
pub fn dimensions(&self) -> Option<(u32, u32)> {
match self {
CoverSize::Tiny => Some((64, 64)),
CoverSize::Grid => Some((320, 320)),
CoverSize::Preview => Some((1024, 1024)),
CoverSize::Original => None, // No resizing
}
}
pub fn filename(&self) -> &'static str {
match self {
CoverSize::Tiny => "tiny.jpg",
CoverSize::Grid => "grid.jpg",
CoverSize::Preview => "preview.jpg",
CoverSize::Original => "original.jpg",
}
}
}
/// Generate multi-resolution covers for a book
pub fn generate_book_covers(
media_id: MediaId,
source_image: &[u8],
covers_dir: &Path,
) -> Result<Vec<(CoverSize, PathBuf)>> {
// Create cover directory for this media item
let media_cover_dir = covers_dir.join(media_id.to_string());
std::fs::create_dir_all(&media_cover_dir)?;
let img = image::load_from_memory(source_image)
.map_err(|e| PinakesError::MetadataExtraction(format!("cover image load: {e}")))?;
let mut results = Vec::new();
// Generate each size variant
for size in [
CoverSize::Tiny,
CoverSize::Grid,
CoverSize::Preview,
CoverSize::Original,
] {
let cover_path = media_cover_dir.join(size.filename());
match size.dimensions() {
Some((width, height)) => {
// Generate thumbnail
let thumb = img.thumbnail(width, height);
let mut output = std::fs::File::create(&cover_path)?;
let encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(&mut output, 90);
thumb
.write_with_encoder(encoder)
.map_err(|e| PinakesError::MetadataExtraction(format!("cover encode: {e}")))?;
}
None => {
// Save original
let mut output = std::fs::File::create(&cover_path)?;
let encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(&mut output, 95);
img.write_with_encoder(encoder)
.map_err(|e| PinakesError::MetadataExtraction(format!("cover encode: {e}")))?;
}
}
results.push((size, cover_path));
}
Ok(results)
}
/// Extract full-size cover from an EPUB file
pub fn extract_epub_cover(epub_path: &Path) -> Result<Option<Vec<u8>>> {
let mut doc = epub::doc::EpubDoc::new(epub_path)
.map_err(|e| PinakesError::MetadataExtraction(format!("EPUB open: {e}")))?;
// Try to get the cover image
if let Some(cover_id) = doc.get_cover_id()
&& let Some((cover_data, _mime)) = doc.get_resource(&cover_id)
{
return Ok(Some(cover_data));
}
// Fallback: look for common cover image filenames
let cover_names = ["cover.jpg", "cover.jpeg", "cover.png", "Cover.jpg", "Cover.jpeg", "Cover.png"];
for name in &cover_names {
if let Some(data) = doc.get_resource_by_path(name) {
return Ok(Some(data));
}
}
Ok(None)
}
/// Extract full-size cover from a PDF file (first page)
pub fn extract_pdf_cover(pdf_path: &Path) -> Result<Option<Vec<u8>>> {
// Use pdftoppm to extract the first page at high resolution
let pdftoppm = "pdftoppm";
let temp_dir = std::env::temp_dir();
let temp_prefix = temp_dir.join(format!("pdf_cover_{}", uuid::Uuid::new_v4()));
let status = Command::new(pdftoppm)
.args(["-jpeg", "-f", "1", "-l", "1", "-scale-to", "1200"])
.arg(pdf_path)
.arg(&temp_prefix)
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.map_err(|e| PinakesError::MetadataExtraction(format!("pdftoppm: {e}")))?;
if !status.success() {
return Err(PinakesError::MetadataExtraction(format!(
"pdftoppm exited with status {}",
status
)));
}
// pdftoppm outputs files like prefix-1.jpg
let output_path = format!("{}-1.jpg", temp_prefix.display());
let output_pathbuf = PathBuf::from(&output_path);
if output_pathbuf.exists() {
let data = std::fs::read(&output_pathbuf)?;
let _ = std::fs::remove_file(&output_pathbuf);
Ok(Some(data))
} else {
Ok(None)
}
}
/// Returns the default covers directory under the data dir
pub fn default_covers_dir() -> PathBuf {
crate::config::Config::default_data_dir().join("covers")
}
/// Returns the default thumbnail directory under the data dir.
pub fn default_thumbnail_dir() -> PathBuf {
crate::config::Config::default_data_dir().join("thumbnails")