mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-09-23 23:32:05 +00:00
refactor(x-media): split the post title from its content
`Fetched.title` carried whatever text the platform had — a tweet's body,
a bilibili dynamic's body, a pixiv artwork's title — which was enough
while x/twitter (no title at all) set the shape. The platforms actually
disagree: pixiv has a title *and* a description, bilibili has an opus
headline *and* a body. Posts now carry both:
- `title`: the platform's title (a pixiv artwork title, a bilibili opus
headline or video card title), empty on text-only platforms;
- `content`: the body (tweet / bsky / misskey text, bilibili dynamic
body, and pixiv's description — fetched for the first time here and
flattened from the app API's HTML to plain text).
`{content}` joins the caption-format placeholders, so a custom
`/set_format` can include a pixiv description. The built-in captions keep
producing byte-identical output: `compose_text` joins the two fields the
same way the single field already was, and bilibili's forward marker
(`//@author:`) now lands in `content` behind the head line's `title`.
`CachedPost.content` is `#[serde(default)]`, so link-cache entries and
queued task payloads written before the split still parse, their text
living in `title`.
This commit is contained in:
@@ -327,7 +327,8 @@ mod tests {
|
||||
"https://x.com/nsfw_author/status/2083868672721039569"
|
||||
);
|
||||
// The appended media short link (no URL-entity mapping) is stripped.
|
||||
assert_eq!(fetched.title, "nsfw content");
|
||||
assert_eq!(fetched.title, "");
|
||||
assert_eq!(fetched.content, "nsfw content");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -99,6 +99,7 @@ fn empty_fetched(url: &str) -> Fetched {
|
||||
// crafted links cannot break the parse (Telegram 400).
|
||||
caption: encode_text(url).into_owned(),
|
||||
title: String::new(),
|
||||
content: String::new(),
|
||||
media: vec![],
|
||||
sensitive: true,
|
||||
site_id: "twitter",
|
||||
@@ -352,17 +353,20 @@ impl From<Tweet> for Fetched {
|
||||
fn from(tweet: Tweet) -> Self {
|
||||
let url = tweet.url();
|
||||
let author_url = tweet.author_url();
|
||||
// A tweet has no title: its text is all content.
|
||||
let render_data = Some(crate::site::RenderData {
|
||||
url: url.clone(),
|
||||
author: encode_text(&tweet.author).into_owned(),
|
||||
author_url: author_url.clone(),
|
||||
title: encode_text(&tweet.text).into_owned(),
|
||||
title: String::new(),
|
||||
content: encode_text(&tweet.text).into_owned(),
|
||||
tags: String::new(),
|
||||
});
|
||||
Fetched {
|
||||
source_url: url,
|
||||
caption: tweet.caption(),
|
||||
title: tweet.text.clone(),
|
||||
title: String::new(),
|
||||
content: tweet.text.clone(),
|
||||
media: tweet.media,
|
||||
sensitive: tweet.sensitive,
|
||||
site_id: "twitter",
|
||||
@@ -437,7 +441,8 @@ mod tests {
|
||||
assert_eq!(tweet.text, ">^ω^< & more 'quoted'");
|
||||
assert_eq!(tweet.author, "O'Brien");
|
||||
let fetched: Fetched = tweet.into();
|
||||
assert_eq!(fetched.title, ">^ω^< & more 'quoted'");
|
||||
assert_eq!(fetched.title, "");
|
||||
assert_eq!(fetched.content, ">^ω^< & more 'quoted'");
|
||||
// The caption escapes the raw text exactly once (encode_text covers
|
||||
// & < >; apostrophes stay literal — they are harmless in text).
|
||||
assert!(
|
||||
@@ -496,7 +501,8 @@ mod tests {
|
||||
fetched.source_url,
|
||||
"https://x.com/author_handle/status/861627479294746624"
|
||||
);
|
||||
assert_eq!(fetched.title, "a & b <c>");
|
||||
assert_eq!(fetched.title, "");
|
||||
assert_eq!(fetched.content, "a & b <c>");
|
||||
assert!(fetched.sensitive);
|
||||
assert_eq!(fetched.media.len(), 2);
|
||||
match &fetched.media[0] {
|
||||
|
||||
Reference in New Issue
Block a user