diff --git a/codegen/src/abtest.rs b/codegen/src/abtest.rs index 23dd8ea..a87873f 100644 --- a/codegen/src/abtest.rs +++ b/codegen/src/abtest.rs @@ -27,7 +27,6 @@ pub enum ABTest { TrackViewcount = 8, PlaylistsForShorts = 9, ChannelAboutModal = 10, - LikeButtonViewmodel = 11, } const TESTS_TO_RUN: [ABTest; 3] = [ @@ -101,7 +100,6 @@ pub async fn run_test( ABTest::PlaylistsForShorts => playlists_for_shorts(&query).await, ABTest::TrackViewcount => track_viewcount(&query).await, ABTest::ChannelAboutModal => channel_about_modal(&query).await, - ABTest::LikeButtonViewmodel => like_button_viewmodel(&query).await, } .unwrap(); pb.inc(1); @@ -303,19 +301,3 @@ pub async fn channel_about_modal(rp: &RustyPipeQuery) -> Result { .unwrap(); Ok(!res.contains("\"EgVhYm91dPIGBAoCEgA%3D\"")) } - -pub async fn like_button_viewmodel(rp: &RustyPipeQuery) -> Result { - let res = rp - .raw( - ClientType::Desktop, - "next", - &QVideo { - context: rp.get_context(ClientType::Desktop, true, None).await, - video_id: "ZeerrnuLi5E", - content_check_ok: true, - racy_check_ok: true, - }, - ) - .await?; - Ok(res.contains("\"segmentedLikeDislikeButtonViewModel\"")) -} diff --git a/notes/AB_Tests.md b/notes/AB_Tests.md index a6108e8..20efb3b 100644 --- a/notes/AB_Tests.md +++ b/notes/AB_Tests.md @@ -432,35 +432,3 @@ channel metadata has to be fetched. The new modal uses a continuation request with a token which can be easily generated. Attempts to fetch the old about tab with the A/B test enabled will lead to a redirect to the main tab. - -## [11] Like-Button viewmodel - -- **Encountered on:** 03.11.2023 -- **Impact:** 🟢 Low -- **Endpoint:** next - -YouTube introduced an updated date model for the like/dislike buttons. The new model -looks needlessly complex but contains the same parsing-relevant data as the old model -(accessibility text to get like count). - -```json -{ - "segmentedLikeDislikeButtonViewModel": { - "likeButtonViewModel": { - "likeButtonViewModel": { - "toggleButtonViewModel": { - "toggleButtonViewModel": { - "defaultButtonViewModel": { - "buttonViewModel": { - "iconName": "LIKE", - "title": "4.2M", - "accessibilityText": "like this video along with 4,209,059 other people" - } - } - } - } - } - } - } -} -``` diff --git a/src/client/channel.rs b/src/client/channel.rs index fa4d0ac..4af14ee 100644 --- a/src/client/channel.rs +++ b/src/client/channel.rs @@ -291,14 +291,10 @@ impl MapResponse for response::ChannelAbout { fn map_response( self, _id: &str, - _lang: Language, + lang: Language, _deobf: Option<&crate::deobfuscate::DeobfData>, _visitor_data: Option<&str>, ) -> Result, ExtractionError> { - // Channel info is always fetched in English. There is no localized data there - // and it allows parsing the country name. - let lang = Language::En; - let ep = self .on_response_received_endpoints .into_iter() diff --git a/src/client/response/video_details.rs b/src/client/response/video_details.rs index 50373d7..c9b4d2e 100644 --- a/src/client/response/video_details.rs +++ b/src/client/response/video_details.rs @@ -147,46 +147,6 @@ pub(crate) enum TopLevelButton { SegmentedLikeDislikeButtonRenderer { like_button: ToggleButtonWrap, }, - #[serde(rename_all = "camelCase")] - SegmentedLikeDislikeButtonViewModel { - like_button_view_model: LikeButtonViewModelWrap, - }, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct LikeButtonViewModelWrap { - pub like_button_view_model: LikeButtonViewModel, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct LikeButtonViewModel { - pub toggle_button_view_model: ToggleButtonViewModelWrap, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct ToggleButtonViewModelWrap { - pub toggle_button_view_model: ToggleButtonViewModel, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct ToggleButtonViewModel { - pub default_button_view_model: ButtonViewModelWrap, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct ButtonViewModelWrap { - pub button_view_model: ButtonViewModel, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct ButtonViewModel { - pub accessibility_text: String, } /// Like/Dislike button diff --git a/src/client/video_details.rs b/src/client/video_details.rs index 14949be..32b63f4 100644 --- a/src/client/video_details.rs +++ b/src/client/video_details.rs @@ -159,20 +159,17 @@ impl MapResponse for response::VideoDetails { video_actions, date_text, }) => { - let like_text = video_actions + let like_btn = video_actions .menu_renderer .top_level_buttons .into_iter() .find_map(|button| { - let (icon, text) = match button { - response::video_details::TopLevelButton::ToggleButtonRenderer(btn) => (btn.default_icon.icon_type, btn.accessibility_data), - response::video_details::TopLevelButton::SegmentedLikeDislikeButtonRenderer { like_button } => (like_button.toggle_button_renderer.default_icon.icon_type, like_button.toggle_button_renderer.accessibility_data), - response::video_details::TopLevelButton::SegmentedLikeDislikeButtonViewModel { like_button_view_model } => { - (IconType::Like, like_button_view_model.like_button_view_model.toggle_button_view_model.toggle_button_view_model.default_button_view_model.button_view_model.accessibility_text) - }, + let btn = match button { + response::video_details::TopLevelButton::ToggleButtonRenderer(btn) => btn, + response::video_details::TopLevelButton::SegmentedLikeDislikeButtonRenderer { like_button } => like_button.toggle_button_renderer, }; - match icon { - IconType::Like => Some(text), + match btn.default_icon.icon_type { + IconType::Like => Some(btn), _ => None } }); @@ -187,7 +184,7 @@ impl MapResponse for response::VideoDetails { .unwrap_or_default(), // accessibility_data contains no digits if the like count is hidden, // so we ignore parse errors here for now - like_text.and_then(|txt| util::parse_numeric(&txt).ok()), + like_btn.and_then(|btn| util::parse_numeric(&btn.accessibility_data).ok()), date_text.as_deref().and_then(|txt| { timeago::parse_textual_date_or_warn(lang, txt, &mut warnings) }), diff --git a/src/util/mod.rs b/src/util/mod.rs index c1c4f17..9de438d 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -362,7 +362,6 @@ where let mut filtered = String::new(); let mut exp = 0; let mut after_point = false; - let mut last_number = false; for c in string.chars() { if c.is_ascii_digit() { @@ -371,10 +370,6 @@ where if after_point { exp -= 1; } - if !last_number { - filtered.push(' '); - last_number = true; - } } else if c == decimal_point && !digits.is_empty() { after_point = true; } else if !matches!( @@ -382,7 +377,6 @@ where '\u{200b}' | '\u{202b}' | '\u{202c}' | '\u{202e}' | '\u{200e}' | '\u{200f}' | '.' | ',' ) { c.to_lowercase().for_each(|c| filtered.push(c)); - last_number = false; } } @@ -642,7 +636,6 @@ pub(crate) mod tests { )] #[case(Language::As, "১ জন গ্ৰাহক", 1)] #[case(Language::Ru, "Зрителей, ожидающих начала трансляции: 6", 6)] - #[case(Language::Si, "වාදන මි4.6ක්", 4_600_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);