diff --git a/crates/archivr-core/src/capture.rs b/crates/archivr-core/src/capture.rs index 8d006c0..d85ceaf 100644 --- a/crates/archivr-core/src/capture.rs +++ b/crates/archivr-core/src/capture.rs @@ -784,32 +784,51 @@ pub fn perform_capture(archive_paths: &ArchivePaths, locator: &str) -> Result { + Ok(result) => { let file_extension = ".html".to_string(); - let temp_file = store_path + let temp_html = store_path .join("temp") .join(×tamp) .join(format!("{timestamp}{file_extension}")); - let byte_size = fs::metadata(&temp_file) - .with_context(|| format!("failed to stat staged file {}", temp_file.display()))? + let byte_size = fs::metadata(&temp_html) + .with_context(|| format!("failed to stat staged file {}", temp_html.display()))? .len() as i64; - let hash_exists = hash_exists(&hash, &file_extension, store_path)?; - if hash_exists { - let _ = fs::remove_dir_all(store_path.join("temp").join(×tamp)); - } else { - move_temp_to_raw( - &store_path - .join("temp") - .join(×tamp) - .join(format!("{timestamp}{file_extension}")), - &hash, - store_path, - )?; - let _ = fs::remove_dir_all(store_path.join("temp").join(×tamp)); + // 1. Move HTML to raw store (if this hash hasn't been seen before). + if !hash_exists(&result.html_hash, &file_extension, store_path)? { + move_temp_to_raw(&temp_html, &result.html_hash, store_path)?; } - record_media_entry( + // 2. Process favicon while the temp dir still exists. + // Errors here are silenced — favicon is supplementary. + let favicon_info: Option<(String, i64)> = (|| -> Option<(String, i64)> { + let fav_hash = result.favicon_hash.as_deref()?; + let fav_ext = result.favicon_ext.as_deref()?; + let fav_temp = store_path + .join("temp").join(×tamp) + .join(format!("{timestamp}.favicon{fav_ext}")); + if !fav_temp.exists() { return None; } + let fav_size = fs::metadata(&fav_temp).ok()?.len() as i64; + let fav_raw = raw_relative_path_from_hash(fav_hash, fav_ext).ok()?; + if !hash_exists(fav_hash, fav_ext, store_path).ok()? { + move_temp_to_raw(&fav_temp, fav_hash, store_path).ok()?; + } + let fav_blob = database::BlobRecord { + sha256: fav_hash.to_string(), + byte_size: fav_size, + mime_type: None, + extension: extension_without_dot(fav_ext), + raw_relpath: path_to_store_string(&fav_raw), + }; + let fav_blob_id = database::upsert_blob(&conn, &fav_blob).ok()?; + Some((fav_blob.raw_relpath, fav_blob_id)) + })(); + + // 3. Remove the temp directory. + let _ = fs::remove_dir_all(store_path.join("temp").join(×tamp)); + + // 4. Create the entry + primary_media artifact. + let entry = record_media_entry( &conn, store_path, user_id, @@ -818,11 +837,28 @@ pub fn perform_capture(archive_paths: &ArchivePaths, locator: &str) -> Result