Sort by <field>_sort from tags if it is available #107
@ -44,6 +44,8 @@ enum ArtistCommand {
|
|||||||
Add(ArtistValue),
|
Add(ArtistValue),
|
||||||
#[structopt(about = "Remove an artist from the collection")]
|
#[structopt(about = "Remove an artist from the collection")]
|
||||||
Remove(ArtistValue),
|
Remove(ArtistValue),
|
||||||
|
#[structopt(about = "Edit the artist's sort name")]
|
||||||
|
Sort(SortCommand),
|
||||||
#[structopt(name = "musicbrainz", about = "Edit the MusicBrainz URL of an artist")]
|
#[structopt(name = "musicbrainz", about = "Edit the MusicBrainz URL of an artist")]
|
||||||
MusicBrainz(UrlCommand<SingleUrlValue>),
|
MusicBrainz(UrlCommand<SingleUrlValue>),
|
||||||
#[structopt(
|
#[structopt(
|
||||||
@ -57,12 +59,28 @@ enum ArtistCommand {
|
|||||||
Qobuz(UrlCommand<SingleUrlValue>),
|
Qobuz(UrlCommand<SingleUrlValue>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(StructOpt, Debug)]
|
||||||
|
enum SortCommand {
|
||||||
|
#[structopt(help = "Set the provided name as the artist's sort name")]
|
||||||
|
Set(ArtistSortValue),
|
||||||
|
#[structopt(help = "Clear the artist's sort name")]
|
||||||
|
Clear(ArtistValue),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(StructOpt, Debug)]
|
#[derive(StructOpt, Debug)]
|
||||||
struct ArtistValue {
|
struct ArtistValue {
|
||||||
#[structopt(help = "The name of the artist")]
|
#[structopt(help = "The name of the artist")]
|
||||||
artist: String,
|
artist: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(StructOpt, Debug)]
|
||||||
|
struct ArtistSortValue {
|
||||||
|
#[structopt(help = "The name of the artist")]
|
||||||
|
artist: String,
|
||||||
|
#[structopt(help = "The sort name of the artist")]
|
||||||
|
sort: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(StructOpt, Debug)]
|
#[derive(StructOpt, Debug)]
|
||||||
enum UrlCommand<T: StructOpt> {
|
enum UrlCommand<T: StructOpt> {
|
||||||
#[structopt(about = "Add the provided URL(s) without overwriting existing values")]
|
#[structopt(about = "Add the provided URL(s) without overwriting existing values")]
|
||||||
@ -137,6 +155,9 @@ impl ArtistCommand {
|
|||||||
ArtistCommand::Remove(artist_value) => {
|
ArtistCommand::Remove(artist_value) => {
|
||||||
music_hoard.remove_artist(ArtistId::new(artist_value.artist));
|
music_hoard.remove_artist(ArtistId::new(artist_value.artist));
|
||||||
}
|
}
|
||||||
|
ArtistCommand::Sort(sort_command) => {
|
||||||
|
sort_command.handle(music_hoard);
|
||||||
|
}
|
||||||
ArtistCommand::MusicBrainz(url_command) => {
|
ArtistCommand::MusicBrainz(url_command) => {
|
||||||
single_url_command_dispatch!(url_command, music_hoard, musicbrainz)
|
single_url_command_dispatch!(url_command, music_hoard, musicbrainz)
|
||||||
}
|
}
|
||||||
@ -153,6 +174,22 @@ impl ArtistCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SortCommand {
|
||||||
|
fn handle(self, music_hoard: &mut MH) {
|
||||||
|
match self {
|
||||||
|
SortCommand::Set(artist_sort_value) => music_hoard
|
||||||
|
.set_artist_sort(
|
||||||
|
ArtistId::new(artist_sort_value.artist),
|
||||||
|
ArtistId::new(artist_sort_value.sort),
|
||||||
|
)
|
||||||
|
.expect("faild to set artist sort name"),
|
||||||
|
SortCommand::Clear(artist_value) => music_hoard
|
||||||
|
.clear_artist_sort(ArtistId::new(artist_value.artist))
|
||||||
|
.expect("failed to clear artist sort name"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let opt = Opt::from_args();
|
let opt = Opt::from_args();
|
||||||
|
|
||||||
|
@ -225,9 +225,7 @@ mod tests {
|
|||||||
fn save_errors() {
|
fn save_errors() {
|
||||||
let mut object = HashMap::<ArtistId, String>::new();
|
let mut object = HashMap::<ArtistId, String>::new();
|
||||||
object.insert(
|
object.insert(
|
||||||
ArtistId {
|
ArtistId::new(String::from("artist")),
|
||||||
name: String::from("artist"),
|
|
||||||
},
|
|
||||||
String::from("string"),
|
String::from("string"),
|
||||||
);
|
);
|
||||||
let serde_err = serde_json::to_string(&object);
|
let serde_err = serde_json::to_string(&object);
|
||||||
|
64
src/lib.rs
64
src/lib.rs
@ -380,6 +380,7 @@ impl Merge for ArtistProperties {
|
|||||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
pub struct Artist {
|
pub struct Artist {
|
||||||
pub id: ArtistId,
|
pub id: ArtistId,
|
||||||
|
pub sort: Option<ArtistId>,
|
||||||
pub properties: ArtistProperties,
|
pub properties: ArtistProperties,
|
||||||
pub albums: Vec<Album>,
|
pub albums: Vec<Album>,
|
||||||
}
|
}
|
||||||
@ -433,11 +434,33 @@ impl Artist {
|
|||||||
pub fn new<ID: Into<ArtistId>>(id: ID) -> Self {
|
pub fn new<ID: Into<ArtistId>>(id: ID) -> Self {
|
||||||
Artist {
|
Artist {
|
||||||
id: id.into(),
|
id: id.into(),
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties::default(),
|
properties: ArtistProperties::default(),
|
||||||
albums: vec![],
|
albums: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_with_sort<ID: Into<ArtistId>, SORT: Into<ArtistId>>(id: ID, sort: SORT) -> Self {
|
||||||
|
Artist {
|
||||||
|
id: id.into(),
|
||||||
|
sort: Some(sort.into()),
|
||||||
|
properties: ArtistProperties::default(),
|
||||||
|
albums: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_sort_key(&self) -> &ArtistId {
|
||||||
|
self.sort.as_ref().unwrap_or(&self.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_sort_key<SORT: Into<ArtistId>>(&mut self, sort: SORT) {
|
||||||
|
self.sort = Some(sort.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_sort_key(&mut self) {
|
||||||
|
_ = self.sort.take();
|
||||||
|
}
|
||||||
|
|
||||||
fn add_unique_url<S: AsRef<str>, T: for<'a> TryFrom<&'a str, Error = Error> + Eq + Display>(
|
fn add_unique_url<S: AsRef<str>, T: for<'a> TryFrom<&'a str, Error = Error> + Eq + Display>(
|
||||||
container: &mut Option<T>,
|
container: &mut Option<T>,
|
||||||
url: S,
|
url: S,
|
||||||
@ -552,7 +575,7 @@ impl PartialOrd for Artist {
|
|||||||
|
|
||||||
impl Ord for Artist {
|
impl Ord for Artist {
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
self.id.cmp(&other.id)
|
self.get_sort_key().cmp(other.get_sort_key())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,6 +846,21 @@ impl<LIB, DB> MusicHoard<LIB, DB> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_artist_sort<ID: AsRef<ArtistId>, SORT: Into<ArtistId>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: ID,
|
||||||
|
artist_sort: SORT,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.get_artist_or_err(artist_id.as_ref())?
|
||||||
|
.set_sort_key(artist_sort);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_artist_sort<ID: AsRef<ArtistId>>(&mut self, artist_id: ID) -> Result<(), Error> {
|
||||||
|
self.get_artist_or_err(artist_id.as_ref())?.clear_sort_key();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
music_hoard_unique_url_dispatch!(musicbrainz);
|
music_hoard_unique_url_dispatch!(musicbrainz);
|
||||||
|
|
||||||
music_hoard_multi_url_dispatch!(musicbutler);
|
music_hoard_multi_url_dispatch!(musicbutler);
|
||||||
@ -845,7 +883,7 @@ impl<LIB, DB> MusicHoard<LIB, DB> {
|
|||||||
MergeSorted::new(primary.into_iter(), secondary.into_iter()).collect()
|
MergeSorted::new(primary.into_iter(), secondary.into_iter()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn items_to_artists(items: Vec<Item>) -> Vec<Artist> {
|
fn items_to_artists(items: Vec<Item>) -> Result<Vec<Artist>, Error> {
|
||||||
let mut artists: Vec<Artist> = vec![];
|
let mut artists: Vec<Artist> = vec![];
|
||||||
let mut album_ids = HashMap::<ArtistId, HashSet<AlbumId>>::new();
|
let mut album_ids = HashMap::<ArtistId, HashSet<AlbumId>>::new();
|
||||||
|
|
||||||
@ -854,6 +892,8 @@ impl<LIB, DB> MusicHoard<LIB, DB> {
|
|||||||
name: item.album_artist,
|
name: item.album_artist,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let artist_sort = item.album_artist_sort.map(|s| ArtistId { name: s });
|
||||||
|
|
||||||
let album_id = AlbumId {
|
let album_id = AlbumId {
|
||||||
year: item.album_year,
|
year: item.album_year,
|
||||||
title: item.album_title,
|
title: item.album_title,
|
||||||
@ -886,6 +926,21 @@ impl<LIB, DB> MusicHoard<LIB, DB> {
|
|||||||
artists.last_mut().unwrap()
|
artists.last_mut().unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if artist.sort.is_some() {
|
||||||
|
if artist_sort.is_some() && (artist.sort != artist_sort) {
|
||||||
|
return Err(Error::CollectionError(format!(
|
||||||
|
"multiple album_artist_sort found for artist '{}': '{}' != '{}'",
|
||||||
|
artist.id,
|
||||||
|
artist.sort.as_ref().unwrap(),
|
||||||
|
artist_sort.as_ref().unwrap()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if artist_sort.is_some() {
|
||||||
|
artist.sort = artist_sort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if album_ids[&artist_id].contains(&album_id) {
|
if album_ids[&artist_id].contains(&album_id) {
|
||||||
// Assume results are in some order which means they will likely be grouped by
|
// Assume results are in some order which means they will likely be grouped by
|
||||||
// album. Therefore, we look from the back since the last inserted album is most
|
// album. Therefore, we look from the back since the last inserted album is most
|
||||||
@ -909,7 +964,7 @@ impl<LIB, DB> MusicHoard<LIB, DB> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
artists
|
Ok(artists)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_artist(&mut self, artist_id: &ArtistId) -> Option<&mut Artist> {
|
fn get_artist(&mut self, artist_id: &ArtistId) -> Option<&mut Artist> {
|
||||||
@ -927,7 +982,7 @@ impl<LIB: ILibrary, DB> MusicHoard<LIB, DB> {
|
|||||||
/// Rescan the library and merge with the in-memory collection.
|
/// Rescan the library and merge with the in-memory collection.
|
||||||
pub fn rescan_library(&mut self) -> Result<(), Error> {
|
pub fn rescan_library(&mut self) -> Result<(), Error> {
|
||||||
let items = self.library.list(&Query::new())?;
|
let items = self.library.list(&Query::new())?;
|
||||||
let mut library_collection = Self::items_to_artists(items);
|
let mut library_collection = Self::items_to_artists(items)?;
|
||||||
Self::sort(&mut library_collection);
|
Self::sort(&mut library_collection);
|
||||||
|
|
||||||
let collection = mem::take(&mut self.collection);
|
let collection = mem::take(&mut self.collection);
|
||||||
@ -1036,6 +1091,7 @@ mod tests {
|
|||||||
for track in album.tracks.iter() {
|
for track in album.tracks.iter() {
|
||||||
items.push(Item {
|
items.push(Item {
|
||||||
album_artist: artist.id.name.clone(),
|
album_artist: artist.id.name.clone(),
|
||||||
|
album_artist_sort: artist.sort.as_ref().map(|s| s.name.clone()),
|
||||||
album_year: album.id.year,
|
album_year: album.id.year,
|
||||||
album_title: album.id.title.clone(),
|
album_title: album.id.title.clone(),
|
||||||
track_number: track.id.number,
|
track_number: track.id.number,
|
||||||
|
@ -22,6 +22,8 @@ const LIST_FORMAT_ARG: &str = concat!(
|
|||||||
"--format=",
|
"--format=",
|
||||||
"$albumartist",
|
"$albumartist",
|
||||||
list_format_separator!(),
|
list_format_separator!(),
|
||||||
|
"$albumartist_sort",
|
||||||
|
list_format_separator!(),
|
||||||
"$year",
|
"$year",
|
||||||
list_format_separator!(),
|
list_format_separator!(),
|
||||||
"$album",
|
"$album",
|
||||||
@ -52,6 +54,7 @@ impl ToBeetsArg for Field {
|
|||||||
let negate = if include { "" } else { "^" };
|
let negate = if include { "" } else { "^" };
|
||||||
match self {
|
match self {
|
||||||
Field::AlbumArtist(ref s) => format!("{negate}albumartist:{s}"),
|
Field::AlbumArtist(ref s) => format!("{negate}albumartist:{s}"),
|
||||||
|
Field::AlbumArtistSort(ref s) => format!("{negate}albumartist_sort:{s}"),
|
||||||
Field::AlbumYear(ref u) => format!("{negate}year:{u}"),
|
Field::AlbumYear(ref u) => format!("{negate}year:{u}"),
|
||||||
Field::AlbumTitle(ref s) => format!("{negate}album:{s}"),
|
Field::AlbumTitle(ref s) => format!("{negate}album:{s}"),
|
||||||
Field::TrackNumber(ref u) => format!("{negate}track:{u}"),
|
Field::TrackNumber(ref u) => format!("{negate}track:{u}"),
|
||||||
@ -128,24 +131,30 @@ impl<BLE: IBeetsLibraryExecutor> ILibraryPrivate for BeetsLibrary<BLE> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let album_artist = split[0].to_string();
|
let album_artist = split[0].to_string();
|
||||||
let album_year = split[1].parse::<u32>()?;
|
let album_artist_sort = if !split[1].is_empty() {
|
||||||
let album_title = split[2].to_string();
|
Some(split[1].to_string())
|
||||||
let track_number = split[3].parse::<u32>()?;
|
} else {
|
||||||
let track_title = split[4].to_string();
|
None
|
||||||
let track_artist = split[5]
|
};
|
||||||
|
let album_year = split[2].parse::<u32>()?;
|
||||||
|
let album_title = split[3].to_string();
|
||||||
|
let track_number = split[4].parse::<u32>()?;
|
||||||
|
let track_title = split[5].to_string();
|
||||||
|
let track_artist = split[6]
|
||||||
.to_string()
|
.to_string()
|
||||||
.split("; ")
|
.split("; ")
|
||||||
.map(|s| s.to_owned())
|
.map(|s| s.to_owned())
|
||||||
.collect();
|
.collect();
|
||||||
let track_format = match split[6].to_string().as_str() {
|
let track_format = match split[7].to_string().as_str() {
|
||||||
TRACK_FORMAT_FLAC => Format::Flac,
|
TRACK_FORMAT_FLAC => Format::Flac,
|
||||||
TRACK_FORMAT_MP3 => Format::Mp3,
|
TRACK_FORMAT_MP3 => Format::Mp3,
|
||||||
_ => return Err(Error::Invalid(line.to_string())),
|
_ => return Err(Error::Invalid(line.to_string())),
|
||||||
};
|
};
|
||||||
let track_bitrate = split[7].trim_end_matches("kbps").parse::<u32>()?;
|
let track_bitrate = split[8].trim_end_matches("kbps").parse::<u32>()?;
|
||||||
|
|
||||||
items.push(Item {
|
items.push(Item {
|
||||||
album_artist,
|
album_artist,
|
||||||
|
album_artist_sort,
|
||||||
album_year,
|
album_year,
|
||||||
album_title,
|
album_title,
|
||||||
track_number,
|
track_number,
|
||||||
@ -170,10 +179,15 @@ mod tests {
|
|||||||
|
|
||||||
fn item_to_beets_string(item: &Item) -> String {
|
fn item_to_beets_string(item: &Item) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{album_artist}{sep}{album_year}{sep}{album_title}{sep}\
|
"{album_artist}{sep}{album_artist_sort}{sep}\
|
||||||
|
{album_year}{sep}{album_title}{sep}\
|
||||||
{track_number}{sep}{track_title}{sep}\
|
{track_number}{sep}{track_title}{sep}\
|
||||||
{track_artist}{sep}{track_format}{sep}{track_bitrate}kbps",
|
{track_artist}{sep}{track_format}{sep}{track_bitrate}kbps",
|
||||||
album_artist = item.album_artist,
|
album_artist = item.album_artist,
|
||||||
|
album_artist_sort = match item.album_artist_sort {
|
||||||
|
Some(ref album_artist_sort) => album_artist_sort,
|
||||||
|
None => "",
|
||||||
|
},
|
||||||
album_year = item.album_year,
|
album_year = item.album_year,
|
||||||
album_title = item.album_title,
|
album_title = item.album_title,
|
||||||
track_number = item.track_number,
|
track_number = item.track_number,
|
||||||
|
@ -30,6 +30,7 @@ impl ILibrary for NullLibrary {
|
|||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
pub album_artist: String,
|
pub album_artist: String,
|
||||||
|
pub album_artist_sort: Option<String>,
|
||||||
pub album_year: u32,
|
pub album_year: u32,
|
||||||
pub album_title: String,
|
pub album_title: String,
|
||||||
pub track_number: u32,
|
pub track_number: u32,
|
||||||
@ -43,6 +44,7 @@ pub struct Item {
|
|||||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||||
pub enum Field {
|
pub enum Field {
|
||||||
AlbumArtist(String),
|
AlbumArtist(String),
|
||||||
|
AlbumArtistSort(String),
|
||||||
AlbumYear(u32),
|
AlbumYear(u32),
|
||||||
AlbumTitle(String),
|
AlbumTitle(String),
|
||||||
TrackNumber(u32),
|
TrackNumber(u32),
|
||||||
|
@ -5,6 +5,7 @@ macro_rules! collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: "album_artist a".to_string(),
|
name: "album_artist a".to_string(),
|
||||||
},
|
},
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000",
|
"https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000",
|
||||||
@ -100,6 +101,7 @@ macro_rules! collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: "album_artist b".to_string(),
|
name: "album_artist b".to_string(),
|
||||||
},
|
},
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111",
|
"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111",
|
||||||
@ -192,6 +194,7 @@ macro_rules! collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: "album_artist c".to_string(),
|
name: "album_artist c".to_string(),
|
||||||
},
|
},
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111",
|
"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111",
|
||||||
|
File diff suppressed because one or more lines are too long
@ -41,6 +41,7 @@ fn artist_to_items(artist: &Artist) -> Vec<Item> {
|
|||||||
for track in album.tracks.iter() {
|
for track in album.tracks.iter() {
|
||||||
items.push(Item {
|
items.push(Item {
|
||||||
album_artist: artist.id.name.clone(),
|
album_artist: artist.id.name.clone(),
|
||||||
|
album_artist_sort: artist.sort.as_ref().map(|s| s.name.clone()),
|
||||||
album_year: album.id.year,
|
album_year: album.id.year,
|
||||||
album_title: album.id.title.clone(),
|
album_title: album.id.title.clone(),
|
||||||
track_number: track.id.number,
|
track_number: track.id.number,
|
||||||
|
@ -10,6 +10,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: String::from("Eluveitie"),
|
name: String::from("Eluveitie"),
|
||||||
},
|
},
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38",
|
"https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38",
|
||||||
@ -243,6 +244,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: String::from("Frontside"),
|
name: String::from("Frontside"),
|
||||||
},
|
},
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490",
|
"https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490",
|
||||||
@ -389,6 +391,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: String::from("Heaven’s Basement"),
|
name: String::from("Heaven’s Basement"),
|
||||||
},
|
},
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc",
|
"https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc",
|
||||||
@ -509,6 +512,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: String::from("Metallica"),
|
name: String::from("Metallica"),
|
||||||
},
|
},
|
||||||
|
sort: None,
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab",
|
"https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab",
|
||||||
@ -863,6 +867,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
|||||||
id: ArtistId {
|
id: ArtistId {
|
||||||
name: String::from("Аркона"),
|
name: String::from("Аркона"),
|
||||||
},
|
},
|
||||||
|
sort: Some(ArtistId{
|
||||||
|
name: String::from("Arkona")
|
||||||
|
}),
|
||||||
properties: ArtistProperties {
|
properties: ArtistProperties {
|
||||||
musicbrainz: Some(MusicBrainz::new(
|
musicbrainz: Some(MusicBrainz::new(
|
||||||
"https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212",
|
"https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212",
|
||||||
|
Loading…
Reference in New Issue
Block a user