feat: extract timestamps from video links
This commit is contained in:
parent
ed522e622d
commit
e4b10fcc83
3 changed files with 101 additions and 62 deletions
|
|
@ -10,15 +10,19 @@ pub enum TextComponent {
|
|||
/// Web link
|
||||
Web { text: String, url: String },
|
||||
/// Link to a YouTube video
|
||||
Video { title: String, id: String },
|
||||
Video {
|
||||
text: String,
|
||||
id: String,
|
||||
start_time: u32,
|
||||
},
|
||||
/// Link to a YouTube channel
|
||||
Channel { name: String, id: String },
|
||||
Channel { text: String, id: String },
|
||||
/// Link to a YouTube playlist
|
||||
Playlist { name: String, id: String },
|
||||
Playlist { text: String, id: String },
|
||||
/// Link to a YouTube Music artist
|
||||
Artist { name: String, id: String },
|
||||
Artist { text: String, id: String },
|
||||
/// Link to a YouTube Music album
|
||||
Album { name: String, id: String },
|
||||
Album { text: String, id: String },
|
||||
}
|
||||
|
||||
/// Trait for converting rich text to plain text.
|
||||
|
|
@ -46,12 +50,27 @@ pub trait ToHtml {
|
|||
fn to_html_yt_host(&self, yt_host: &str) -> String;
|
||||
}
|
||||
|
||||
impl ToPlaintext for TextComponent {
|
||||
fn to_plaintext_yt_host(&self, yt_host: &str) -> String {
|
||||
impl TextComponent {
|
||||
pub fn get_text<'a>(&'a self) -> &'a str {
|
||||
match self {
|
||||
TextComponent::Text(text) => text.to_owned(),
|
||||
TextComponent::Text(text) => text,
|
||||
TextComponent::Web { text, .. } => text,
|
||||
TextComponent::Video { text, .. } => text,
|
||||
TextComponent::Channel { text, .. } => text,
|
||||
TextComponent::Playlist { text, .. } => text,
|
||||
TextComponent::Artist { text, .. } => text,
|
||||
TextComponent::Album { text, .. } => text,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_url(&self, yt_host: &str) -> String {
|
||||
match self {
|
||||
TextComponent::Text(_) => "".to_owned(),
|
||||
TextComponent::Web { url, .. } => url.to_owned(),
|
||||
TextComponent::Video { id, .. } => format!("{}/watch?v={}", yt_host, id),
|
||||
TextComponent::Video { id, start_time, .. } => match start_time {
|
||||
0 => format!("{}/watch?v={}", yt_host, id),
|
||||
n => format!("{}/watch?v={}&t={}s", yt_host, id, n),
|
||||
},
|
||||
TextComponent::Channel { id, .. } | TextComponent::Artist { id, .. } => {
|
||||
format!("{}/channel/{}", yt_host, id)
|
||||
}
|
||||
|
|
@ -62,6 +81,15 @@ impl ToPlaintext for TextComponent {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToPlaintext for TextComponent {
|
||||
fn to_plaintext_yt_host(&self, yt_host: &str) -> String {
|
||||
match self {
|
||||
TextComponent::Text(text) => text.to_owned(),
|
||||
_ => self.get_url(yt_host),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "html")]
|
||||
impl ToHtml for TextComponent {
|
||||
fn to_html_yt_host(&self, yt_host: &str) -> String {
|
||||
|
|
@ -69,35 +97,18 @@ impl ToHtml for TextComponent {
|
|||
TextComponent::Text(text) => askama_escape::escape(&text, askama_escape::Html)
|
||||
.to_string()
|
||||
.replace("\n", "<br>"),
|
||||
TextComponent::Web { text, url } => {
|
||||
TextComponent::Web { text, .. } => {
|
||||
format!(
|
||||
r#"<a href="{}" target="_blank" rel="noreferrer">{}</a>"#,
|
||||
url,
|
||||
askama_escape::escape(&text, askama_escape::Html)
|
||||
self.get_url(yt_host),
|
||||
askama_escape::escape(text, askama_escape::Html)
|
||||
)
|
||||
}
|
||||
TextComponent::Video { title, id } => {
|
||||
_ => {
|
||||
format!(
|
||||
r#"<a href="{}/watch?v={}" rel="noreferrer">{}</a>"#,
|
||||
yt_host,
|
||||
id,
|
||||
askama_escape::escape(&title, askama_escape::Html)
|
||||
)
|
||||
}
|
||||
TextComponent::Channel { name, id } | TextComponent::Artist { name, id } => {
|
||||
format!(
|
||||
r#"<a href="{}/channel/{}" rel="noreferrer">{}</a>"#,
|
||||
yt_host,
|
||||
id,
|
||||
askama_escape::escape(&name, askama_escape::Html)
|
||||
)
|
||||
}
|
||||
TextComponent::Playlist { name, id } | TextComponent::Album { name, id } => {
|
||||
format!(
|
||||
r#"<a href="{}/playlist?list={}" rel="noreferrer">{}</a>"#,
|
||||
yt_host,
|
||||
id,
|
||||
askama_escape::escape(&name, askama_escape::Html)
|
||||
r#"<a href="{}">{}</a>"#,
|
||||
self.get_url(yt_host),
|
||||
askama_escape::escape(self.get_text(), askama_escape::Html)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -133,7 +144,7 @@ mod tests {
|
|||
text::TextComponent::Text { text: "🎧Listen and download aespa's debut single \"Black Mamba\": ".to_owned() },
|
||||
text::TextComponent::Web { text: "https://smarturl.it/aespa_BlackMamba".to_owned(), url: "https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbFY1QmpQamJPSms0Z1FnVTlQUS00ZFhBZnBJZ3xBQ3Jtc0tuRGJBanludGoyRnphb2dZWVd3cUNnS3dEd0FnNHFOZEY1NHBJaHFmLXpaWUJwX3ZucDZxVnpGeHNGX1FpMzFkZW9jQkI2Mi1wNGJ1UVFNN3h1MnN3R3JLMzdxU01nZ01POHBGcmxHU2puSUk1WHRzQQ&q=https%3A%2F%2Fsmarturl.it%2Faespa_BlackMamba&v=ZeerrnuLi5E".to_owned() },
|
||||
text::TextComponent::Text { text: "\n🐍The Debut Stage ".to_owned() },
|
||||
text::TextComponent::Video { title: "https://youtu.be/Ky5RT5oGg0w".to_owned(), video_id: "Ky5RT5oGg0w".to_owned() },
|
||||
text::TextComponent::Video { text: "https://youtu.be/Ky5RT5oGg0w".to_owned(), video_id: "Ky5RT5oGg0w".to_owned(), start_time: 0 },
|
||||
text::TextComponent::Text { text: "\n\n🎟️ aespa Showcase SYNK in LA! Tickets now on sale: ".to_owned() },
|
||||
text::TextComponent::Web { text: "https://www.ticketmaster.com/event/0A...".to_owned(), url: "https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbFpUMEZiaXJWWkszaVZXaEM0emxWU1JQV3NoQXxBQ3Jtc0tuU2g4VWNPNE5UY3hoSWYtamFzX0h4bUVQLVJiRy1ubDZrTnh3MUpGdDNSaUo0ZlMyT3lUM28ycUVBdHJLMndGcDhla3BkOFpxSVFfOS1QdVJPVHBUTEV1LXpOV0J2QXdhV05lV210cEJtZUJMeHdaTQ&q=https%3A%2F%2Fwww.ticketmaster.com%2Fevent%2F0A005CCD9E871F6E&v=ZeerrnuLi5E".to_owned() },
|
||||
text::TextComponent::Text { text: "\n\nSubscribe to aespa Official YouTube Channel!\n".to_owned() },
|
||||
|
|
@ -198,7 +209,7 @@ aespa 에스파 'Black Mamba' MV ℗ SM Entertainment"#
|
|||
let html = richtext.to_html_yt_host("https://piped.kavin.rocks");
|
||||
assert_eq!(
|
||||
html,
|
||||
"🎧Listen and download aespa's debut single "Black Mamba": <a href=\"https://smarturl.it/aespa_BlackMamba\" target=\"_blank\" rel=\"noreferrer\">https://smarturl.it/aespa_BlackMamba</a><br>🐍The Debut Stage <a href=\"https://piped.kavin.rocks/watch?v=Ky5RT5oGg0w\" rel=\"noreferrer\">https://youtu.be/Ky5RT5oGg0w</a><br><br>🎟\u{fe0f} aespa Showcase SYNK in LA! Tickets now on sale: <a href=\"https://www.ticketmaster.com/event/0A005CCD9E871F6E\" target=\"_blank\" rel=\"noreferrer\">https://www.ticketmaster.com/event/0A...</a><br><br>Subscribe to aespa Official YouTube Channel!<br><a href=\"https://www.youtube.com/aespa?sub_confirmation=1\" target=\"_blank\" rel=\"noreferrer\">https://www.youtube.com/aespa?sub_con...</a><br><br>aespa official<br><a href=\"https://www.youtube.com/c/aespa\" target=\"_blank\" rel=\"noreferrer\">https://www.youtube.com/c/aespa</a><br><a href=\"https://www.instagram.com/aespa_official\" target=\"_blank\" rel=\"noreferrer\">https://www.instagram.com/aespa_official</a><br><a href=\"https://www.tiktok.com/@aespa_official\" target=\"_blank\" rel=\"noreferrer\">https://www.tiktok.com/@aespa_official</a><br><a href=\"https://twitter.com/aespa_Official\" target=\"_blank\" rel=\"noreferrer\">https://twitter.com/aespa_Official</a><br><a href=\"https://www.facebook.com/aespa.official\" target=\"_blank\" rel=\"noreferrer\">https://www.facebook.com/aespa.official</a><br><a href=\"https://weibo.com/aespa\" target=\"_blank\" rel=\"noreferrer\">https://weibo.com/aespa</a><br><br>#aespa #æspa #BlackMamba #블랙맘바 #에스파<br>aespa 에스파 'Black Mamba' MV ℗ SM Entertainment"
|
||||
"🎧Listen and download aespa's debut single "Black Mamba": <a href=\"https://smarturl.it/aespa_BlackMamba\" target=\"_blank\" rel=\"noreferrer\">https://smarturl.it/aespa_BlackMamba</a><br>🐍The Debut Stage <a href=\"https://piped.kavin.rocks/watch?v=Ky5RT5oGg0w\">https://youtu.be/Ky5RT5oGg0w</a><br><br>🎟\u{fe0f} aespa Showcase SYNK in LA! Tickets now on sale: <a href=\"https://www.ticketmaster.com/event/0A005CCD9E871F6E\" target=\"_blank\" rel=\"noreferrer\">https://www.ticketmaster.com/event/0A...</a><br><br>Subscribe to aespa Official YouTube Channel!<br><a href=\"https://www.youtube.com/aespa?sub_confirmation=1\" target=\"_blank\" rel=\"noreferrer\">https://www.youtube.com/aespa?sub_con...</a><br><br>aespa official<br><a href=\"https://www.youtube.com/c/aespa\" target=\"_blank\" rel=\"noreferrer\">https://www.youtube.com/c/aespa</a><br><a href=\"https://www.instagram.com/aespa_official\" target=\"_blank\" rel=\"noreferrer\">https://www.instagram.com/aespa_official</a><br><a href=\"https://www.tiktok.com/@aespa_official\" target=\"_blank\" rel=\"noreferrer\">https://www.tiktok.com/@aespa_official</a><br><a href=\"https://twitter.com/aespa_Official\" target=\"_blank\" rel=\"noreferrer\">https://twitter.com/aespa_Official</a><br><a href=\"https://www.facebook.com/aespa.official\" target=\"_blank\" rel=\"noreferrer\">https://www.facebook.com/aespa.official</a><br><a href=\"https://weibo.com/aespa\" target=\"_blank\" rel=\"noreferrer\">https://weibo.com/aespa</a><br><br>#aespa #æspa #BlackMamba #블랙맘바 #에스파<br>aespa 에스파 'Black Mamba' MV ℗ SM Entertainment"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue