fix: A/B test 21: music album recommendations
This commit is contained in:
parent
544782f8de
commit
6737512f5f
13 changed files with 8680 additions and 113 deletions
|
|
@ -40,13 +40,11 @@ pub enum ABTest {
|
|||
MusicPlaylistFacepile = 18,
|
||||
MusicAlbumGroupsReordered = 19,
|
||||
MusicContinuationItemRenderer = 20,
|
||||
AlbumRecommends = 21,
|
||||
}
|
||||
|
||||
/// List of active A/B tests that are run when none is manually specified
|
||||
const TESTS_TO_RUN: &[ABTest] = &[
|
||||
ABTest::MusicAlbumGroupsReordered,
|
||||
ABTest::MusicContinuationItemRenderer,
|
||||
];
|
||||
const TESTS_TO_RUN: &[ABTest] = &[ABTest::MusicAlbumGroupsReordered, ABTest::AlbumRecommends];
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ABTestRes {
|
||||
|
|
@ -121,6 +119,7 @@ pub async fn run_test(
|
|||
ABTest::MusicContinuationItemRenderer => {
|
||||
music_continuation_item_renderer(&query).await
|
||||
}
|
||||
ABTest::AlbumRecommends => album_recommends(&query).await,
|
||||
}
|
||||
.unwrap();
|
||||
pb.inc(1);
|
||||
|
|
@ -443,3 +442,18 @@ pub async fn music_continuation_item_renderer(rp: &RustyPipeQuery) -> Result<boo
|
|||
.await?;
|
||||
Ok(res.contains("\"continuationItemRenderer\""))
|
||||
}
|
||||
|
||||
pub async fn album_recommends(rp: &RustyPipeQuery) -> Result<bool> {
|
||||
let id = "MPREb_u1I69lSAe5v";
|
||||
let res = rp
|
||||
.raw(
|
||||
ClientType::DesktopMusic,
|
||||
"browse",
|
||||
&QBrowse {
|
||||
browse_id: id,
|
||||
params: None,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
Ok(res.contains("\"musicCarouselShelfRenderer\""))
|
||||
}
|
||||
|
|
|
|||
130
codegen/src/collect_album_versions_titles.rs
Normal file
130
codegen/src/collect_album_versions_titles.rs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
use std::{collections::BTreeMap, fs::File, io::BufReader};
|
||||
|
||||
use path_macro::path;
|
||||
use rustypipe::{
|
||||
client::{ClientType, RustyPipe},
|
||||
param::{Language, LANGUAGES},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_with::rust::deserialize_ignore_any;
|
||||
|
||||
use crate::{
|
||||
model::{QBrowse, SectionList, TextRuns},
|
||||
util::{self, DICT_DIR},
|
||||
};
|
||||
|
||||
pub async fn collect_album_versions_titles() {
|
||||
let json_path = path!(*DICT_DIR / "other_versions_titles.json");
|
||||
let mut res = BTreeMap::new();
|
||||
|
||||
let rp = RustyPipe::new();
|
||||
|
||||
for lang in LANGUAGES {
|
||||
let query = QBrowse {
|
||||
browse_id: "MPREb_nlBWQROfvjo",
|
||||
params: None,
|
||||
};
|
||||
let raw_resp = rp
|
||||
.query()
|
||||
.lang(lang)
|
||||
.raw(ClientType::DesktopMusic, "browse", &query)
|
||||
.await
|
||||
.unwrap();
|
||||
let data = serde_json::from_str::<AlbumData>(&raw_resp).unwrap();
|
||||
let title = data
|
||||
.contents
|
||||
.two_column_browse_results_renderer
|
||||
.secondary_contents
|
||||
.section_list_renderer
|
||||
.contents
|
||||
.into_iter()
|
||||
.find_map(|x| match x {
|
||||
ItemSection::MusicCarouselShelfRenderer(music_carousel_shelf) => {
|
||||
Some(music_carousel_shelf)
|
||||
}
|
||||
ItemSection::None => None,
|
||||
})
|
||||
.expect("other versions")
|
||||
.header
|
||||
.expect("header")
|
||||
.music_carousel_shelf_basic_header_renderer
|
||||
.title
|
||||
.runs
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap()
|
||||
.text;
|
||||
println!("{lang}: {title}");
|
||||
res.insert(lang, title);
|
||||
}
|
||||
|
||||
let file = File::create(json_path).unwrap();
|
||||
serde_json::to_writer_pretty(file, &res).unwrap();
|
||||
}
|
||||
|
||||
pub fn write_samples_to_dict() {
|
||||
let json_path = path!(*DICT_DIR / "other_versions_titles.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
let collected: BTreeMap<Language, String> =
|
||||
serde_json::from_reader(BufReader::new(json_file)).unwrap();
|
||||
let mut dict = util::read_dict();
|
||||
let langs = dict.keys().copied().collect::<Vec<_>>();
|
||||
|
||||
for lang in langs {
|
||||
let dict_entry = dict.entry(lang).or_default();
|
||||
|
||||
let e = collected.get(&lang).unwrap();
|
||||
assert_eq!(e, e.trim());
|
||||
dict_entry.album_versions_title = e.to_owned();
|
||||
|
||||
for lang in &dict_entry.equivalent {
|
||||
let ee = collected.get(lang).unwrap();
|
||||
if ee != e {
|
||||
panic!("equivalent lang conflict, lang: {lang}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
util::write_dict(dict);
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct AlbumData {
|
||||
contents: AlbumDataContents,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct AlbumDataContents {
|
||||
two_column_browse_results_renderer: X1,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct X1 {
|
||||
secondary_contents: SectionList<ItemSection>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum ItemSection {
|
||||
MusicCarouselShelfRenderer(MusicCarouselShelf),
|
||||
#[serde(other, deserialize_with = "deserialize_ignore_any")]
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct MusicCarouselShelf {
|
||||
header: Option<MusicCarouselShelfHeader>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct MusicCarouselShelfHeader {
|
||||
music_carousel_shelf_basic_header_renderer: MusicCarouselShelfHeaderRenderer,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct MusicCarouselShelfHeaderRenderer {
|
||||
title: TextRuns,
|
||||
}
|
||||
|
|
@ -90,6 +90,8 @@ pub(crate) struct Entry {
|
|||
pub chan_prefix: &'static str,
|
||||
/// Channel name suffix on playlist pages
|
||||
pub chan_suffix: &'static str,
|
||||
/// "Other versions" title on album pages
|
||||
pub album_versions_title: &'static str,
|
||||
}
|
||||
"#;
|
||||
|
||||
|
|
@ -178,8 +180,8 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
.to_string()
|
||||
.replace('\n', "\n ");
|
||||
|
||||
write!(code_timeago_tokens, "{} => Entry {{\n timeago_tokens: {},\n month_before_day: {:?},\n months: {},\n timeago_nd_tokens: {},\n comma_decimal: {:?},\n number_tokens: {},\n number_nd_tokens: {},\n album_types: {},\n chan_prefix: {:?},\n chan_suffix: {:?},\n }},\n ",
|
||||
selector, code_ta_tokens, entry.month_before_day, code_months, code_ta_nd_tokens, entry.comma_decimal, code_number_tokens, code_number_nd_tokens, code_album_types, entry.chan_prefix, entry.chan_suffix).unwrap();
|
||||
write!(code_timeago_tokens, "{} => Entry {{\n timeago_tokens: {},\n month_before_day: {:?},\n months: {},\n timeago_nd_tokens: {},\n comma_decimal: {:?},\n number_tokens: {},\n number_nd_tokens: {},\n album_types: {},\n chan_prefix: {:?},\n chan_suffix: {:?},\n album_versions_title: {:?},\n }},\n ",
|
||||
selector, code_ta_tokens, entry.month_before_day, code_months, code_ta_nd_tokens, entry.comma_decimal, code_number_tokens, code_number_nd_tokens, code_album_types, entry.chan_prefix, entry.chan_suffix, entry.album_versions_title).unwrap();
|
||||
}
|
||||
|
||||
code_timeago_tokens = code_timeago_tokens.trim_end().to_owned() + "\n }\n}\n";
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
mod abtest;
|
||||
mod collect_album_types;
|
||||
mod collect_album_versions_titles;
|
||||
mod collect_chan_prefixes;
|
||||
mod collect_history_dates;
|
||||
mod collect_large_numbers;
|
||||
|
|
@ -34,12 +35,14 @@ enum Commands {
|
|||
CollectHistoryDates,
|
||||
CollectMusicHistoryDates,
|
||||
CollectChanPrefixes,
|
||||
CollectAlbumVersionsTitles,
|
||||
ParsePlaylistDates,
|
||||
ParseHistoryDates,
|
||||
ParseLargeNumbers,
|
||||
ParseAlbumTypes,
|
||||
ParseVideoDurations,
|
||||
ParseChanPrefixes,
|
||||
ParseAlbumVersionsTitles,
|
||||
GenLocales,
|
||||
GenDict,
|
||||
DownloadTestfiles,
|
||||
|
|
@ -58,28 +61,25 @@ async fn main() {
|
|||
|
||||
match cli.command {
|
||||
Commands::CollectPlaylistDates => {
|
||||
collect_playlist_dates::collect_dates(cli.concurrency).await;
|
||||
collect_playlist_dates::collect_dates(cli.concurrency).await
|
||||
}
|
||||
Commands::CollectLargeNumbers => {
|
||||
collect_large_numbers::collect_large_numbers(cli.concurrency).await;
|
||||
collect_large_numbers::collect_large_numbers(cli.concurrency).await
|
||||
}
|
||||
Commands::CollectAlbumTypes => {
|
||||
collect_album_types::collect_album_types(cli.concurrency).await;
|
||||
collect_album_types::collect_album_types(cli.concurrency).await
|
||||
}
|
||||
Commands::CollectVideoDurations => {
|
||||
collect_video_durations::collect_video_durations(cli.concurrency).await;
|
||||
collect_video_durations::collect_video_durations(cli.concurrency).await
|
||||
}
|
||||
Commands::CollectVideoDates => {
|
||||
collect_video_dates::collect_video_dates(cli.concurrency).await;
|
||||
collect_video_dates::collect_video_dates(cli.concurrency).await
|
||||
}
|
||||
Commands::CollectHistoryDates => {
|
||||
collect_history_dates::collect_dates().await;
|
||||
}
|
||||
Commands::CollectMusicHistoryDates => {
|
||||
collect_history_dates::collect_dates_music().await;
|
||||
}
|
||||
Commands::CollectChanPrefixes => {
|
||||
collect_chan_prefixes::collect_chan_prefixes().await;
|
||||
Commands::CollectHistoryDates => collect_history_dates::collect_dates().await,
|
||||
Commands::CollectMusicHistoryDates => collect_history_dates::collect_dates_music().await,
|
||||
Commands::CollectChanPrefixes => collect_chan_prefixes::collect_chan_prefixes().await,
|
||||
Commands::CollectAlbumVersionsTitles => {
|
||||
collect_album_versions_titles::collect_album_versions_titles().await
|
||||
}
|
||||
Commands::ParsePlaylistDates => collect_playlist_dates::write_samples_to_dict(),
|
||||
Commands::ParseHistoryDates => collect_history_dates::write_samples_to_dict(),
|
||||
|
|
@ -87,9 +87,10 @@ async fn main() {
|
|||
Commands::ParseAlbumTypes => collect_album_types::write_samples_to_dict(),
|
||||
Commands::ParseVideoDurations => collect_video_durations::parse_video_durations(),
|
||||
Commands::ParseChanPrefixes => collect_chan_prefixes::write_samples_to_dict(),
|
||||
Commands::GenLocales => {
|
||||
gen_locales::generate_locales().await;
|
||||
Commands::ParseAlbumVersionsTitles => {
|
||||
collect_album_versions_titles::write_samples_to_dict()
|
||||
}
|
||||
Commands::GenLocales => gen_locales::generate_locales().await,
|
||||
Commands::GenDict => gen_dictionary::generate_dictionary(),
|
||||
Commands::DownloadTestfiles => download_testfiles::download_testfiles().await,
|
||||
Commands::AbTest { id, n } => {
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ pub struct DictEntry {
|
|||
pub chan_prefix: String,
|
||||
/// Channel name suffix on playlist pages
|
||||
pub chan_suffix: String,
|
||||
/// "Other versions" title on album pages
|
||||
pub album_versions_title: String,
|
||||
}
|
||||
|
||||
/// Parsed TimeAgo string, contains amount and time unit.
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
When YouTube introduces a new feature, it does so gradually. When a user creates a new
|
||||
session, YouTube decided randomly which new features should be enabled.
|
||||
|
||||
YouTube sessions are identified by the visitor data ID. This cookie is sent with
|
||||
every API request using the `context.client.visitor_data` JSON parameter. It is also
|
||||
returned in the `responseContext.visitorData` response parameter and stored as the
|
||||
`__SECURE-YEC` cookie.
|
||||
YouTube sessions are identified by the visitor data ID. This cookie is sent with every
|
||||
API request using the `context.client.visitor_data` JSON parameter. It is also returned
|
||||
in the `responseContext.visitorData` response parameter and stored as the `__SECURE-YEC`
|
||||
cookie.
|
||||
|
||||
By sending the same visitor data ID, A/B tests can be reproduced, which is important
|
||||
for testing alternative YouTube clients.
|
||||
By sending the same visitor data ID, A/B tests can be reproduced, which is important for
|
||||
testing alternative YouTube clients.
|
||||
|
||||
This page lists all A/B tests that were encountered while maintaining the RustyPipe
|
||||
client.
|
||||
|
|
@ -1042,7 +1042,7 @@ omitted for albums in their group, while singles and EPs have a label with their
|
|||
- **Encountered on:** 25.01.2025
|
||||
- **Impact:** 🟢 Low
|
||||
- **Endpoint:** browse (YTM)
|
||||
- **Status:** Common (4%)
|
||||
- **Status:** Stabilized
|
||||
|
||||
YouTube Music now uses a `continuationItemRenderer` for music playlists instead of
|
||||
putting the continuations in a separate attribute of the MusicShelf.
|
||||
|
|
@ -1052,3 +1052,18 @@ items.
|
|||
|
||||
YouTube Music now also sends a random 16-character string as a `clientScreenNonce` in
|
||||
the request context. This is not mandatory though.
|
||||
|
||||
## [21] Music album recommendations
|
||||
|
||||
- **Encountered on:** 26.02.2025
|
||||
- **Impact:** 🟢 Low
|
||||
- **Endpoint:** browse (YTM)
|
||||
- **Status:** Common (15%)
|
||||
|
||||

|
||||
|
||||
YouTube Music has added "Recommended" and "More from \<Artist\>" carousels to album
|
||||
pages. The difficulty is distinguishing them reliably for parsing the album variants.
|
||||
|
||||
The current solution is adding the "Other versions" title in all languages to the
|
||||
dictionary and comparing it.
|
||||
|
|
|
|||
BIN
notes/_img/ab_21.png
Normal file
BIN
notes/_img/ab_21.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 290 KiB |
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
AlbumId, ChannelId, MusicAlbum, MusicPlaylist, TrackItem, TrackType,
|
||||
},
|
||||
serializer::{text::TextComponents, MapResult},
|
||||
util::{self, TryRemove, DOT_SEPARATOR},
|
||||
util::{self, dictionary, TryRemove, DOT_SEPARATOR},
|
||||
};
|
||||
|
||||
use self::response::url_endpoint::MusicPageType;
|
||||
|
|
@ -382,7 +382,18 @@ impl MapResponse<MusicAlbum> for response::MusicPlaylist {
|
|||
match section {
|
||||
response::music_item::ItemSection::MusicShelfRenderer(sh) => shelf = Some(sh),
|
||||
response::music_item::ItemSection::MusicCarouselShelfRenderer(sh) => {
|
||||
album_variants = Some(sh.contents);
|
||||
if sh
|
||||
.header
|
||||
.map(|h| {
|
||||
h.music_carousel_shelf_basic_header_renderer
|
||||
.title
|
||||
.first_str()
|
||||
== dictionary::entry(ctx.lang).album_versions_title
|
||||
})
|
||||
.unwrap_or_default()
|
||||
{
|
||||
album_variants = Some(sh.contents);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
|
@ -572,8 +583,8 @@ mod tests {
|
|||
#[case::single("single", "MPREb_bHfHGoy7vuv")]
|
||||
#[case::description("description", "MPREb_PiyfuVl6aYd")]
|
||||
#[case::unavailable("unavailable", "MPREb_AzuWg8qAVVl")]
|
||||
#[case::unavailable("unavailable", "MPREb_AzuWg8qAVVl")]
|
||||
#[case::two_columns("20240228_twoColumns", "MPREb_bHfHGoy7vuv")]
|
||||
#[case::recommends("20250225_recommends", "MPREb_u1I69lSAe5v")]
|
||||
fn map_music_album(#[case] name: &str, #[case] id: &str) {
|
||||
let json_path = path!(*TESTFILES / "music_playlist" / format!("album_{name}.json"));
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
---
|
||||
source: src/client/music_playlist.rs
|
||||
expression: map_res.c
|
||||
---
|
||||
MusicAlbum(
|
||||
id: "MPREb_u1I69lSAe5v",
|
||||
playlist_id: Some("OLAK5uy_lGP_zv0vJDUlecQDzugUJmjcF7pvyVNyY"),
|
||||
name: "Waldbrand",
|
||||
cover: [
|
||||
Thumbnail(
|
||||
url: "https://lh3.googleusercontent.com/IYxE8yTIpFUu0OayA5SaxFEn6zQ7T21hpkvI8CODY9NEH1XIhyoUhGohkZuaK-xSu22BC4wjp6srNjIW=w60-h60-l90-rj",
|
||||
width: 60,
|
||||
height: 60,
|
||||
),
|
||||
Thumbnail(
|
||||
url: "https://lh3.googleusercontent.com/IYxE8yTIpFUu0OayA5SaxFEn6zQ7T21hpkvI8CODY9NEH1XIhyoUhGohkZuaK-xSu22BC4wjp6srNjIW=w120-h120-l90-rj",
|
||||
width: 120,
|
||||
height: 120,
|
||||
),
|
||||
Thumbnail(
|
||||
url: "https://lh3.googleusercontent.com/IYxE8yTIpFUu0OayA5SaxFEn6zQ7T21hpkvI8CODY9NEH1XIhyoUhGohkZuaK-xSu22BC4wjp6srNjIW=w226-h226-l90-rj",
|
||||
width: 226,
|
||||
height: 226,
|
||||
),
|
||||
Thumbnail(
|
||||
url: "https://lh3.googleusercontent.com/IYxE8yTIpFUu0OayA5SaxFEn6zQ7T21hpkvI8CODY9NEH1XIhyoUhGohkZuaK-xSu22BC4wjp6srNjIW=w544-h544-l90-rj",
|
||||
width: 544,
|
||||
height: 544,
|
||||
),
|
||||
],
|
||||
artists: [
|
||||
ArtistId(
|
||||
id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
name: "Madeline Juno",
|
||||
),
|
||||
],
|
||||
artist_id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
description: None,
|
||||
album_type: ep,
|
||||
year: Some(2016),
|
||||
by_va: false,
|
||||
track_count: 5,
|
||||
tracks: [
|
||||
TrackItem(
|
||||
id: "aGd3VKSOTxY",
|
||||
name: "Ich wache auf",
|
||||
duration: Some(222),
|
||||
cover: [],
|
||||
artists: [
|
||||
ArtistId(
|
||||
id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
name: "Madeline Juno",
|
||||
),
|
||||
],
|
||||
artist_id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
album: Some(AlbumId(
|
||||
id: "MPREb_u1I69lSAe5v",
|
||||
name: "Waldbrand",
|
||||
)),
|
||||
view_count: Some(208000),
|
||||
track_type: track,
|
||||
track_nr: Some(1),
|
||||
by_va: false,
|
||||
),
|
||||
TrackItem(
|
||||
id: "lhPOMUjV4rE",
|
||||
name: "Waldbrand",
|
||||
duration: Some(209),
|
||||
cover: [],
|
||||
artists: [
|
||||
ArtistId(
|
||||
id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
name: "Madeline Juno",
|
||||
),
|
||||
],
|
||||
artist_id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
album: Some(AlbumId(
|
||||
id: "MPREb_u1I69lSAe5v",
|
||||
name: "Waldbrand",
|
||||
)),
|
||||
view_count: Some(6000000),
|
||||
track_type: video,
|
||||
track_nr: Some(2),
|
||||
by_va: false,
|
||||
),
|
||||
TrackItem(
|
||||
id: "Bu26uFtpt58",
|
||||
name: "Verlernt",
|
||||
duration: Some(224),
|
||||
cover: [],
|
||||
artists: [
|
||||
ArtistId(
|
||||
id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
name: "Madeline Juno",
|
||||
),
|
||||
],
|
||||
artist_id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
album: Some(AlbumId(
|
||||
id: "MPREb_u1I69lSAe5v",
|
||||
name: "Waldbrand",
|
||||
)),
|
||||
view_count: Some(418000),
|
||||
track_type: track,
|
||||
track_nr: Some(3),
|
||||
by_va: false,
|
||||
),
|
||||
TrackItem(
|
||||
id: "RgwNqqiVqdY",
|
||||
name: "In Farbe",
|
||||
duration: Some(222),
|
||||
cover: [],
|
||||
artists: [
|
||||
ArtistId(
|
||||
id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
name: "Madeline Juno",
|
||||
),
|
||||
],
|
||||
artist_id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
album: Some(AlbumId(
|
||||
id: "MPREb_u1I69lSAe5v",
|
||||
name: "Waldbrand",
|
||||
)),
|
||||
view_count: Some(127000),
|
||||
track_type: track,
|
||||
track_nr: Some(4),
|
||||
by_va: false,
|
||||
),
|
||||
TrackItem(
|
||||
id: "2TuOh30XbCI",
|
||||
name: "Stadt im Hinterland",
|
||||
duration: Some(198),
|
||||
cover: [],
|
||||
artists: [
|
||||
ArtistId(
|
||||
id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
name: "Madeline Juno",
|
||||
),
|
||||
],
|
||||
artist_id: Some("UCpJyCbFbdTrx0M90HCNBHFQ"),
|
||||
album: Some(AlbumId(
|
||||
id: "MPREb_u1I69lSAe5v",
|
||||
name: "Waldbrand",
|
||||
)),
|
||||
view_count: Some(79000),
|
||||
track_type: track,
|
||||
track_nr: Some(5),
|
||||
by_va: false,
|
||||
),
|
||||
],
|
||||
variants: [],
|
||||
)
|
||||
|
|
@ -53,6 +53,8 @@ pub(crate) struct Entry {
|
|||
pub chan_prefix: &'static str,
|
||||
/// Channel name suffix on playlist pages
|
||||
pub chan_suffix: &'static str,
|
||||
/// "Other versions" title on album pages
|
||||
pub album_versions_title: &'static str,
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
|
@ -183,6 +185,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "deur",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Ander weergawes",
|
||||
},
|
||||
Language::Am => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -310,6 +313,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "በ",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "ሌሎች ስሪቶች",
|
||||
},
|
||||
Language::Ar => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -445,6 +449,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "بواسطة",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "إصدارات أخرى",
|
||||
},
|
||||
Language::As => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -567,6 +572,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "ৰ দ\u{9cd}ব\u{9be}ৰ\u{9be}",
|
||||
album_versions_title: "অন\u{9cd}য সংস\u{9cd}কৰণ",
|
||||
},
|
||||
Language::Az => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -682,6 +688,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "by",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Digər versiyalar",
|
||||
},
|
||||
Language::Be => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -829,6 +836,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "ад",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Іншыя версіі",
|
||||
},
|
||||
Language::Bg => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -945,6 +953,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "от",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Други версии",
|
||||
},
|
||||
Language::Bn => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1062,6 +1071,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: ",",
|
||||
chan_suffix: "দ\u{9cd}ব\u{9be}র\u{9be}",
|
||||
album_versions_title: "অন\u{9cd}য সংস\u{9cd}করণগ\u{9c1}লি",
|
||||
},
|
||||
Language::Bs => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1201,6 +1211,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "od",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Druge verzije",
|
||||
},
|
||||
Language::Ca => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1325,6 +1336,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "de:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Altres versions",
|
||||
},
|
||||
Language::Cs => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1455,6 +1467,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "autor:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Jiné verze",
|
||||
},
|
||||
Language::Da => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1579,6 +1592,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "af",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Andre versioner",
|
||||
},
|
||||
Language::De => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1700,6 +1714,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "von",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Weitere Versionen",
|
||||
},
|
||||
Language::El => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1830,6 +1845,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "από το χρήστη",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Άλλες εκτελέσεις",
|
||||
},
|
||||
Language::En | Language::EnGb | Language::EnIn => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -1971,6 +1987,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "by",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Other versions",
|
||||
},
|
||||
Language::Es => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2098,6 +2115,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "de",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Otras versiones",
|
||||
},
|
||||
Language::EsUs | Language::Es419 => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2226,6 +2244,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "de",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Otras versiones",
|
||||
},
|
||||
Language::Et => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2351,6 +2370,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "kanalilt",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Teised versioonid",
|
||||
},
|
||||
Language::Eu => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2467,6 +2487,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "egilea:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Beste bertsio batzuk",
|
||||
},
|
||||
Language::Fa => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2574,6 +2595,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "توسط",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "نسخه\u{200c}های دیگر",
|
||||
},
|
||||
Language::Fi => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2693,6 +2715,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "tekijä:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Muut versiot",
|
||||
},
|
||||
Language::Fil => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2810,6 +2833,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "ni/ng",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Iba pang bersyon",
|
||||
},
|
||||
Language::Fr | Language::FrCa => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -2941,6 +2965,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "de",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Autres versions",
|
||||
},
|
||||
Language::Gl => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3065,6 +3090,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "de",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Outras versións",
|
||||
},
|
||||
Language::Gu => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3170,6 +3196,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "દ\u{acd}વારા",
|
||||
album_versions_title: "અન\u{acd}ય વર\u{acd}ઝન",
|
||||
},
|
||||
Language::Hi => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3286,6 +3313,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "क\u{947} ज\u{93c}रिए",
|
||||
album_versions_title: "अन\u{94d}य वर\u{94d}शन",
|
||||
},
|
||||
Language::Hr => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3425,6 +3453,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "omogućio kanal",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Druge verzije",
|
||||
},
|
||||
Language::Hu => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3554,6 +3583,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "csatornától",
|
||||
album_versions_title: "Más verziók",
|
||||
},
|
||||
Language::Hy => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3676,6 +3706,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "հեղինակ՝",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Այլ տարբերակներ",
|
||||
},
|
||||
Language::Id => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3794,6 +3825,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "oleh",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Versi lainnya",
|
||||
},
|
||||
Language::Is => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -3928,6 +3960,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "eftir",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Aðrar útgáfur",
|
||||
},
|
||||
Language::It => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4060,6 +4093,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "di",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Altre versioni",
|
||||
},
|
||||
Language::Iw => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4198,6 +4232,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "מאת",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "גרסאות אחרות",
|
||||
},
|
||||
Language::Ja => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4278,6 +4313,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "作成者:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "他のバージョン",
|
||||
},
|
||||
Language::Ka => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4400,6 +4436,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "-ის მიერ",
|
||||
album_versions_title: "სხვა ვერსიები",
|
||||
},
|
||||
Language::Kk => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4523,6 +4560,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "қосқан",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Басқа нұсқалары",
|
||||
},
|
||||
Language::Km => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4623,6 +4661,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "ដោយ",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "ប\u{17d2}រភេទផ\u{17d2}សេងៗ",
|
||||
},
|
||||
Language::Kn => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4749,6 +4788,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "ಚಾನಲ\u{ccd}\u{200c}ನ\u{cbf}ಂದ",
|
||||
album_versions_title: "ಇತರ ಆವೃತ\u{ccd}ತ\u{cbf}ಗಳು",
|
||||
},
|
||||
Language::Ko => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4832,6 +4872,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "게시자:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "다른 버전",
|
||||
},
|
||||
Language::Ky => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -4950,6 +4991,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "каналы аркылуу",
|
||||
album_versions_title: "Башка версиялар",
|
||||
},
|
||||
Language::Lo => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5076,6 +5118,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "ໂດຍ",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "ເວ\u{eb5}ຊ\u{eb1}ນອ\u{eb7}\u{ec8}ນໆ",
|
||||
},
|
||||
Language::Lt => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5210,6 +5253,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "pridėjo",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Kitos versijos",
|
||||
},
|
||||
Language::Lv => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5344,6 +5388,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "autors:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Citas versijas",
|
||||
},
|
||||
Language::Mk => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5471,6 +5516,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "од",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Други верзии",
|
||||
},
|
||||
Language::Ml => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5585,6 +5631,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "മ\u{d41}ഖേന",
|
||||
album_versions_title: "മറ\u{d4d}റ\u{d4d} പതിപ\u{d4d}പ\u{d41}കൾ",
|
||||
},
|
||||
Language::Mn => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5689,6 +5736,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "сувгийн нэр:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Бусад хувилбар",
|
||||
},
|
||||
Language::Mr => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5813,6 +5861,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "द\u{94d}वार\u{947}",
|
||||
album_versions_title: "इतर आव\u{943}त\u{94d}त\u{94d}या",
|
||||
},
|
||||
Language::Ms => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -5926,6 +5975,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "oleh",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Versi lain",
|
||||
},
|
||||
Language::My => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6046,6 +6096,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "မ\u{103e}",
|
||||
album_versions_title: "အခြား ဗားရ\u{103e}င\u{103a}းများ",
|
||||
},
|
||||
Language::Ne => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6149,6 +6200,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "द\u{94d}वारा",
|
||||
album_versions_title: "अन\u{94d}य स\u{902}स\u{94d}करणहर\u{942}",
|
||||
},
|
||||
Language::Nl => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6271,6 +6323,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "door",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Andere versies",
|
||||
},
|
||||
Language::No => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6399,6 +6452,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "av",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Andre versjoner",
|
||||
},
|
||||
Language::Or => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6514,6 +6568,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "ଦ\u{b4d}ଵ\u{b3e}ର\u{b3e}",
|
||||
album_versions_title: "ଅନ\u{b4d}ୟ ସଂସ\u{b4d}କରଣଗ\u{b41}ଡ\u{b3c}\u{b3f}କ",
|
||||
},
|
||||
Language::Pa => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6629,6 +6684,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "ਵ\u{a71}ਲ\u{a4b}\u{a02}",
|
||||
album_versions_title: "ਹ\u{a4b}ਰ ਵਰਜਨ",
|
||||
},
|
||||
Language::Pl => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6774,6 +6830,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "autor:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Inne wersje",
|
||||
},
|
||||
Language::Pt => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -6903,6 +6960,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "por",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Outras versões",
|
||||
},
|
||||
Language::PtPt => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7015,6 +7073,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "de",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Outras versões",
|
||||
},
|
||||
Language::Ro => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7143,6 +7202,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "de",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Alte versiuni",
|
||||
},
|
||||
Language::Ru => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7286,6 +7346,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Другие версии",
|
||||
},
|
||||
Language::Si => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7397,6 +7458,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "ව\u{dd2}ස\u{dd2}න\u{dca}",
|
||||
album_versions_title: "අනෙක\u{dd4}ත\u{dca} අන\u{dd4}ව\u{dcf}දයන\u{dca}",
|
||||
},
|
||||
Language::Sk => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7527,6 +7589,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "Autori:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Ďalšie verzie",
|
||||
},
|
||||
Language::Sl => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7676,6 +7739,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "kanal",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Druge različice",
|
||||
},
|
||||
Language::Sq => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7796,6 +7860,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "nga",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Versione të tjera",
|
||||
},
|
||||
Language::Sr => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -7926,6 +7991,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "са канала",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Друге верзије",
|
||||
},
|
||||
Language::SrLatn => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8056,6 +8122,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "sa kanala",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Druge verzije",
|
||||
},
|
||||
Language::Sv => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8178,6 +8245,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "från",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Andra versioner",
|
||||
},
|
||||
Language::Sw => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8291,6 +8359,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "kutoka",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Matoleo mengine",
|
||||
},
|
||||
Language::Ta => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8421,6 +8490,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "வழங\u{bcd}கியவர\u{bcd}:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "பிற பதிப\u{bcd}புகள\u{bcd}",
|
||||
},
|
||||
Language::Te => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8547,6 +8617,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "ఛ\u{c3e}న\u{c46}ల\u{c4d} ద\u{c4d}వ\u{c3e}ర\u{c3e}",
|
||||
album_versions_title: "ఇతర వ\u{c46}ర\u{c4d}షన\u{c4d}\u{200c}లు",
|
||||
},
|
||||
Language::Th => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8677,6 +8748,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "โดย",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "เวอร\u{e4c}ช\u{e31}นอ\u{e37}\u{e48}นๆ",
|
||||
},
|
||||
Language::Tr => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8797,6 +8869,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "",
|
||||
chan_suffix: "tarafından",
|
||||
album_versions_title: "Diğer versiyonlar",
|
||||
},
|
||||
Language::Uk => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -8945,6 +9018,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "власник:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Інші версії",
|
||||
},
|
||||
Language::Ur => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -9070,6 +9144,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "منجانب",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "دیگر ورژنز",
|
||||
},
|
||||
Language::Uz => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -9184,6 +9259,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "muallif:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Boshqa versiyalari",
|
||||
},
|
||||
Language::Vi => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -9265,6 +9341,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "của",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Các phiên bản khác",
|
||||
},
|
||||
Language::ZhCn => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -9362,6 +9439,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "创建者:",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "其他版本",
|
||||
},
|
||||
Language::ZhHk => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -9443,6 +9521,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "來自",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "其他版本",
|
||||
},
|
||||
Language::ZhTw => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -9523,6 +9602,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "由",
|
||||
chan_suffix: "建立",
|
||||
album_versions_title: "其他版本",
|
||||
},
|
||||
Language::Zu => Entry {
|
||||
timeago_tokens: ::phf::Map {
|
||||
|
|
@ -9658,6 +9738,7 @@ pub(crate) fn entry(lang: Language) -> Entry {
|
|||
},
|
||||
chan_prefix: "ka-",
|
||||
chan_suffix: "",
|
||||
album_versions_title: "Ezinye izinguqulo",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
85
testfiles/dict/other_versions_titles.json
Normal file
85
testfiles/dict/other_versions_titles.json
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
"af": "Ander weergawes",
|
||||
"am": "ሌሎች ስሪቶች",
|
||||
"ar": "إصدارات أخرى",
|
||||
"as": "অন্য সংস্কৰণ",
|
||||
"az": "Digər versiyalar",
|
||||
"be": "Іншыя версіі",
|
||||
"bg": "Други версии",
|
||||
"bn": "অন্য সংস্করণগুলি",
|
||||
"bs": "Druge verzije",
|
||||
"ca": "Altres versions",
|
||||
"cs": "Jiné verze",
|
||||
"da": "Andre versioner",
|
||||
"de": "Weitere Versionen",
|
||||
"el": "Άλλες εκτελέσεις",
|
||||
"en": "Other versions",
|
||||
"en-GB": "Other versions",
|
||||
"en-IN": "Other versions",
|
||||
"es": "Otras versiones",
|
||||
"es-419": "Otras versiones",
|
||||
"es-US": "Otras versiones",
|
||||
"et": "Teised versioonid",
|
||||
"eu": "Beste bertsio batzuk",
|
||||
"fa": "نسخههای دیگر",
|
||||
"fi": "Muut versiot",
|
||||
"fil": "Iba pang bersyon",
|
||||
"fr": "Autres versions",
|
||||
"fr-CA": "Autres versions",
|
||||
"gl": "Outras versións",
|
||||
"gu": "અન્ય વર્ઝન",
|
||||
"hi": "अन्य वर्शन",
|
||||
"hr": "Druge verzije",
|
||||
"hu": "Más verziók",
|
||||
"hy": "Այլ տարբերակներ",
|
||||
"id": "Versi lainnya",
|
||||
"is": "Aðrar útgáfur",
|
||||
"it": "Altre versioni",
|
||||
"iw": "גרסאות אחרות",
|
||||
"ja": "他のバージョン",
|
||||
"ka": "სხვა ვერსიები",
|
||||
"kk": "Басқа нұсқалары",
|
||||
"km": "ប្រភេទផ្សេងៗ",
|
||||
"kn": "ಇತರ ಆವೃತ್ತಿಗಳು",
|
||||
"ko": "다른 버전",
|
||||
"ky": "Башка версиялар",
|
||||
"lo": "ເວີຊັນອື່ນໆ",
|
||||
"lt": "Kitos versijos",
|
||||
"lv": "Citas versijas",
|
||||
"mk": "Други верзии",
|
||||
"ml": "മറ്റ് പതിപ്പുകൾ",
|
||||
"mn": "Бусад хувилбар",
|
||||
"mr": "इतर आवृत्त्या",
|
||||
"ms": "Versi lain",
|
||||
"my": "အခြား ဗားရှင်းများ",
|
||||
"ne": "अन्य संस्करणहरू",
|
||||
"nl": "Andere versies",
|
||||
"no": "Andre versjoner",
|
||||
"or": "ଅନ୍ୟ ସଂସ୍କରଣଗୁଡ଼ିକ",
|
||||
"pa": "ਹੋਰ ਵਰਜਨ",
|
||||
"pl": "Inne wersje",
|
||||
"pt": "Outras versões",
|
||||
"pt-PT": "Outras versões",
|
||||
"ro": "Alte versiuni",
|
||||
"ru": "Другие версии",
|
||||
"si": "අනෙකුත් අනුවාදයන්",
|
||||
"sk": "Ďalšie verzie",
|
||||
"sl": "Druge različice",
|
||||
"sq": "Versione të tjera",
|
||||
"sr": "Друге верзије",
|
||||
"sr-Latn": "Druge verzije",
|
||||
"sv": "Andra versioner",
|
||||
"sw": "Matoleo mengine",
|
||||
"ta": "பிற பதிப்புகள்",
|
||||
"te": "ఇతర వెర్షన్లు",
|
||||
"th": "เวอร์ชันอื่นๆ",
|
||||
"tr": "Diğer versiyonlar",
|
||||
"uk": "Інші версії",
|
||||
"ur": "دیگر ورژنز",
|
||||
"uz": "Boshqa versiyalari",
|
||||
"vi": "Các phiên bản khác",
|
||||
"zh-CN": "其他版本",
|
||||
"zh-HK": "其他版本",
|
||||
"zh-TW": "其他版本",
|
||||
"zu": "Ezinye izinguqulo"
|
||||
}
|
||||
7989
testfiles/music_playlist/album_20250225_recommends.json
Normal file
7989
testfiles/music_playlist/album_20250225_recommends.json
Normal file
File diff suppressed because it is too large
Load diff
Reference in a new issue