mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-09-26 23:52:05 +00:00
refactor(x-media): hoist the shared caption builder
bilibili and misskey each had a byte-identical caption() (same escaping, same empty-text early return, differing only in a named format argument). site::caption holds it once; both adapters call it.
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
use super::model;
|
||||
use crate::media::Media;
|
||||
use crate::site::{FetchError, Fetched, RenderData, Site, SiteFuture, compose_text};
|
||||
use html_escape::{encode_double_quoted_attribute, encode_text};
|
||||
use html_escape::encode_text;
|
||||
use regex::Regex;
|
||||
use std::sync::LazyLock;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
@@ -276,7 +276,7 @@ impl From<model::Item> for Fetched {
|
||||
let text = compose_text(&title, &content);
|
||||
let tags = topic_name(&item).to_string();
|
||||
|
||||
let caption = caption(&url, &author_url, &author, &text);
|
||||
let caption = crate::site::caption(&url, &author_url, &author, &text);
|
||||
let media = media_of(&item);
|
||||
|
||||
Fetched {
|
||||
@@ -485,19 +485,6 @@ fn to_https(url: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn caption(url: &str, author_url: &str, author: &str, text: &str) -> String {
|
||||
let url = encode_double_quoted_attribute(url);
|
||||
let author_url = encode_double_quoted_attribute(author_url);
|
||||
let author = encode_text(author);
|
||||
if text.is_empty() {
|
||||
return format!("{url}\n<a href=\"{author_url}\">{author}</a>");
|
||||
}
|
||||
format!(
|
||||
"{url}\n<a href=\"{author_url}\">{author}</a>: {}",
|
||||
encode_text(text)
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use super::model;
|
||||
use crate::media::Media;
|
||||
use crate::site::{FetchError, Fetched, RenderData, Site, SiteFuture};
|
||||
use html_escape::{encode_double_quoted_attribute, encode_text};
|
||||
use html_escape::encode_text;
|
||||
use regex::Regex;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
@@ -117,7 +117,7 @@ impl From<model::Note> for Fetched {
|
||||
text.push_str(content.text.as_deref().unwrap_or_default().trim());
|
||||
let text = text.trim().to_string();
|
||||
|
||||
let caption = caption(&url, &author_url, &author, &text);
|
||||
let caption = crate::site::caption(&url, &author_url, &author, &text);
|
||||
let sensitive = content.cw.is_some() || content.files.iter().any(|f| f.is_sensitive);
|
||||
let media: Vec<Media> = content.files.iter().filter_map(media_from_file).collect();
|
||||
|
||||
@@ -143,19 +143,6 @@ impl From<model::Note> for Fetched {
|
||||
}
|
||||
}
|
||||
|
||||
fn caption(url: &str, author_url: &str, author: &str, text: &str) -> String {
|
||||
let url = encode_double_quoted_attribute(url);
|
||||
let author_url = encode_double_quoted_attribute(author_url);
|
||||
let author = encode_text(author);
|
||||
if text.is_empty() {
|
||||
return format!("{url}\n<a href=\"{author_url}\">{author}</a>");
|
||||
}
|
||||
format!(
|
||||
"{url}\n<a href=\"{author_url}\">{author}</a>: {text}",
|
||||
text = encode_text(text),
|
||||
)
|
||||
}
|
||||
|
||||
/// Maps a Misskey DriveFile to a [`Media`] item; unknown/audio/other types
|
||||
/// are skipped (twitter's `_ => {}` precedent). GIF must be matched before
|
||||
/// the generic image arm.
|
||||
|
||||
@@ -79,6 +79,24 @@ pub(crate) struct RenderData {
|
||||
pub tags: String,
|
||||
}
|
||||
|
||||
/// The built-in caption for a post that has no user-supplied format: the
|
||||
/// canonical URL, the author as a link, then the post's text after a colon.
|
||||
/// The two URLs are escaped for an HTML attribute and the text as HTML text,
|
||||
/// so site-supplied content cannot inject markup. Shared by the adapters whose
|
||||
/// captions have exactly this shape (bilibili, misskey).
|
||||
pub fn caption(url: &str, author_url: &str, author: &str, text: &str) -> String {
|
||||
let url = html_escape::encode_double_quoted_attribute(url);
|
||||
let author_url = html_escape::encode_double_quoted_attribute(author_url);
|
||||
let author = html_escape::encode_text(author);
|
||||
if text.is_empty() {
|
||||
return format!("{url}\n<a href=\"{author_url}\">{author}</a>");
|
||||
}
|
||||
format!(
|
||||
"{url}\n<a href=\"{author_url}\">{author}</a>: {}",
|
||||
html_escape::encode_text(text)
|
||||
)
|
||||
}
|
||||
|
||||
/// The post's text as one string: title and content joined by a line break,
|
||||
/// each only when it is non-empty. This is what the sites' built-in captions
|
||||
/// show after the author line, and what the bot quotes when it is long.
|
||||
|
||||
Reference in New Issue
Block a user