diff --git a/crates/x-media/src/site/pixiv/api.rs b/crates/x-media/src/site/pixiv/api.rs index 3b8c171..70a19a8 100644 --- a/crates/x-media/src/site/pixiv/api.rs +++ b/crates/x-media/src/site/pixiv/api.rs @@ -290,7 +290,7 @@ impl PixivAPI { let mut unpacked = 0u64; let mut extension = "jpg"; for i in 0..archive.len() { - let mut entry = archive.by_index(i).map_err(|e| e.to_string())?; + let entry = archive.by_index(i).map_err(|e| e.to_string())?; if entry.size() > 64 * 1024 * 1024 { return Err(format!("frame {i} exceeds size cap")); } diff --git a/crates/xmedia-bot/src/send/mod.rs b/crates/xmedia-bot/src/send/mod.rs index c41c8d7..145324d 100644 --- a/crates/xmedia-bot/src/send/mod.rs +++ b/crates/xmedia-bot/src/send/mod.rs @@ -330,6 +330,16 @@ fn kind_of_item(item: &MediaItemPayload) -> CachedMediaKind { } } +/// A cache entry may replay a remote source URL. Local temp paths disappear +/// when the task settles and must never be persisted as a source. +fn replayable_cache_url(media: &str) -> String { + if media.starts_with("http://") || media.starts_with("https://") { + media.to_string() + } else { + String::new() + } +} + /// Collects the Telegram file ids of a sent media group, aligned to the /// batch's items. fn collect_file_ids(messages: &[Message], batch: &[MediaItemPayload], out: &mut Vec) { @@ -338,9 +348,7 @@ fn collect_file_ids(messages: &[Message], batch: &[MediaItemPayload], out: &mut out.push(CachedMedia { kind: kind_of_item(item), file_id, - // A fresh send's item is the source URL (file ids only appear - // in a *cached* send, and `cache_sent_task` skips those). - url: item_url(item).to_string(), + url: replayable_cache_url(item_url(item)), }); } } @@ -1778,4 +1786,12 @@ mod tests { "a degraded entry that fails again must be dropped" ); } + #[test] + fn local_media_cache_does_not_store_a_dead_path() { + assert_eq!(replayable_cache_url("/tmp/tgxmb-ugoira/video.mp4"), ""); + assert_eq!( + replayable_cache_url("https://cdn.example/video.mp4"), + "https://cdn.example/video.mp4" + ); + } }