Add examples for the MusicBrainz API
All checks were successful
Cargo CI / Build and Test (pull_request) Successful in 2m0s
Cargo CI / Lint (pull_request) Successful in 1m6s

This commit is contained in:
Wojciech Kozlowski 2024-03-17 14:15:47 +01:00
parent a75dd46a40
commit a95c06deb5
6 changed files with 124 additions and 2 deletions

View File

@ -33,6 +33,7 @@ jobs:
--source-dir . --source-dir .
--ignore-not-existing --ignore-not-existing
--ignore "build.rs" --ignore "build.rs"
--ignore "examples/*"
--ignore "tests/*" --ignore "tests/*"
--ignore "src/main.rs" --ignore "src/main.rs"
--ignore "src/bin/musichoard-edit.rs" --ignore "src/bin/musichoard-edit.rs"

View File

@ -44,5 +44,15 @@ required-features = ["bin", "database-json", "library-beets", "library-beets-ssh
name = "musichoard-edit" name = "musichoard-edit"
required-features = ["bin", "database-json"] required-features = ["bin", "database-json"]
[[example]]
name = "musicbrainz-api---lookup-artist-release-groups"
path = "examples/musicbrainz_api/lookup_artist_release_groups.rs"
required-features = ["bin", "musicbrainz-api"]
[[example]]
name = "musicbrainz-api---search-release-group"
path = "examples/musicbrainz_api/search_release_group.rs"
required-features = ["bin", "musicbrainz-api"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

View File

@ -46,6 +46,7 @@ grcov codecov/debug/profraw \
--source-dir . \ --source-dir . \
--ignore-not-existing \ --ignore-not-existing \
--ignore "build.rs" \ --ignore "build.rs" \
--ignore "examples/*" \
--ignore "tests/*" \ --ignore "tests/*" \
--ignore "src/main.rs" \ --ignore "src/main.rs" \
--ignore "src/bin/musichoard-edit.rs" \ --ignore "src/bin/musichoard-edit.rs" \

View File

@ -0,0 +1,36 @@
#![allow(non_snake_case)]
use musichoard::{
external::musicbrainz::api::{client::MusicBrainzApiClient, MusicBrainzApi},
interface::musicbrainz::{IMusicBrainz, Mbid},
};
use structopt::StructOpt;
use uuid::Uuid;
const USER_AGENT: &str = concat!(
"MusicHoard---examples---musicbrainz-api---lookup-artist-release-groups/",
env!("CARGO_PKG_VERSION"),
" ( musichoard@thenineworlds.net )"
);
#[derive(StructOpt)]
struct Opt {
#[structopt(help = "Artist MBID to lookup")]
mbid: Uuid,
}
fn main() {
let opt = Opt::from_args();
println!("USER_AGENT: {USER_AGENT}");
let client = MusicBrainzApiClient::new(USER_AGENT).expect("failed to create API client");
let mut api = MusicBrainzApi::new(client);
let mbid: Mbid = opt.mbid.into();
let albums = api
.lookup_artist_release_groups(&mbid)
.expect("failed to make API call");
println!("{albums:#?}");
}

View File

@ -0,0 +1,74 @@
#![allow(non_snake_case)]
use std::{num::ParseIntError, str::FromStr};
use musichoard::{
collection::album::{Album, AlbumDate, AlbumId},
external::musicbrainz::api::{client::MusicBrainzApiClient, MusicBrainzApi},
interface::musicbrainz::{IMusicBrainz, Mbid},
};
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 {
#[structopt(help = "Release group's artist MBID")]
arid: Uuid,
#[structopt(help = "Release group title")]
title: String,
#[structopt(help = "Release group release date")]
date: Option<Date>,
}
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}");
let client = MusicBrainzApiClient::new(USER_AGENT).expect("failed to create API client");
let mut api = MusicBrainzApi::new(client);
let arid: Mbid = opt.arid.into();
let date: AlbumDate = opt.date.map(Into::into).unwrap_or_default();
let album = Album::new(AlbumId::new(opt.title), date, None, vec![]);
let matches = api
.search_release_group(&arid, album)
.expect("failed to make API call");
println!("{matches:#?}");
}

View File

@ -74,7 +74,7 @@ impl<Mbc: IMusicBrainzApiClient> IMusicBrainz for MusicBrainzApi<Mbc> {
) -> Result<Vec<Match<Album>>, Error> { ) -> Result<Vec<Match<Album>>, Error> {
let title = &album.id.title; let title = &album.id.title;
let arid = arid.uuid().as_hyphenated().to_string(); let arid = arid.uuid().as_hyphenated().to_string();
let mut query = format!("\"{title}\" AND arid:{arid}"); let mut query = format!("releasegroup:\"{title}\" AND arid:{arid}");
if let Some(year) = album.date.year { if let Some(year) = album.date.year {
query.push_str(&format!(" AND firstreleasedate:{year}")); query.push_str(&format!(" AND firstreleasedate:{year}"));
@ -292,7 +292,7 @@ mod tests {
let url = format!( let url = format!(
"https://musicbrainz.org/ws/2\ "https://musicbrainz.org/ws/2\
/release-group\ /release-group\
?query=%22{title}%22+AND+arid%3A{arid}+AND+firstreleasedate%3A{year}", ?query=releasegroup%3A%22{title}%22+AND+arid%3A{arid}+AND+firstreleasedate%3A{year}",
title = "an+album", title = "an+album",
arid = "00000000-0000-0000-0000-000000000000", arid = "00000000-0000-0000-0000-000000000000",
year = "1986" year = "1986"