Compare commits

..
2 Commits
Author SHA1 Message Date
YoursFunny caf41183a4 bump version to 1.0.2 2026-08-04 01:29:50 +08:00
YoursFunny b6ae88e869 twitter: request original image via name=orig 2026-08-04 01:28:21 +08:00
4 changed files with 50 additions and 5 deletions
Generated
+2 -2
View File
@@ -3296,7 +3296,7 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
[[package]] [[package]]
name = "x-media" name = "x-media"
version = "1.0.0" version = "1.0.2"
dependencies = [ dependencies = [
"bytes", "bytes",
"dotenv", "dotenv",
@@ -3314,7 +3314,7 @@ dependencies = [
[[package]] [[package]]
name = "xmedia-bot" name = "xmedia-bot"
version = "1.0.0" version = "1.0.2"
dependencies = [ dependencies = [
"dotenv", "dotenv",
"html-escape", "html-escape",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "x-media" name = "x-media"
version = "1.0.0" version = "1.0.2"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
+46 -1
View File
@@ -127,7 +127,7 @@ impl Tweet {
match item.media_type.as_str() { match item.media_type.as_str() {
"photo" => media.push(Media::Illustration { "photo" => media.push(Media::Illustration {
title: None, title: None,
url: item.media_url_https, url: original_twimg_url(&item.media_url_https),
thumbnail_url: None, thumbnail_url: None,
fallback_url: None, fallback_url: None,
}), }),
@@ -198,6 +198,20 @@ fn expand_links(text: &str, urls: &[model::SyndicationEntityUrl]) -> String {
out out
} }
/// pbs.twimg.com serves a reduced default size without size params; `name=orig`
/// returns the original file (fxtwitter used to hand out the original
/// directly, the syndication API does not). Non-twimg URLs pass through
/// unchanged.
fn original_twimg_url(url: &str) -> String {
if url.starts_with("https://pbs.twimg.com/")
&& (url.ends_with(".jpg") || url.ends_with(".png"))
{
format!("{url}?name=orig")
} else {
url.to_string()
}
}
fn mp4_variant(item: &model::SyndicationMedia) -> String { fn mp4_variant(item: &model::SyndicationMedia) -> String {
item.video_info item.video_info
.as_ref() .as_ref()
@@ -302,6 +316,16 @@ mod tests {
assert_eq!(fetched.title, "a & b <c>"); assert_eq!(fetched.title, "a & b <c>");
assert!(fetched.sensitive); assert!(fetched.sensitive);
assert_eq!(fetched.media.len(), 2); assert_eq!(fetched.media.len(), 2);
match &fetched.media[0] {
Media::Illustration { url, .. } => {
// Photo URL is rewritten to request the original file.
assert_eq!(
url,
"https://pbs.twimg.com/media/photo.jpg?name=orig"
);
}
other => panic!("expected illustration, got {other:?}"),
}
match &fetched.media[1] { match &fetched.media[1] {
Media::Video { url, thumbnail_url, .. } => { Media::Video { url, thumbnail_url, .. } => {
assert_eq!(url, "https://video.twimg.com/v.mp4"); assert_eq!(url, "https://video.twimg.com/v.mp4");
@@ -435,6 +459,27 @@ mod tests {
assert_eq!(tweet.text, text, "full text kept intact"); assert_eq!(tweet.text, text, "full text kept intact");
} }
#[test]
fn original_twimg_url_rewrites_photo_urls() {
assert_eq!(
original_twimg_url("https://pbs.twimg.com/media/C_UdnvPUwAE3Dnn.jpg"),
"https://pbs.twimg.com/media/C_UdnvPUwAE3Dnn.jpg?name=orig"
);
assert_eq!(
original_twimg_url("https://pbs.twimg.com/media/abc.png"),
"https://pbs.twimg.com/media/abc.png?name=orig"
);
// Non-twimg URLs (videos, animated gifs) pass through unchanged.
assert_eq!(
original_twimg_url("https://video.twimg.com/v.mp4"),
"https://video.twimg.com/v.mp4"
);
assert_eq!(
original_twimg_url("https://pbs.twimg.com/media/abc.webp"),
"https://pbs.twimg.com/media/abc.webp"
);
}
#[test] #[test]
fn syndication_token_matches_js_formula() { fn syndication_token_matches_js_formula() {
// JS: ((861627479294746624 / 1e15) * PI).toString(36) == "236.vrsocvda" // JS: ((861627479294746624 / 1e15) * PI).toString(36) == "236.vrsocvda"
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "xmedia-bot" name = "xmedia-bot"
version = "1.0.0" version = "1.0.2"
edition = "2024" edition = "2024"
[dependencies] [dependencies]