2024-03-17 14:19:30 +01:00
|
|
|
#![allow(non_snake_case)]
|
|
|
|
|
|
|
|
use std::{num::ParseIntError, str::FromStr};
|
|
|
|
|
|
|
|
use musichoard::{
|
2024-08-29 13:27:03 +02:00
|
|
|
collection::{album::AlbumDate, musicbrainz::Mbid},
|
2024-08-28 18:21:13 +02:00
|
|
|
external::musicbrainz::{
|
2024-08-29 13:29:53 +02:00
|
|
|
api::{search::SearchReleaseGroupRequest, MusicBrainzClient},
|
|
|
|
http::MusicBrainzHttp,
|
2024-08-28 18:21:13 +02:00
|
|
|
},
|
2024-03-17 14:19:30 +01:00
|
|
|
};
|
|
|
|
use structopt::StructOpt;
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
const USER_AGENT: &str = concat!(
|
|
|
|
"MusicHoard---examples---musicbrainz-api---search-release-group/",
|
|
|
|
env!("CARGO_PKG_VERSION"),
|
|
|
|
" ( musichoard@thenineworlds.net )"
|
|
|
|
);
|
|
|
|
|
|
|
|
#[derive(StructOpt)]
|
|
|
|
struct Opt {
|
2024-03-17 17:18:06 +01:00
|
|
|
#[structopt(subcommand)]
|
|
|
|
command: OptCommand,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt)]
|
|
|
|
enum OptCommand {
|
2024-08-28 18:21:13 +02:00
|
|
|
#[structopt(about = "Search by artist MBID, title(, and date)")]
|
2024-03-17 17:18:06 +01:00
|
|
|
Title(OptTitle),
|
|
|
|
#[structopt(about = "Search by release group MBID")]
|
|
|
|
Rgid(OptRgid),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt)]
|
|
|
|
struct OptTitle {
|
2024-08-28 18:21:13 +02:00
|
|
|
#[structopt(help = "Release group's artist MBID")]
|
|
|
|
arid: Uuid,
|
|
|
|
|
2024-03-17 14:19:30 +01:00
|
|
|
#[structopt(help = "Release group title")]
|
|
|
|
title: String,
|
|
|
|
|
|
|
|
#[structopt(help = "Release group release date")]
|
|
|
|
date: Option<Date>,
|
|
|
|
}
|
|
|
|
|
2024-03-17 17:18:06 +01:00
|
|
|
#[derive(StructOpt)]
|
|
|
|
struct OptRgid {
|
|
|
|
#[structopt(help = "Release group MBID")]
|
|
|
|
rgid: Uuid,
|
|
|
|
}
|
|
|
|
|
2024-03-17 14:19:30 +01:00
|
|
|
struct Date(AlbumDate);
|
|
|
|
|
|
|
|
impl FromStr for Date {
|
|
|
|
type Err = ParseIntError;
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
let mut elems = s.split('-');
|
|
|
|
|
|
|
|
let elem = elems.next();
|
|
|
|
let year = elem.map(|s| s.parse()).transpose()?;
|
|
|
|
|
|
|
|
let elem = elems.next();
|
|
|
|
let month = elem.map(|s| s.parse()).transpose()?;
|
|
|
|
|
|
|
|
let elem = elems.next();
|
|
|
|
let day = elem.map(|s| s.parse()).transpose()?;
|
|
|
|
|
|
|
|
Ok(Date(AlbumDate::new(year, month, day)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Date> for AlbumDate {
|
|
|
|
fn from(value: Date) -> Self {
|
|
|
|
value.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let opt = Opt::from_args();
|
|
|
|
|
|
|
|
println!("USER_AGENT: {USER_AGENT}");
|
|
|
|
|
2024-08-28 18:21:13 +02:00
|
|
|
let http = MusicBrainzHttp::new(USER_AGENT).expect("failed to create API client");
|
|
|
|
let mut client = MusicBrainzClient::new(http);
|
2024-03-17 17:18:06 +01:00
|
|
|
|
2024-08-28 18:21:13 +02:00
|
|
|
let mut request = SearchReleaseGroupRequest::default();
|
|
|
|
let arid: Mbid;
|
|
|
|
let date: AlbumDate;
|
|
|
|
let title: String;
|
|
|
|
let rgid: Mbid;
|
|
|
|
match opt.command {
|
2024-03-17 17:18:06 +01:00
|
|
|
OptCommand::Title(opt_title) => {
|
2024-08-28 18:21:13 +02:00
|
|
|
arid = opt_title.arid.into();
|
|
|
|
date = opt_title.date.map(Into::into).unwrap_or_default();
|
|
|
|
title = opt_title.title;
|
|
|
|
request
|
|
|
|
.arid(&arid)
|
|
|
|
.first_release_date(&date)
|
|
|
|
.release_group(&title);
|
2024-03-17 17:18:06 +01:00
|
|
|
}
|
|
|
|
OptCommand::Rgid(opt_rgid) => {
|
2024-08-28 18:21:13 +02:00
|
|
|
rgid = opt_rgid.rgid.into();
|
|
|
|
request.rgid(&rgid);
|
2024-03-17 17:18:06 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-08-28 18:21:13 +02:00
|
|
|
let matches = client
|
|
|
|
.search_release_group(request)
|
2024-03-17 14:19:30 +01:00
|
|
|
.expect("failed to make API call");
|
|
|
|
|
|
|
|
println!("{matches:#?}");
|
|
|
|
}
|