From fd3e128f5002f572f80b0215ef9df8dc80f479b9 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Thu, 18 Jan 2024 16:03:15 +0100 Subject: [PATCH 1/2] fix: remove shorts duration parsing --- src/client/response/video_item.rs | 90 +------------------------------ src/util/timeago.rs | 4 ++ tests/youtube.rs | 1 - 3 files changed, 6 insertions(+), 89 deletions(-) diff --git a/src/client/response/video_item.rs b/src/client/response/video_item.rs index a46b0a0..c151e08 100644 --- a/src/client/response/video_item.rs +++ b/src/client/response/video_item.rs @@ -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")] pub view_count_text: Option, - /// video duration - /// - /// Example: `the horror maze - 44 seconds - play video` - /// - /// Dashes may be `\u2013` (emdash) - #[serde_as(as = "Option")] - pub accessibility: Option, #[serde(default)] #[serde_as(as = "DefaultOnError")] pub navigation_endpoint: Option, @@ -395,10 +386,6 @@ impl IsShort for Vec { } } -static ACCESSIBILITY_SEP_REGEX: Lazy = 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 YouTubeListMapper { .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::>(); - 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 { 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::>(); - 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::>(); - assert_eq!(parts[parts.len() - 1], "1 минута."); - } -} diff --git a/src/util/timeago.rs b/src/util/timeago.rs index aa9781a..bcd25f0 100644 --- a/src/util/timeago.rs +++ b/src/util/timeago.rs @@ -322,6 +322,10 @@ pub fn parse_video_duration(lang: Language, video_duration: &str) -> Option 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 diff --git a/tests/youtube.rs b/tests/youtube.rs index 1207df8..0629b56 100644 --- a/tests/youtube.rs +++ b/tests/youtube.rs @@ -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(); From d413cad8bbe0957aae150e21c9f1121fda6a629c Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 24 Jan 2024 12:48:13 +0100 Subject: [PATCH 2/2] fix: number parsing for as,bs,it, update testdata --- ...t__channel__tests__map_channel_shorts.snap | 96 +++++++++---------- src/util/dictionary.rs | 35 +++---- src/util/mod.rs | 3 + testfiles/dict/dictionary.json | 5 +- tests/youtube.rs | 14 +-- 5 files changed, 79 insertions(+), 74 deletions(-) diff --git a/src/client/snapshots/rustypipe__client__channel__tests__map_channel_shorts.snap b/src/client/snapshots/rustypipe__client__channel__tests__map_channel_shorts.snap index 65d6b8b..c2116be 100644 --- a/src/client/snapshots/rustypipe__client__channel__tests__map_channel_shorts.snap +++ b/src/client/snapshots/rustypipe__client__channel__tests__map_channel_shorts.snap @@ -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", diff --git a/src/util/dictionary.rs b/src/util/dictionary.rs index d4d3b79..a7711ff 100644 --- a/src/util/dictionary.rs +++ b/src/util/dictionary.rs @@ -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 { diff --git a/src/util/mod.rs b/src/util/mod.rs index e48cd2b..34d09ac 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -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::(string, lang).unwrap(); assert_eq!(res, expect); diff --git a/testfiles/dict/dictionary.json b/testfiles/dict/dictionary.json index 66d9dea..9a1fc98 100644 --- a/testfiles/dict/dictionary.json +++ b/testfiles/dict/dictionary.json @@ -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 }, diff --git a/tests/youtube.rs b/tests/youtube.rs index 0629b56..60c5c0e 100644 --- a/tests/youtube.rs +++ b/tests/youtube.rs @@ -1537,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( @@ -1960,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); @@ -2011,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 @@ -2028,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");