From daf3d035be38b59aef1ae205ac91c2bbdda2fe66 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Mon, 31 Mar 2025 18:11:14 +0200 Subject: [PATCH] fix: handle music artist not found --- src/client/music_artist.rs | 22 +++++++++++++++++++--- src/client/music_playlist.rs | 15 ++++----------- src/client/response/music_artist.rs | 9 ++++++--- src/client/response/music_item.rs | 16 ++++++++++++++++ src/client/response/music_playlist.rs | 21 +++------------------ 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/client/music_artist.rs b/src/client/music_artist.rs index c73b919..13cbeda 100644 --- a/src/client/music_artist.rs +++ b/src/client/music_artist.rs @@ -154,7 +154,24 @@ fn map_artist_page( ctx: &MapRespCtx<'_>, skip_extendables: bool, ) -> Result, ExtractionError> { - let header = res.header.music_immersive_header_renderer; + let contents = match res.contents { + Some(c) => c, + None => { + if res.microformat.microformat_data_renderer.noindex { + return Err(ExtractionError::NotFound { + id: ctx.id.to_owned(), + msg: "no contents".into(), + }); + } else { + return Err(ExtractionError::InvalidData("no contents".into())); + } + } + }; + + let header = res + .header + .ok_or(ExtractionError::InvalidData("no header".into()))? + .music_immersive_header_renderer; if let Some(share) = header.share_endpoint { let pb = share.share_entity_endpoint.serialized_share_entity; @@ -171,8 +188,7 @@ fn map_artist_page( } } - let sections = res - .contents + let sections = contents .single_column_browse_results_renderer .contents .into_iter() diff --git a/src/client/music_playlist.rs b/src/client/music_playlist.rs index ccd5f21..64f3d7e 100644 --- a/src/client/music_playlist.rs +++ b/src/client/music_playlist.rs @@ -154,11 +154,7 @@ impl MapResponse for response::MusicPlaylist { let contents = match self.contents { Some(c) => c, None => { - if self - .microformat - .map(|m| m.microformat_data_renderer.noindex) - .unwrap_or_default() - { + if self.microformat.microformat_data_renderer.noindex { return Err(ExtractionError::NotFound { id: ctx.id.to_owned(), msg: "no contents".into(), @@ -359,11 +355,7 @@ impl MapResponse for response::MusicPlaylist { let contents = match self.contents { Some(c) => c, None => { - if self - .microformat - .map(|m| m.microformat_data_renderer.noindex) - .unwrap_or_default() - { + if self.microformat.microformat_data_renderer.noindex { return Err(ExtractionError::NotFound { id: ctx.id.to_owned(), msg: "no contents".into(), @@ -492,7 +484,8 @@ impl MapResponse for response::MusicPlaylist { let playlist_id = self .microformat - .and_then(|mf| mf.microformat_data_renderer.url_canonical) + .microformat_data_renderer + .url_canonical .and_then(|x| { x.strip_prefix("https://music.youtube.com/playlist?list=") .map(str::to_owned) diff --git a/src/client/response/music_artist.rs b/src/client/response/music_artist.rs index 88232ad..d510cf9 100644 --- a/src/client/response/music_artist.rs +++ b/src/client/response/music_artist.rs @@ -5,7 +5,8 @@ use crate::serializer::text::Text; use super::{ music_item::{ - Button, Grid, ItemSection, MusicThumbnailRenderer, SimpleHeader, SingleColumnBrowseResult, + Button, Grid, ItemSection, MusicMicroformat, MusicThumbnailRenderer, SimpleHeader, + SingleColumnBrowseResult, }, SectionList, Tab, }; @@ -14,8 +15,10 @@ use super::{ #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct MusicArtist { - pub contents: SingleColumnBrowseResult>>, - pub header: Header, + pub contents: Option>>>, + pub header: Option
, + #[serde(default)] + pub microformat: MusicMicroformat, } #[derive(Debug, Deserialize)] diff --git a/src/client/response/music_item.rs b/src/client/response/music_item.rs index 5a6ab05..bc912c9 100644 --- a/src/client/response/music_item.rs +++ b/src/client/response/music_item.rs @@ -433,6 +433,22 @@ pub(crate) enum TrackBadge { LiveBadgeRenderer {}, } +#[serde_as] +#[derive(Default, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct MusicMicroformat { + #[serde_as(as = "DefaultOnError")] + pub microformat_data_renderer: MicroformatData, +} + +#[derive(Default, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct MicroformatData { + pub url_canonical: Option, + #[serde(default)] + pub noindex: bool, +} + /* #MAPPER */ diff --git a/src/client/response/music_playlist.rs b/src/client/response/music_playlist.rs index 05abfbb..84202f0 100644 --- a/src/client/response/music_playlist.rs +++ b/src/client/response/music_playlist.rs @@ -5,22 +5,21 @@ use crate::serializer::text::{AttributedText, Text, TextComponents}; use super::{ music_item::{ - Button, ItemSection, MusicContentsRenderer, MusicItemMenuEntry, MusicThumbnailRenderer, + Button, ItemSection, MusicContentsRenderer, MusicItemMenuEntry, MusicMicroformat, + MusicThumbnailRenderer, }, url_endpoint::OnTapWrap, ContentsRenderer, SectionList, Tab, }; /// Response model for YouTube Music playlists and albums -#[serde_as] #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct MusicPlaylist { pub contents: Option, pub header: Option
, #[serde(default)] - #[serde_as(as = "DefaultOnError")] - pub microformat: Option, + pub microformat: MusicMicroformat, } #[serde_as] @@ -162,17 +161,3 @@ pub(crate) struct AvatarStackViewModel { pub(crate) struct AvatarStackRendererContext { pub command_context: Option, } - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct Microformat { - pub microformat_data_renderer: MicroformatData, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct MicroformatData { - pub url_canonical: Option, - #[serde(default)] - pub noindex: bool, -}