Decide carefully where external::musicbrainz
belongs
#196
90
src/external/musicbrainz/mod.rs
vendored
90
src/external/musicbrainz/mod.rs
vendored
@ -15,10 +15,7 @@ use url::form_urlencoded;
|
|||||||
use crate::{
|
use crate::{
|
||||||
collection::album::AlbumDate,
|
collection::album::AlbumDate,
|
||||||
core::{
|
core::{
|
||||||
collection::{
|
collection::album::{AlbumPrimaryType, AlbumSecondaryType},
|
||||||
album::{Album, AlbumPrimaryType, AlbumSecondaryType},
|
|
||||||
musicbrainz::IMusicBrainzRef,
|
|
||||||
},
|
|
||||||
interface::musicbrainz::Mbid,
|
interface::musicbrainz::Mbid,
|
||||||
},
|
},
|
||||||
interface::musicbrainz::MbidError,
|
interface::musicbrainz::MbidError,
|
||||||
@ -81,44 +78,91 @@ impl<Http> MusicBrainzClient<Http> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<Http: IMusicBrainzHttp> MusicBrainzClient<Http> {
|
impl<Http: IMusicBrainzHttp> MusicBrainzClient<Http> {
|
||||||
|
fn display_album_date(date: &AlbumDate) -> Option<String> {
|
||||||
|
match date.year {
|
||||||
|
Some(year) => match date.month {
|
||||||
|
Some(month) => match date.day {
|
||||||
|
Some(day) => Some(format!("{year}-{month:02}-{day:02}")),
|
||||||
|
None => Some(format!("{year}-{month:02}")),
|
||||||
|
},
|
||||||
|
None => Some(format!("{year}")),
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn search_release_group(
|
pub fn search_release_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
arid: &Mbid,
|
request: SearchReleaseGroupRequest,
|
||||||
album: &Album,
|
) -> Result<SearchReleaseGroupResponse, Error> {
|
||||||
) -> Result<ResponseSearchReleaseGroup, Error> {
|
let mut query: Vec<String> = vec![];
|
||||||
let title = &album.id.title;
|
|
||||||
let arid = arid.uuid().as_hyphenated().to_string();
|
|
||||||
let mut query = format!("arid:{arid}");
|
|
||||||
|
|
||||||
match album.musicbrainz {
|
if let Some(arid) = request.arid {
|
||||||
Some(ref mbref) => {
|
query.push(format!("arid:{}", arid.uuid().as_hyphenated().to_string()));
|
||||||
let rgid = mbref.mbid().uuid().as_hyphenated().to_string();
|
|
||||||
query.push_str(&format!(" AND rgid:{rgid}"));
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
query.push_str(&format!(" AND releasegroup:\"{title}\""));
|
|
||||||
if let Some(year) = album.date.year {
|
|
||||||
query.push_str(&format!(" AND firstreleasedate:{year}"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(date) = request.first_release_date {
|
||||||
|
if let Some(date_string) = Self::display_album_date(date) {
|
||||||
|
query.push(format!("firstreleasedate:{date_string}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let query: String = form_urlencoded::byte_serialize(query.as_bytes()).collect();
|
if let Some(release_group) = request.release_group {
|
||||||
|
query.push(format!("releasegroup:\"{release_group}\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(rgid) = request.rgid {
|
||||||
|
query.push(format!("rgid:{}", rgid.uuid().as_hyphenated().to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let query: String =
|
||||||
|
form_urlencoded::byte_serialize(query.join(" AND ").as_bytes()).collect();
|
||||||
let url = format!("{MB_BASE_URL}/release-group?query={query}");
|
let url = format!("{MB_BASE_URL}/release-group?query={query}");
|
||||||
|
|
||||||
Ok(self.http.get(&url)?)
|
Ok(self.http.get(&url)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct SearchReleaseGroupRequest<'a> {
|
||||||
|
arid: Option<&'a Mbid>,
|
||||||
|
first_release_date: Option<&'a AlbumDate>,
|
||||||
|
release_group: Option<&'a str>,
|
||||||
|
rgid: Option<&'a Mbid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SearchReleaseGroupRequest<'a> {
|
||||||
|
pub fn arid(&mut self, arid: &'a Mbid) -> &mut Self {
|
||||||
|
self.arid = Some(arid);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first_release_date(&mut self, first_release_date: &'a AlbumDate) -> &mut Self {
|
||||||
|
self.first_release_date = Some(first_release_date);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release_group(&mut self, release_group: &'a str) -> &mut Self {
|
||||||
|
self.release_group = Some(release_group);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rgid(&mut self, rgid: &'a Mbid) -> &mut Self {
|
||||||
|
self.rgid = Some(rgid);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Separate deserialize types from internal types like in JSON code.
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all(deserialize = "kebab-case"))]
|
#[serde(rename_all(deserialize = "kebab-case"))]
|
||||||
pub struct ResponseSearchReleaseGroup {
|
pub struct SearchReleaseGroupResponse {
|
||||||
pub release_groups: Vec<SearchReleaseGroup>,
|
pub release_groups: Vec<SearchReleaseGroupResponseUnit>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all(deserialize = "kebab-case"))]
|
#[serde(rename_all(deserialize = "kebab-case"))]
|
||||||
pub struct SearchReleaseGroup {
|
pub struct SearchReleaseGroupResponseUnit {
|
||||||
pub score: u8,
|
pub score: u8,
|
||||||
pub id: Mbid,
|
pub id: Mbid,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
22
src/tui/lib/external/musicbrainz/mod.rs
vendored
22
src/tui/lib/external/musicbrainz/mod.rs
vendored
@ -1,8 +1,11 @@
|
|||||||
//! Module for interacting with the [MusicBrainz API](https://musicbrainz.org/doc/MusicBrainz_API).
|
//! Module for interacting with the [MusicBrainz API](https://musicbrainz.org/doc/MusicBrainz_API).
|
||||||
|
|
||||||
use musichoard::{
|
use musichoard::{
|
||||||
collection::album::Album,
|
collection::{album::Album, musicbrainz::IMusicBrainzRef},
|
||||||
external::musicbrainz::{IMusicBrainzHttp, MusicBrainzClient, SearchReleaseGroup},
|
external::musicbrainz::{
|
||||||
|
IMusicBrainzHttp, MusicBrainzClient, SearchReleaseGroupRequest,
|
||||||
|
SearchReleaseGroupResponseUnit,
|
||||||
|
},
|
||||||
interface::musicbrainz::Mbid,
|
interface::musicbrainz::Mbid,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -24,16 +27,25 @@ impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
|
|||||||
arid: &Mbid,
|
arid: &Mbid,
|
||||||
album: &Album,
|
album: &Album,
|
||||||
) -> Result<Vec<Match<Album>>, Error> {
|
) -> Result<Vec<Match<Album>>, Error> {
|
||||||
let mb_response = self.client.search_release_group(arid, album)?;
|
let mut request = SearchReleaseGroupRequest::default();
|
||||||
|
request
|
||||||
|
.arid(arid)
|
||||||
|
.release_group(&album.id.title)
|
||||||
|
.first_release_date(&album.date);
|
||||||
|
if let Some(ref mbref) = album.musicbrainz {
|
||||||
|
request.rgid(mbref.mbid());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mb_response = self.client.search_release_group(request)?;
|
||||||
Ok(mb_response
|
Ok(mb_response
|
||||||
.release_groups
|
.release_groups
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(from_search_release_group)
|
.map(from_search_release_group_response_unit)
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_search_release_group(entity: SearchReleaseGroup) -> Match<Album> {
|
fn from_search_release_group_response_unit(entity: SearchReleaseGroupResponseUnit) -> Match<Album> {
|
||||||
let mut album = Album::new(
|
let mut album = Album::new(
|
||||||
entity.title,
|
entity.title,
|
||||||
entity.first_release_date,
|
entity.first_release_date,
|
||||||
|
Loading…
Reference in New Issue
Block a user