fix: extracting artist discography with without page type

This commit is contained in:
ThetaDev 2023-05-31 11:38:50 +02:00
parent 0cd018e37a
commit 182f9ebfb8
4 changed files with 45 additions and 28 deletions

View file

@ -4,7 +4,7 @@ use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
use crate::{ use crate::{
client::response::url_endpoint::{MusicPageType, NavigationEndpoint}, client::response::url_endpoint::NavigationEndpoint,
error::{Error, ExtractionError}, error::{Error, ExtractionError},
model::{AlbumItem, ArtistId, MusicArtist}, model::{AlbumItem, ArtistId, MusicArtist},
serializer::MapResult, serializer::MapResult,
@ -191,20 +191,29 @@ fn map_artist_page(
.music_carousel_shelf_basic_header_renderer .music_carousel_shelf_basic_header_renderer
.more_content_button .more_content_button
{ {
match button.button_renderer.navigation_endpoint.music_page() { if let NavigationEndpoint::Browse {
browse_endpoint, ..
} = button.button_renderer.navigation_endpoint
{
// Music videos // Music videos
Some((MusicPageType::Playlist, id)) => { if browse_endpoint
.browse_endpoint_context_supported_configs
.map(|cfg| {
cfg.browse_endpoint_context_music_config.page_type
== PageType::Playlist
})
.unwrap_or_default()
{
if videos_playlist_id.is_none() { if videos_playlist_id.is_none() {
videos_playlist_id = Some(id); videos_playlist_id = Some(browse_endpoint.browse_id);
} }
} } else if browse_endpoint
// Albums .browse_id
Some((MusicPageType::ArtistDiscography, _)) => { .starts_with(util::ARTIST_DISCOGRAPHY_PREFIX)
{
can_fetch_more = true; can_fetch_more = true;
extendable_albums = true; extendable_albums = true;
} } else {
// Albums or playlists
Some((MusicPageType::Artist, _)) => {
// Peek at the first item to determine type // Peek at the first item to determine type
if let Some(response::music_item::MusicResponseItem::MusicTwoRowItemRenderer(item)) = shelf.contents.c.first() { if let Some(response::music_item::MusicResponseItem::MusicTwoRowItemRenderer(item)) = shelf.contents.c.first() {
if let Some(PageType::Album) = item.navigation_endpoint.page_type() { if let Some(PageType::Album) = item.navigation_endpoint.page_type() {
@ -213,7 +222,6 @@ fn map_artist_page(
} }
} }
} }
_ => {}
} }
} }
} }

View file

@ -759,7 +759,7 @@ impl MusicListMapper {
})); }));
Ok(Some(MusicItemType::Playlist)) Ok(Some(MusicItemType::Playlist))
} }
MusicPageType::None | MusicPageType::ArtistDiscography => { MusicPageType::None => {
// There may be broken YT channels from the artist search. They can be skipped. // There may be broken YT channels from the artist search. They can be skipped.
Ok(None) Ok(None)
} }
@ -901,7 +901,7 @@ impl MusicListMapper {
})); }));
Ok(Some(MusicItemType::Playlist)) Ok(Some(MusicItemType::Playlist))
} }
MusicPageType::None | MusicPageType::ArtistDiscography => Ok(None), MusicPageType::None => Ok(None),
MusicPageType::Unknown => { MusicPageType::Unknown => {
self.has_unknown = true; self.has_unknown = true;
Ok(None) Ok(None)
@ -1039,7 +1039,7 @@ impl MusicListMapper {
})); }));
Some(MusicItemType::Playlist) Some(MusicItemType::Playlist)
} }
MusicPageType::None | MusicPageType::ArtistDiscography => None, MusicPageType::None => None,
MusicPageType::Unknown => { MusicPageType::Unknown => {
self.has_unknown = true; self.has_unknown = true;
None None

View file

@ -102,9 +102,12 @@ pub(crate) struct BrowseEndpointConfig {
pub browse_endpoint_context_music_config: BrowseEndpointMusicConfig, pub browse_endpoint_context_music_config: BrowseEndpointMusicConfig,
} }
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub(crate) struct BrowseEndpointMusicConfig { pub(crate) struct BrowseEndpointMusicConfig {
#[serde(default)]
#[serde_as(as = "DefaultOnError")]
pub page_type: PageType, pub page_type: PageType,
} }
@ -114,9 +117,12 @@ pub(crate) struct CommandMetadata {
pub web_command_metadata: WebCommandMetadata, pub web_command_metadata: WebCommandMetadata,
} }
#[serde_as]
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub(crate) struct WebCommandMetadata { pub(crate) struct WebCommandMetadata {
#[serde(default)]
#[serde_as(as = "DefaultOnError")]
pub web_page_type: PageType, pub web_page_type: PageType,
} }
@ -144,15 +150,13 @@ pub(crate) enum MusicVideoType {
Track, Track,
} }
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)] #[derive(Default, Debug, Clone, Copy, Deserialize, PartialEq, Eq)]
pub(crate) enum PageType { pub(crate) enum PageType {
#[serde( #[serde(
rename = "MUSIC_PAGE_TYPE_ARTIST", rename = "MUSIC_PAGE_TYPE_ARTIST",
alias = "MUSIC_PAGE_TYPE_AUDIOBOOK_ARTIST" alias = "MUSIC_PAGE_TYPE_AUDIOBOOK_ARTIST"
)] )]
Artist, Artist,
#[serde(rename = "MUSIC_PAGE_TYPE_ARTIST_DISCOGRAPHY")]
ArtistDiscography,
#[serde(rename = "MUSIC_PAGE_TYPE_ALBUM", alias = "MUSIC_PAGE_TYPE_AUDIOBOOK")] #[serde(rename = "MUSIC_PAGE_TYPE_ALBUM", alias = "MUSIC_PAGE_TYPE_AUDIOBOOK")]
Album, Album,
#[serde( #[serde(
@ -162,7 +166,7 @@ pub(crate) enum PageType {
Channel, Channel,
#[serde(rename = "MUSIC_PAGE_TYPE_PLAYLIST", alias = "WEB_PAGE_TYPE_PLAYLIST")] #[serde(rename = "MUSIC_PAGE_TYPE_PLAYLIST", alias = "WEB_PAGE_TYPE_PLAYLIST")]
Playlist, Playlist,
#[serde(rename = "MUSIC_PAGE_TYPE_UNKNOWN")] #[default]
Unknown, Unknown,
} }
@ -170,9 +174,6 @@ impl PageType {
pub(crate) fn to_url_target(self, id: String) -> Option<UrlTarget> { pub(crate) fn to_url_target(self, id: String) -> Option<UrlTarget> {
match self { match self {
PageType::Artist | PageType::Channel => Some(UrlTarget::Channel { id }), PageType::Artist | PageType::Channel => Some(UrlTarget::Channel { id }),
PageType::ArtistDiscography => id
.strip_prefix(util::ARTIST_DISCOGRAPHY_PREFIX)
.map(|id| UrlTarget::Channel { id: id.to_owned() }),
PageType::Album => Some(UrlTarget::Album { id }), PageType::Album => Some(UrlTarget::Album { id }),
PageType::Playlist => Some(UrlTarget::Playlist { id }), PageType::Playlist => Some(UrlTarget::Playlist { id }),
PageType::Unknown => None, PageType::Unknown => None,
@ -183,7 +184,6 @@ impl PageType {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(crate) enum MusicPageType { pub(crate) enum MusicPageType {
Artist, Artist,
ArtistDiscography,
Album, Album,
Playlist, Playlist,
Track { is_video: bool }, Track { is_video: bool },
@ -195,7 +195,6 @@ impl From<PageType> for MusicPageType {
fn from(t: PageType) -> Self { fn from(t: PageType) -> Self {
match t { match t {
PageType::Artist => MusicPageType::Artist, PageType::Artist => MusicPageType::Artist,
PageType::ArtistDiscography => MusicPageType::ArtistDiscography,
PageType::Album => MusicPageType::Album, PageType::Album => MusicPageType::Album,
PageType::Playlist => MusicPageType::Playlist, PageType::Playlist => MusicPageType::Playlist,
PageType::Channel => MusicPageType::None, PageType::Channel => MusicPageType::None,

View file

@ -80,32 +80,42 @@ SAttributed {
Text { Text {
text: "\n\n", text: "\n\n",
}, },
Text { Browse {
text: "#aespa", text: "#aespa",
page_type: Unknown,
browse_id: "FEhashtag",
}, },
Text { Text {
text: " ", text: " ",
}, },
Text { Browse {
text: "#æspa", text: "#æspa",
page_type: Unknown,
browse_id: "FEhashtag",
}, },
Text { Text {
text: " ", text: " ",
}, },
Text { Browse {
text: "#BlackMamba", text: "#BlackMamba",
page_type: Unknown,
browse_id: "FEhashtag",
}, },
Text { Text {
text: " ", text: " ",
}, },
Text { Browse {
text: "#블랙맘바", text: "#블랙맘바",
page_type: Unknown,
browse_id: "FEhashtag",
}, },
Text { Text {
text: " ", text: " ",
}, },
Text { Browse {
text: "#에스파", text: "#에스파",
page_type: Unknown,
browse_id: "FEhashtag",
}, },
Text { Text {
text: "\naespa 에스파 'Black Mamba' MV ℗ SM Entertainment", text: "\naespa 에스파 'Black Mamba' MV ℗ SM Entertainment",