fix: parsing is_ytm for playlists
This commit is contained in:
parent
0677fd487e
commit
97492780c6
7 changed files with 38 additions and 23 deletions
|
|
@ -52,6 +52,10 @@ pub struct DictEntry {
|
||||||
///
|
///
|
||||||
/// Format: Parsed token -> decimal power
|
/// Format: Parsed token -> decimal power
|
||||||
pub number_tokens: BTreeMap<String, u8>,
|
pub number_tokens: BTreeMap<String, u8>,
|
||||||
|
/// Tokens for parsing number strings with no digits (e.g. "No videos")
|
||||||
|
///
|
||||||
|
/// Format: Parsed token -> value
|
||||||
|
pub number_nd_tokens: BTreeMap<String, u8>,
|
||||||
/// Names of album types (Album, Single, ...)
|
/// Names of album types (Album, Single, ...)
|
||||||
///
|
///
|
||||||
/// Format: Parsed text -> Album type
|
/// Format: Parsed text -> Album type
|
||||||
|
|
|
||||||
|
|
@ -184,11 +184,7 @@ impl MapResponse<MusicPlaylist> for response::MusicPlaylist {
|
||||||
Some(header) => {
|
Some(header) => {
|
||||||
let h = header.music_detail_header_renderer;
|
let h = header.music_detail_header_renderer;
|
||||||
|
|
||||||
let from_ytm = h
|
let from_ytm = h.subtitle.0.iter().any(util::is_ytm);
|
||||||
.subtitle
|
|
||||||
.0
|
|
||||||
.iter()
|
|
||||||
.any(|c| c.as_str() == util::YT_MUSIC_NAME);
|
|
||||||
let channel = h
|
let channel = h
|
||||||
.subtitle
|
.subtitle
|
||||||
.0
|
.0
|
||||||
|
|
|
||||||
|
|
@ -731,7 +731,8 @@ impl MusicListMapper {
|
||||||
|
|
||||||
let from_ytm = channel_p
|
let from_ytm = channel_p
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| p.first_str() == util::YT_MUSIC_NAME)
|
.and_then(|p| p.0.first())
|
||||||
|
.map(util::is_ytm)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let channel = channel_p.and_then(|p| {
|
let channel = channel_p.and_then(|p| {
|
||||||
p.0.into_iter().find_map(|c| ChannelId::try_from(c).ok())
|
p.0.into_iter().find_map(|c| ChannelId::try_from(c).ok())
|
||||||
|
|
@ -872,7 +873,8 @@ impl MusicListMapper {
|
||||||
// (featured on the startpage or in genres)
|
// (featured on the startpage or in genres)
|
||||||
let from_ytm = subtitle_p2
|
let from_ytm = subtitle_p2
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| p.first_str() == util::YT_MUSIC_NAME)
|
.and_then(|p| p.0.first())
|
||||||
|
.map(util::is_ytm)
|
||||||
.unwrap_or(true);
|
.unwrap_or(true);
|
||||||
let channel = subtitle_p2.and_then(|p| {
|
let channel = subtitle_p2.and_then(|p| {
|
||||||
p.0.into_iter().find_map(|c| ChannelId::try_from(c).ok())
|
p.0.into_iter().find_map(|c| ChannelId::try_from(c).ok())
|
||||||
|
|
@ -1007,7 +1009,8 @@ impl MusicListMapper {
|
||||||
MusicPageType::Playlist => {
|
MusicPageType::Playlist => {
|
||||||
let from_ytm = subtitle_p2
|
let from_ytm = subtitle_p2
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| p.first_str() == util::YT_MUSIC_NAME)
|
.and_then(|p| p.0.first())
|
||||||
|
.map(util::is_ytm)
|
||||||
.unwrap_or(true);
|
.unwrap_or(true);
|
||||||
let channel = subtitle_p2
|
let channel = subtitle_p2
|
||||||
.and_then(|p| p.0.into_iter().find_map(|c| ChannelId::try_from(c).ok()));
|
.and_then(|p| p.0.into_iter().find_map(|c| ChannelId::try_from(c).ok()));
|
||||||
|
|
|
||||||
|
|
@ -4233,18 +4233,21 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
||||||
},
|
},
|
||||||
comma_decimal: false,
|
comma_decimal: false,
|
||||||
number_tokens: ::phf::Map {
|
number_tokens: ::phf::Map {
|
||||||
key: 12913932095322966823,
|
key: 15467950696543387533,
|
||||||
disps: &[
|
disps: &[
|
||||||
(0, 1),
|
(2, 0),
|
||||||
(0, 0),
|
(2, 1),
|
||||||
],
|
],
|
||||||
entries: &[
|
entries: &[
|
||||||
("ବ\u{b3f}ଜଣ", 9),
|
|
||||||
("ହଟ\u{b3f}", 3),
|
|
||||||
("ନ\u{b3f}ଜଣ", 6),
|
("ନ\u{b3f}ଜଣ", 6),
|
||||||
("ହଜଣ", 3),
|
("ବ\u{b3f}", 9),
|
||||||
|
("ନ\u{b3f}", 6),
|
||||||
|
("ବ\u{b3f}ଜଣ", 9),
|
||||||
("ବ\u{b3f}ଟ\u{b3f}", 9),
|
("ବ\u{b3f}ଟ\u{b3f}", 9),
|
||||||
|
("ହଜଣ", 3),
|
||||||
("ନ\u{b3f}ଟ\u{b3f}", 6),
|
("ନ\u{b3f}ଟ\u{b3f}", 6),
|
||||||
|
("ହ", 3),
|
||||||
|
("ହଟ\u{b3f}", 3),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
album_types: ::phf::Map {
|
album_types: ::phf::Map {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use rand::Rng;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{error::Error, param::Language};
|
use crate::{error::Error, param::Language, serializer::text::TextComponent};
|
||||||
|
|
||||||
pub static VIDEO_ID_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[A-Za-z0-9_-]{11}$").unwrap());
|
pub static VIDEO_ID_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[A-Za-z0-9_-]{11}$").unwrap());
|
||||||
pub static CHANNEL_ID_REGEX: Lazy<Regex> =
|
pub static CHANNEL_ID_REGEX: Lazy<Regex> =
|
||||||
|
|
@ -34,8 +34,6 @@ pub static VANITY_PATH_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||||
|
|
||||||
/// Separator string for YouTube Music subtitles
|
/// Separator string for YouTube Music subtitles
|
||||||
pub const DOT_SEPARATOR: &str = " • ";
|
pub const DOT_SEPARATOR: &str = " • ";
|
||||||
/// YouTube Music name (author of official playlists)
|
|
||||||
pub const YT_MUSIC_NAME: &str = "YouTube Music";
|
|
||||||
pub const VARIOUS_ARTISTS: &str = "Various Artists";
|
pub const VARIOUS_ARTISTS: &str = "Various Artists";
|
||||||
pub const PLAYLIST_ID_ALBUM_PREFIX: &str = "OLAK";
|
pub const PLAYLIST_ID_ALBUM_PREFIX: &str = "OLAK";
|
||||||
|
|
||||||
|
|
@ -269,6 +267,16 @@ impl<T> TryRemove<T> for Vec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if a channel name equals "YouTube Music"
|
||||||
|
/// (the author of original YouTube music playlists)
|
||||||
|
pub(crate) fn is_ytm(text: &TextComponent) -> bool {
|
||||||
|
if let TextComponent::Text { text } = text {
|
||||||
|
text.starts_with("YouTube")
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if a language should be parsed by character
|
/// Check if a language should be parsed by character
|
||||||
pub fn lang_by_char(lang: Language) -> bool {
|
pub fn lang_by_char(lang: Language) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
|
|
|
||||||
|
|
@ -2530,7 +2530,10 @@
|
||||||
"ବିଜଣ": 9,
|
"ବିଜଣ": 9,
|
||||||
"ବିଟି": 9,
|
"ବିଟି": 9,
|
||||||
"ହଜଣ": 3,
|
"ହଜଣ": 3,
|
||||||
"ହଟି": 3
|
"ହଟି": 3,
|
||||||
|
"ହ": 3,
|
||||||
|
"ନି": 6,
|
||||||
|
"ବି": 9
|
||||||
},
|
},
|
||||||
"album_types": {
|
"album_types": {
|
||||||
"ep": "Ep",
|
"ep": "Ep",
|
||||||
|
|
|
||||||
|
|
@ -1242,7 +1242,6 @@ fn music_playlist(
|
||||||
let playlist = tokio_test::block_on(rp.query().music_playlist(id)).unwrap();
|
let playlist = tokio_test::block_on(rp.query().music_playlist(id)).unwrap();
|
||||||
|
|
||||||
assert_eq!(playlist.id, id);
|
assert_eq!(playlist.id, id);
|
||||||
assert_eq!(playlist.name, name);
|
|
||||||
assert!(!playlist.tracks.is_empty());
|
assert!(!playlist.tracks.is_empty());
|
||||||
assert_eq!(!playlist.tracks.is_exhausted(), is_long);
|
assert_eq!(!playlist.tracks.is_exhausted(), is_long);
|
||||||
assert_gte(
|
assert_gte(
|
||||||
|
|
@ -1251,6 +1250,7 @@ fn music_playlist(
|
||||||
"track count",
|
"track count",
|
||||||
);
|
);
|
||||||
if unlocalized {
|
if unlocalized {
|
||||||
|
assert_eq!(playlist.name, name);
|
||||||
assert_eq!(playlist.description, description);
|
assert_eq!(playlist.description, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1600,8 +1600,6 @@ fn music_search_videos(rp: RustyPipe, unlocalized: bool) {
|
||||||
assert_next(res.items, rp.query(), 15, 2);
|
assert_next(res.items, rp.query(), 15, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This podcast was removed from YouTube Music and I could not find another one
|
|
||||||
/*
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn music_search_episode() {
|
async fn music_search_episode() {
|
||||||
let rp = RustyPipe::builder().strict().build();
|
let rp = RustyPipe::builder().strict().build();
|
||||||
|
|
@ -1623,7 +1621,7 @@ async fn music_search_episode() {
|
||||||
"Blond - Da muss man dabei gewesen sein: Das Hörspiel - Fall #1"
|
"Blond - Da muss man dabei gewesen sein: Das Hörspiel - Fall #1"
|
||||||
);
|
);
|
||||||
assert!(!track.cover.is_empty(), "got no cover");
|
assert!(!track.cover.is_empty(), "got no cover");
|
||||||
}*/
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case::single(
|
#[case::single(
|
||||||
|
|
@ -1687,7 +1685,7 @@ fn music_search_albums(
|
||||||
|
|
||||||
assert_eq!(res.corrected_query, None);
|
assert_eq!(res.corrected_query, None);
|
||||||
|
|
||||||
if more {
|
if more && unlocalized {
|
||||||
assert_next(res.items, rp.query(), 15, 1);
|
assert_next(res.items, rp.query(), 15, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue