Compare commits
2 commits
f618add384
...
d413cad8bb
Author | SHA1 | Date | |
---|---|---|---|
d413cad8bb | |||
fd3e128f50 |
7 changed files with 85 additions and 163 deletions
|
@ -1,5 +1,3 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use serde_with::{
|
||||
rust::deserialize_ignore_any, serde_as, DefaultOnError, DisplayFromStr, VecSkipError,
|
||||
|
@ -14,7 +12,7 @@ use crate::{
|
|||
},
|
||||
param::Language,
|
||||
serializer::{
|
||||
text::{AccessibilityText, Text, TextComponent},
|
||||
text::{Text, TextComponent},
|
||||
MapResult,
|
||||
},
|
||||
util::{self, timeago, TryRemove},
|
||||
|
@ -139,13 +137,6 @@ pub(crate) struct ReelItemRenderer {
|
|||
/// Contains `No views` if the view count is zero
|
||||
#[serde_as(as = "Option<Text>")]
|
||||
pub view_count_text: Option<String>,
|
||||
/// video duration
|
||||
///
|
||||
/// Example: `the horror maze - 44 seconds - play video`
|
||||
///
|
||||
/// Dashes may be `\u2013` (emdash)
|
||||
#[serde_as(as = "Option<AccessibilityText>")]
|
||||
pub accessibility: Option<String>,
|
||||
#[serde(default)]
|
||||
#[serde_as(as = "DefaultOnError")]
|
||||
pub navigation_endpoint: Option<ReelNavigationEndpoint>,
|
||||
|
@ -395,10 +386,6 @@ impl IsShort for Vec<TimeOverlay> {
|
|||
}
|
||||
}
|
||||
|
||||
static ACCESSIBILITY_SEP_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||
Regex::new("(?:[ \u{00a0}][-\u{2013}\u{2014}] )|\u{2013}|(?:\u{055d} )|(?:\", )").unwrap()
|
||||
});
|
||||
|
||||
/// Result of mapping a list of different YouTube enities
|
||||
/// (videos, channels, playlists)
|
||||
#[derive(Debug)]
|
||||
|
@ -510,36 +497,10 @@ impl<T> YouTubeListMapper<T> {
|
|||
.timestamp_text
|
||||
});
|
||||
|
||||
let length = video.accessibility.and_then(|acc| {
|
||||
// The video title has to be stripped from the beginning because in Swahili
|
||||
// the duration follows the title with no separator (probably a bug).
|
||||
// Example: `what I do with leftoversdakika 1 - cheza video`
|
||||
let parts = ACCESSIBILITY_SEP_REGEX
|
||||
.split(acc.trim_start_matches(&video.headline))
|
||||
.collect::<Vec<_>>();
|
||||
if parts.len() > 1 {
|
||||
// In Russian, the duration is the last part
|
||||
// Example: `Воспроизвести видео – \"hangover food\". Его продолжительность – 58 секунд.`
|
||||
let i = match self.lang {
|
||||
Language::Ru => 1,
|
||||
_ => 2,
|
||||
};
|
||||
timeago::parse_video_duration_or_warn(
|
||||
self.lang,
|
||||
parts[parts.len() - i],
|
||||
&mut self.warnings,
|
||||
)
|
||||
} else {
|
||||
self.warnings
|
||||
.push(format!("could not split video duration `{acc}`"));
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
VideoItem {
|
||||
id: video.video_id,
|
||||
name: video.headline,
|
||||
length,
|
||||
length: None,
|
||||
thumbnail: video.thumbnail.into(),
|
||||
channel: self.channel.clone(),
|
||||
publish_date: pub_date_txt.as_ref().and_then(|txt| {
|
||||
|
@ -789,50 +750,3 @@ impl YouTubeListMapper<PlaylistItem> {
|
|||
res.c.into_iter().for_each(|item| self.map_item(item));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ACCESSIBILITY_SEP_REGEX;
|
||||
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case::af(
|
||||
"BTS - Permission to Dance Cover #shorts #pinkfong – 50 sekondes – speel video",
|
||||
"50 sekondes"
|
||||
)]
|
||||
#[case::de(
|
||||
"Point of view: Me VS My mom #shorts – 8 Sekunden – Video wiedergeben",
|
||||
"8 Sekunden"
|
||||
)]
|
||||
#[case::be(
|
||||
"Point of view: Me VS My mom #shorts–8 секунд – прайграць відэа",
|
||||
"8 секунд"
|
||||
)]
|
||||
#[case::fil("do u wanna get swole? - 53 segundo - i-play ang video", "53 segundo")]
|
||||
#[case::ar(
|
||||
"«the holy trinity of korean street food»՝ 1 րոպե՝ նվագարկել տեսանյութը",
|
||||
"1 րոպե"
|
||||
)]
|
||||
#[case::lv(
|
||||
"what i ate in google japan — 1 minūte — atskaņot videoklipu",
|
||||
"1 minūte"
|
||||
)]
|
||||
#[case::sq("When you impulse buy... - 1 minutë - luaj videon", "1 minutë")]
|
||||
#[case::uk(
|
||||
"\"Point of view: Me VS My mom #shorts\", 8 секунд – відтворити відео",
|
||||
"8 секунд"
|
||||
)]
|
||||
// INFO: sw is unparseable "coming soonsekunde 58 - cheza video"
|
||||
fn split_duration_txt(#[case] s: &str, #[case] expect: &str) {
|
||||
let parts = ACCESSIBILITY_SEP_REGEX.split(s).collect::<Vec<_>>();
|
||||
assert_eq!(parts[parts.len() - 2], expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn split_duration_txt_ru() {
|
||||
let s = "Воспроизвести видео – \"the holy trinity of korean street food\". Его продолжительность – 1 минута.";
|
||||
let parts = ACCESSIBILITY_SEP_REGEX.split(s).collect::<Vec<_>>();
|
||||
assert_eq!(parts[parts.len() - 1], "1 минута.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "bGXP83AU3Mc",
|
||||
name: "do u wanna get swole?",
|
||||
length: Some(53),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/bGXP83AU3Mc/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLC9bzCBeHDbZFLE84Up3IiBIsxmmA",
|
||||
|
@ -148,7 +148,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "E52sSgZlgYs",
|
||||
name: "the holy trinity of korean street food",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/E52sSgZlgYs/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLDBahtFRcfBInHuA8CjXFPWkF2jHg",
|
||||
|
@ -174,7 +174,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "ovaHmfy3O6U",
|
||||
name: "hangover food",
|
||||
length: Some(58),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/ovaHmfy3O6U/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCHmvWlG06h-DT6oxfmh69JGQ69KA",
|
||||
|
@ -200,7 +200,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "FHTQmKTZnlI",
|
||||
name: "pig trotter raguuuuuuuuu 💅",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/FHTQmKTZnlI/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLD0xhka1osA4nI3VCwhQusn3ND3Hg",
|
||||
|
@ -226,7 +226,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "1AXB0l_wKMs",
|
||||
name: "what i ate in google japan",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/1AXB0l_wKMs/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBsfYJ0KffUNn-9jBzNRTqetyFr8g",
|
||||
|
@ -252,7 +252,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "1ARLtk3HiB0",
|
||||
name: "succumb to your cravings",
|
||||
length: Some(53),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/1ARLtk3HiB0/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBY9E40Ehvq862CVItJy0Uj_pS5bg",
|
||||
|
@ -278,7 +278,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "0FfDoDHpaN8",
|
||||
name: "you can\'t let the what ifs rule your life",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/0FfDoDHpaN8/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBiV2TVPO-VbIjoNtwCKmFuxmj6LA",
|
||||
|
@ -304,7 +304,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "kuT90_RIdF0",
|
||||
name: "duck confit lollipop 🦆🍭",
|
||||
length: Some(59),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/kuT90_RIdF0/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCUN-DW72m7sAXJMgVkWNxPYpJBcQ",
|
||||
|
@ -330,7 +330,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "aPJLhrcM4Yg",
|
||||
name: "HOUSE TOUR",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/aPJLhrcM4Yg/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLD1TbWAIbzyWq8AXLoW0xqaji3ukQ",
|
||||
|
@ -356,7 +356,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "DKQrG_hJJX4",
|
||||
name: "how to meal prep like a korean",
|
||||
length: Some(59),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/DKQrG_hJJX4/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBE2DnpLFvtXsZOu1Ta4JQeOToVAw",
|
||||
|
@ -382,7 +382,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "lNizW_P_oVw",
|
||||
name: "Rating Everything I ate at McDonald\'s Japan 🇯🇵",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/lNizW_P_oVw/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBI5XrkQ9Hesbf4lWELy7Uk3yMGMg",
|
||||
|
@ -408,7 +408,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "kbWyJjrCjwA",
|
||||
name: "enemies as fertilizer √(veg)",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/kbWyJjrCjwA/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLDlk30Km1M0jze1M3O90fB2LdvoAQ",
|
||||
|
@ -434,7 +434,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "xAp910JTDig",
|
||||
name: "let\'s make some cabbage rolls for lunch",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/xAp910JTDig/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLAJtpPGRgffBu9WDXACbtiGa_oRgA",
|
||||
|
@ -460,7 +460,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "vSL7dhKatEk",
|
||||
name: "Rating Everything I ate at IKEA Korea",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/vSL7dhKatEk/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBYpIDYbwwWiCqRNVi6PlfEfjrt4A",
|
||||
|
@ -486,7 +486,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "LZzhUpACXSk",
|
||||
name: "I\'m done being the bigger person",
|
||||
length: Some(59),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/LZzhUpACXSk/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLAFTvhtVUP7QZ4P7U70-0XH7PzDDg",
|
||||
|
@ -512,7 +512,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "5C7nqNDfhis",
|
||||
name: "we\'re cooking a whole bird today",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/5C7nqNDfhis/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLA9I9irDsRjikwd0aqp1FWNFtjAqA",
|
||||
|
@ -538,7 +538,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "6mj4Af0kUOQ",
|
||||
name: "men will disappoint but never potatoes",
|
||||
length: Some(50),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/6mj4Af0kUOQ/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLAVxl-FPt878AQXPBhbV1VSGeR8sw",
|
||||
|
@ -564,7 +564,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "1c3axhSJiaQ",
|
||||
name: "I used to hate korean food",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/1c3axhSJiaQ/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLBucOEbTsWTDjOOCjNa-fAvz1yxyA",
|
||||
|
@ -590,7 +590,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "F9Vz0m7DPeU",
|
||||
name: "Rating everything I got at 7/11 Hawaii ( ft. Mauna Kea )",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/F9Vz0m7DPeU/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLDOoCVL6la3ztUeQ6vP4iL1cEBRjQ",
|
||||
|
@ -616,7 +616,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "Uey7kl56wks",
|
||||
name: "Grabbing Snacks from 7/11 Hawaii",
|
||||
length: Some(49),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/Uey7kl56wks/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCWmgajinNtIEbiPbqEtDvkC7Ydrg",
|
||||
|
@ -642,7 +642,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "3un2eUAr6Dg",
|
||||
name: "cheesy korean corn balls hit different",
|
||||
length: Some(46),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/3un2eUAr6Dg/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLD4LziL6GHd1jg8btMJDIM_RhgE_A",
|
||||
|
@ -668,7 +668,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "rI5tWrGpDJA",
|
||||
name: "hawaiian tajin?!?",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/rI5tWrGpDJA/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLAjNiKHdFSKGavBrZRDxi9WdR-gJw",
|
||||
|
@ -694,7 +694,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "WQiGksTxr5g",
|
||||
name: "Rating everything I ate at Hawaiian Supermarket 🌺🏰 pt.2",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/WQiGksTxr5g/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCvzC5xVdTEJX8xtiOqzmeKvmouIg",
|
||||
|
@ -720,7 +720,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "G7aw-QOsagk",
|
||||
name: "Grocery Shopping at Hawaiian Supermarket 🌺🏰 pt.1",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/G7aw-QOsagk/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLAoKEkj2lqYU07yW_DU35TNHEOq4w",
|
||||
|
@ -746,7 +746,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "Y_F1_Yf-DKQ",
|
||||
name: "Breakfast at Hawaiian McDonald\'s 🌺",
|
||||
length: Some(61),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/Y_F1_Yf-DKQ/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDTLFBwRThZUk0eugFSNxc-CKI_HQ",
|
||||
|
@ -772,7 +772,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "Q_ZMcP8faw4",
|
||||
name: "crab rangoon toast 🦀 🍞",
|
||||
length: Some(55),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/Q_ZMcP8faw4/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLATLiHTNqLoBKsEKbOckkGjXMvoHA",
|
||||
|
@ -798,7 +798,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "1aedyP3r3D0",
|
||||
name: "my secret hot pot sauce 🧙\u{200d}♀\u{fe0f}🍃",
|
||||
length: Some(59),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/1aedyP3r3D0/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCh2MpR5k3jCS_wfX-wjtVuIcu7YQ",
|
||||
|
@ -824,7 +824,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "fkPkHZ1yyBU",
|
||||
name: "the good vs the bad",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/fkPkHZ1yyBU/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCMngiRtLrBPppmfPnJwJ-cYMwttA",
|
||||
|
@ -850,7 +850,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "NbQcySLMLmA",
|
||||
name: "cooking with waste?!🗑\u{fe0f}",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/NbQcySLMLmA/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCvxPQo9eqYwjk4cxyBnrHed-tcZg",
|
||||
|
@ -876,7 +876,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "3w_5vzM1Pc4",
|
||||
name: "Shrek burger 🍔🍀👹",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/3w_5vzM1Pc4/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLB64zOKgmhOt7bvQseeIbjKBICDAg",
|
||||
|
@ -902,7 +902,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "girJP2r_zLg",
|
||||
name: "$$$ on food",
|
||||
length: Some(55),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/girJP2r_zLg/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBg2hmruZvx30aiP4Jb4dhz03qOZA",
|
||||
|
@ -928,7 +928,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "zHp7sZ5OONM",
|
||||
name: "pumpkin spice churro?! 🎃",
|
||||
length: Some(58),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/zHp7sZ5OONM/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLD8ZrcI6mq91ARKnRb_vg-0Qv2raw",
|
||||
|
@ -954,7 +954,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "iqMl3gQEZ0E",
|
||||
name: "3,000,000",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/iqMl3gQEZ0E/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBUC1sw84NlLiyTJTcfnDWFjVC75w",
|
||||
|
@ -980,7 +980,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "glyJWxp7a5g",
|
||||
name: "being smart was my personality trait",
|
||||
length: Some(56),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/glyJWxp7a5g/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBbrWwLndPt5ZV5x4dnqmTC_aAhig",
|
||||
|
@ -1006,7 +1006,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "dd1EZIkANYs",
|
||||
name: "the horror maze",
|
||||
length: Some(44),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/dd1EZIkANYs/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBlqz2BM3K2VeLlXMPBVwXNXih6vg",
|
||||
|
@ -1032,7 +1032,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "enioc_stRww",
|
||||
name: "furikake bagels with wasabi cream cheese",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/enioc_stRww/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBz9Qo96FWssNsMhQ54DMxdYYwLfQ",
|
||||
|
@ -1058,7 +1058,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "NUM8kCPas5w",
|
||||
name: "simple is best",
|
||||
length: Some(49),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/NUM8kCPas5w/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLC8N3YRr9A6-u6L0AtMynct4C_GzQ",
|
||||
|
@ -1084,7 +1084,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "1djkcsFnlYE",
|
||||
name: "edible history lesson!",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/1djkcsFnlYE/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBHn_6yOrnRXH_zbxVaAuKzSulcew",
|
||||
|
@ -1110,7 +1110,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "cIYrJtAoftI",
|
||||
name: "and I\'m feeling good",
|
||||
length: Some(53),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/cIYrJtAoftI/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLC4q0VcbBZroejhAztDkdlk7Ww5Og",
|
||||
|
@ -1136,7 +1136,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "cCrH8Er5tf4",
|
||||
name: "Rating Korean Convenience Store Milk Flavors 🥛🍼",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/cCrH8Er5tf4/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBwc2ikrGH_gZfcyqTnZDfHjt5LuA",
|
||||
|
@ -1162,7 +1162,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "tav5wsH7pzU",
|
||||
name: "online dating?",
|
||||
length: Some(58),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/tav5wsH7pzU/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCheup7XAM_O1UAMEO5Iqup4-lGRQ",
|
||||
|
@ -1188,7 +1188,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "5Vd4_GXjF7o",
|
||||
name: "Creating thumbnails has never been easier with Adobe Express",
|
||||
length: Some(26),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/5Vd4_GXjF7o/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCbYkH7INYGHW0IcO3DKip5iD2PCA",
|
||||
|
@ -1214,7 +1214,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "-FN1sEI8HkU",
|
||||
name: "my favorite color is green",
|
||||
length: Some(45),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/-FN1sEI8HkU/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLCLWKPrR-VCdsXagJ1MIyah7dDdDQ",
|
||||
|
@ -1240,7 +1240,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "viT-dcl2DGE",
|
||||
name: "frodo baggins?",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/viT-dcl2DGE/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLDb0oYC_3V79CSR0j-4sR4CuNQekQ",
|
||||
|
@ -1266,7 +1266,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "N5AKQflK1TU",
|
||||
name: "When you impulse buy...",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/N5AKQflK1TU/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLDwfPTcuQHyziYsmTrSkg9xi1jnag",
|
||||
|
@ -1292,7 +1292,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "OzIFALQ_YtA",
|
||||
name: "taste testing gam!",
|
||||
length: Some(60),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/OzIFALQ_YtA/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBMcyG6Fu4rrXk-JQL5tx0hzSAxlw",
|
||||
|
@ -1318,7 +1318,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "dAcJILbc_0Q",
|
||||
name: "How to: Korean rice wine 🍶 (makgeolli)",
|
||||
length: Some(59),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/dAcJILbc_0Q/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLAXbHym4PFTTO25GCI4n1tjSaQVCw",
|
||||
|
@ -1344,7 +1344,7 @@ Channel(
|
|||
VideoItem(
|
||||
id: "GvutfmW26JQ",
|
||||
name: "👹stay sour 🍋",
|
||||
length: Some(52),
|
||||
length: None,
|
||||
thumbnail: [
|
||||
Thumbnail(
|
||||
url: "https://i.ytimg.com/vi/GvutfmW26JQ/oar2.jpg?sqp=-oaymwEaCJUDENAFSFXyq4qpAwwIARUAAIhCcAHAAQY=&rs=AOn4CLBgCJ06W3wOend0UgkuBKoHOg0eig",
|
||||
|
|
|
@ -391,24 +391,25 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
comma_decimal: false,
|
||||
number_tokens: ::phf::Map {
|
||||
key: 12913932095322966823,
|
||||
key: 10121458955350035957,
|
||||
disps: &[
|
||||
(0, 7),
|
||||
(9, 8),
|
||||
(0, 0),
|
||||
(1, 0),
|
||||
(3, 6),
|
||||
(1, 4),
|
||||
],
|
||||
entries: &[
|
||||
("হ\u{9be}", 3),
|
||||
("হ\u{9be}জ\u{9be}ৰট\u{9be}", 3),
|
||||
("নিয\u{9c1}তট\u{9be}", 6),
|
||||
("হ\u{9be}জ\u{9be}ৰ", 3),
|
||||
("ল\u{9be}", 5),
|
||||
("কোঃ", 5),
|
||||
("ল\u{9be}খট\u{9be}", 5),
|
||||
("কোঃট\u{9be}", 9),
|
||||
("নিঃট\u{9be}", 6),
|
||||
("নিয\u{9c1}ত", 6),
|
||||
("নিঃ", 6),
|
||||
("ল\u{9be}খ", 5),
|
||||
("নিঃট\u{9be}", 6),
|
||||
("হ\u{9be}জ\u{9be}ৰট\u{9be}", 3),
|
||||
("কোঃট\u{9be}", 9),
|
||||
("নিঃ", 6),
|
||||
("নিয\u{9c1}তট\u{9be}", 6),
|
||||
("ল\u{9be}", 5),
|
||||
("নিয\u{9c1}ত", 6),
|
||||
("হ\u{9be}জ\u{9be}ৰ", 3),
|
||||
],
|
||||
},
|
||||
number_nd_tokens: ::phf::Map {
|
||||
|
@ -890,14 +891,15 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
comma_decimal: true,
|
||||
number_tokens: ::phf::Map {
|
||||
key: 12913932095322966823,
|
||||
key: 10121458955350035957,
|
||||
disps: &[
|
||||
(2, 0),
|
||||
],
|
||||
entries: &[
|
||||
("hilj", 3),
|
||||
("mlr", 9),
|
||||
("mil", 6),
|
||||
("mlr", 9),
|
||||
("hilj", 3),
|
||||
("mlrd", 9),
|
||||
],
|
||||
},
|
||||
number_nd_tokens: ::phf::Map {
|
||||
|
@ -3094,8 +3096,9 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
(0, 0),
|
||||
],
|
||||
entries: &[
|
||||
("mrd", 9),
|
||||
("mio", 6),
|
||||
("mln", 6),
|
||||
("mrd", 9),
|
||||
],
|
||||
},
|
||||
number_nd_tokens: ::phf::Map {
|
||||
|
|
|
@ -643,6 +643,9 @@ pub(crate) mod tests {
|
|||
#[case(Language::As, "১ জন গ্ৰাহক", 1)]
|
||||
#[case(Language::Ru, "Зрителей, ожидающих начала трансляции: 6", 6)]
|
||||
#[case(Language::Si, "වාදන මි4.6ක්", 4_600_000)]
|
||||
#[case(Language::As, "3.7 শঃ কোঃ বাৰ প্লে’ কৰা হৈছে", 370_000)]
|
||||
#[case(Language::Bs, "3,3 mlrd. pregleda", 3_300_000_000)]
|
||||
#[case(Language::It, "3,73 Mio di iscritti", 3_730_000)]
|
||||
fn t_parse_large_numstr(#[case] lang: Language, #[case] string: &str, #[case] expect: u64) {
|
||||
let res = parse_large_numstr::<u64>(string, lang).unwrap();
|
||||
assert_eq!(res, expect);
|
||||
|
|
|
@ -322,6 +322,10 @@ pub fn parse_video_duration(lang: Language, video_duration: &str) -> Option<u32>
|
|||
let parts = split_duration_txt(video_duration, matches!(lang, Language::Si | Language::Sw));
|
||||
let mut secs = 0;
|
||||
|
||||
if parts.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
for part in parts {
|
||||
let mut n = if part.digits.is_empty() {
|
||||
1
|
||||
|
|
|
@ -203,6 +203,7 @@
|
|||
"হা": 3,
|
||||
"হাজাৰ": 3,
|
||||
"হাজাৰটা": 3,
|
||||
"কোঃ": 5,
|
||||
"লা": 5,
|
||||
"লাখ": 5,
|
||||
"লাখটা": 5,
|
||||
|
@ -504,7 +505,8 @@
|
|||
"number_tokens": {
|
||||
"hilj": 3,
|
||||
"mil": 6,
|
||||
"mlr": 9
|
||||
"mlr": 9,
|
||||
"mlrd": 9
|
||||
},
|
||||
"number_nd_tokens": {
|
||||
"nema": 0
|
||||
|
@ -1818,6 +1820,7 @@
|
|||
},
|
||||
"comma_decimal": true,
|
||||
"number_tokens": {
|
||||
"mio": 6,
|
||||
"mln": 6,
|
||||
"mrd": 9
|
||||
},
|
||||
|
|
|
@ -831,7 +831,6 @@ fn channel_videos(rp: RustyPipe) {
|
|||
fn channel_shorts(rp: RustyPipe) {
|
||||
let channel = tokio_test::block_on(
|
||||
rp.query()
|
||||
.lang(Language::Sq)
|
||||
.channel_videos_tab("UCh8gHdtzO2tXd593_bjErWg", ChannelVideoTab::Shorts),
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -1538,7 +1537,7 @@ fn music_album_not_found(rp: RustyPipe) {
|
|||
// #[case::basic("basic", "UC7cl4MmM6ZZ2TcFyMk_b4pg", false, 15, 2)]
|
||||
#[case::no_more_albums("no_more_albums", "UCOR4_bSVIXPsGa4BbCSt60Q", true, 15, 0)]
|
||||
#[case::only_singles("only_singles", "UCfwCE5VhPMGxNPFxtVv7lRw", false, 13, 0)]
|
||||
#[case::no_artist("no_artist", "UCh8gHdtzO2tXd593_bjErWg", false, 0, 2)]
|
||||
#[case::no_artist("no_artist", "UCh8gHdtzO2tXd593_bjErWg", false, 0, 0)]
|
||||
// querying Trailerpark's secondary YouTube channel should result in the YTM channel being fetched
|
||||
#[case::secondary_channel("no_more_albums", "UCC9192yGQD25eBZgFZ84MPw", true, 15, 0)]
|
||||
fn music_artist(
|
||||
|
@ -1961,12 +1960,12 @@ fn music_search_albums(
|
|||
|
||||
assert_eq!(album.artists.len(), 1);
|
||||
let album_artist = &album.artists[0];
|
||||
assert_eq!(album_artist.id.as_ref().unwrap(), artist_id);
|
||||
assert_eq!(album_artist.id.as_ref().expect("artist.id"), artist_id);
|
||||
if unlocalized {
|
||||
assert_eq!(album_artist.name, artist);
|
||||
}
|
||||
|
||||
assert_eq!(album.artist_id.as_ref().unwrap(), artist_id);
|
||||
assert_eq!(album.artist_id.as_ref().expect("artist_id"), artist_id);
|
||||
assert!(!album.cover.is_empty(), "got no cover");
|
||||
assert_eq!(album.year.as_ref().unwrap(), &year);
|
||||
assert_eq!(album.album_type, album_type);
|
||||
|
@ -2012,11 +2011,7 @@ fn music_search_artists_cont(rp: RustyPipe) {
|
|||
|
||||
#[rstest]
|
||||
fn music_search_playlists(rp: RustyPipe, unlocalized: bool) {
|
||||
let res = tokio_test::block_on(
|
||||
rp.query()
|
||||
.music_search_playlists("today's rock hits", false),
|
||||
)
|
||||
.unwrap();
|
||||
let res = tokio_test::block_on(rp.query().music_search_playlists("rock hits", false)).unwrap();
|
||||
|
||||
assert_eq!(res.corrected_query, None);
|
||||
let playlist = res
|
||||
|
@ -2029,7 +2024,7 @@ fn music_search_playlists(rp: RustyPipe, unlocalized: bool) {
|
|||
});
|
||||
|
||||
if unlocalized {
|
||||
assert_eq!(playlist.name, "Today's Rock Hits");
|
||||
assert_eq!(playlist.name, "Rock Hits");
|
||||
}
|
||||
assert!(!playlist.thumbnail.is_empty(), "got no thumbnail");
|
||||
assert_gte(playlist.track_count.unwrap(), 100, "tracks");
|
||||
|
|
Loading…
Reference in a new issue