Compare commits
No commits in common. "e20610ac538e3b39ec5f38ff65e24df928cd6f02" and "8eda98d15f839d2f5fd1d6e9dddad51cb3507a0b" have entirely different histories.
e20610ac53
...
8eda98d15f
7 changed files with 18 additions and 50 deletions
|
@ -145,7 +145,7 @@ async fn run(cli: Cli) -> Result<()> {
|
||||||
std::fs::create_dir_all(&storage_file)?;
|
std::fs::create_dir_all(&storage_file)?;
|
||||||
storage_file.push("musixmatch_session.json");
|
storage_file.push("musixmatch_session.json");
|
||||||
|
|
||||||
let mxm = Musixmatch::builder().storage_file(storage_file).build()?;
|
let mxm = Musixmatch::builder().storage_file(storage_file).build();
|
||||||
|
|
||||||
match mxm.login().await {
|
match mxm.login().await {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
|
|
|
@ -27,7 +27,6 @@ impl Musixmatch {
|
||||||
}
|
}
|
||||||
|
|
||||||
let lyrics_body = self.execute_get_request::<LyricsBody>(&url).await?;
|
let lyrics_body = self.execute_get_request::<LyricsBody>(&url).await?;
|
||||||
lyrics_body.validate()?;
|
|
||||||
Ok(lyrics_body.lyrics)
|
Ok(lyrics_body.lyrics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +47,6 @@ impl Musixmatch {
|
||||||
}
|
}
|
||||||
|
|
||||||
let lyrics_body = self.execute_get_request::<LyricsBody>(&url).await?;
|
let lyrics_body = self.execute_get_request::<LyricsBody>(&url).await?;
|
||||||
lyrics_body.validate()?;
|
|
||||||
Ok(lyrics_body.lyrics)
|
Ok(lyrics_body.lyrics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,6 @@ pub enum Error {
|
||||||
/// Musixmatch content not found
|
/// Musixmatch content not found
|
||||||
#[error("The requested content could not be found")]
|
#[error("The requested content could not be found")]
|
||||||
NotFound,
|
NotFound,
|
||||||
/// Musixmatch content not available
|
|
||||||
#[error("Unfortunately we're not authorized to show these lyrics")]
|
|
||||||
NotAvailable,
|
|
||||||
/// Error from the HTTP client
|
/// Error from the HTTP client
|
||||||
#[error("http error: {0}")]
|
#[error("http error: {0}")]
|
||||||
Http(#[from] reqwest::Error),
|
Http(#[from] reqwest::Error),
|
||||||
|
|
22
src/lib.rs
22
src/lib.rs
|
@ -19,7 +19,7 @@ use hmac::{Hmac, Mac};
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use reqwest::header::{self, HeaderMap};
|
use reqwest::header::{self, HeaderMap};
|
||||||
use reqwest::{Client, ClientBuilder, Url};
|
use reqwest::{Client, Url};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
|
@ -180,25 +180,21 @@ impl MusixmatchBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new, configured Musixmatch client
|
/// Returns a new, configured Musixmatch client
|
||||||
pub fn build(self) -> Result<Musixmatch> {
|
pub fn build(self) -> Musixmatch {
|
||||||
self.build_with_client(ClientBuilder::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new, configured Musixmatch client using a Reqwest client builder
|
|
||||||
pub fn build_with_client(self, client_builder: ClientBuilder) -> Result<Musixmatch> {
|
|
||||||
let storage = self.storage.or_default(|| Box::<FileStorage>::default());
|
let storage = self.storage.or_default(|| Box::<FileStorage>::default());
|
||||||
let stored_session = Musixmatch::retrieve_session(&storage);
|
let stored_session = Musixmatch::retrieve_session(&storage);
|
||||||
|
|
||||||
let mut headers = HeaderMap::new();
|
let mut headers = HeaderMap::new();
|
||||||
headers.insert(header::COOKIE, "AWSELBCORS=0; AWSELB=0".parse().unwrap());
|
headers.insert(header::COOKIE, "AWSELBCORS=0; AWSELB=0".parse().unwrap());
|
||||||
|
|
||||||
let http = client_builder
|
let http = Client::builder()
|
||||||
.user_agent(self.user_agent.unwrap_or_else(|| DEFAULT_UA.to_owned()))
|
.user_agent(self.user_agent.unwrap_or_else(|| DEFAULT_UA.to_owned()))
|
||||||
.gzip(true)
|
.gzip(true)
|
||||||
.default_headers(headers)
|
.default_headers(headers)
|
||||||
.build()?;
|
.build()
|
||||||
|
.expect("http client could not be constructed");
|
||||||
|
|
||||||
Ok(Musixmatch {
|
Musixmatch {
|
||||||
inner: MusixmatchRef {
|
inner: MusixmatchRef {
|
||||||
http,
|
http,
|
||||||
storage,
|
storage,
|
||||||
|
@ -208,15 +204,13 @@ impl MusixmatchBuilder {
|
||||||
usertoken: Mutex::new(stored_session.map(|s| s.usertoken)),
|
usertoken: Mutex::new(stored_session.map(|s| s.usertoken)),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Musixmatch {
|
impl Default for Musixmatch {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
MusixmatchBuilder::new()
|
MusixmatchBuilder::new().build()
|
||||||
.build()
|
|
||||||
.expect("http client could not be constructed")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,11 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
|
|
||||||
use crate::{error::Result, Error};
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub(crate) struct LyricsBody {
|
pub(crate) struct LyricsBody {
|
||||||
pub lyrics: Lyrics,
|
pub lyrics: Lyrics,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LyricsBody {
|
|
||||||
pub(crate) fn validate(&self) -> Result<()> {
|
|
||||||
if self.lyrics.lyrics_body.is_empty()
|
|
||||||
&& self
|
|
||||||
.lyrics
|
|
||||||
.lyrics_copyright
|
|
||||||
.as_deref()
|
|
||||||
.map(|c| c.contains("not authorized"))
|
|
||||||
.unwrap_or_default()
|
|
||||||
{
|
|
||||||
Err(Error::NotAvailable)
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lyrics from the Musixmatch database.
|
/// Lyrics from the Musixmatch database.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
|
|
@ -147,7 +147,7 @@ pub struct Track {
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct TrackLyricsTranslationStatus {
|
pub struct TrackLyricsTranslationStatus {
|
||||||
/// Source language code (e.g. "ko")
|
/// Source language code (e.g. "ko")
|
||||||
pub from: Option<String>,
|
pub from: String,
|
||||||
/// Target language code (e.g. "en")
|
/// Target language code (e.g. "en")
|
||||||
pub to: String,
|
pub to: String,
|
||||||
/// Translation ratio from 0 (untranslated) - 1 (fully translated)
|
/// Translation ratio from 0 (untranslated) - 1 (fully translated)
|
||||||
|
|
|
@ -28,7 +28,6 @@ fn new_mxm() -> Musixmatch {
|
||||||
std::env::var("MUSIXMATCH_PASSWORD").unwrap(),
|
std::env::var("MUSIXMATCH_PASSWORD").unwrap(),
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testfile<P: AsRef<Path>>(name: P) -> PathBuf {
|
fn testfile<P: AsRef<Path>>(name: P) -> PathBuf {
|
||||||
|
@ -52,7 +51,7 @@ mod album {
|
||||||
"6c3cf9d8-88a8-43ed-850b-55813f01e451"
|
"6c3cf9d8-88a8-43ed-850b-55813f01e451"
|
||||||
);
|
);
|
||||||
assert_eq!(album.album_name, "Gangnam Style (강남스타일)");
|
assert_eq!(album.album_name, "Gangnam Style (강남스타일)");
|
||||||
assert!(album.album_rating > 20);
|
assert!(album.album_rating > 25);
|
||||||
assert_eq!(album.album_track_count, 1);
|
assert_eq!(album.album_track_count, 1);
|
||||||
assert_eq!(album.album_release_date.unwrap(), date!(2012 - 01 - 01));
|
assert_eq!(album.album_release_date.unwrap(), date!(2012 - 01 - 01));
|
||||||
assert_eq!(album.album_release_type, AlbumType::Single);
|
assert_eq!(album.album_release_type, AlbumType::Single);
|
||||||
|
@ -367,9 +366,9 @@ mod track {
|
||||||
assert!(
|
assert!(
|
||||||
track.track_lyrics_translation_status.iter().all(|tl| {
|
track.track_lyrics_translation_status.iter().all(|tl| {
|
||||||
(if lang_3c {
|
(if lang_3c {
|
||||||
tl.from.as_deref() == Some("eng")
|
tl.from == "eng"
|
||||||
} else {
|
} else {
|
||||||
tl.from.as_deref() == Some("en")
|
tl.from == "en"
|
||||||
}) && tl.perc >= 0.0
|
}) && tl.perc >= 0.0
|
||||||
&& tl.perc <= 1.0
|
&& tl.perc <= 1.0
|
||||||
}),
|
}),
|
||||||
|
@ -429,7 +428,7 @@ mod track {
|
||||||
assert!(track.updated_time > datetime!(2022-8-27 0:00 UTC));
|
assert!(track.updated_time > datetime!(2022-8-27 0:00 UTC));
|
||||||
|
|
||||||
let first_tstatus = &track.track_lyrics_translation_status[0];
|
let first_tstatus = &track.track_lyrics_translation_status[0];
|
||||||
assert_eq!(first_tstatus.from.as_deref(), Some("ko"));
|
assert_eq!(first_tstatus.from, "ko");
|
||||||
assert!(first_tstatus.perc >= 0.0 && first_tstatus.perc <= 1.0);
|
assert!(first_tstatus.perc >= 0.0 && first_tstatus.perc <= 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,9 +524,9 @@ mod track {
|
||||||
assert!(
|
assert!(
|
||||||
track.track_lyrics_translation_status.iter().all(|tl| {
|
track.track_lyrics_translation_status.iter().all(|tl| {
|
||||||
(if lang_3c {
|
(if lang_3c {
|
||||||
tl.from.as_deref() == Some("eng")
|
tl.from == "eng"
|
||||||
} else {
|
} else {
|
||||||
tl.from.as_deref() == Some("en")
|
tl.from == "en"
|
||||||
}) && tl.perc >= 0.0
|
}) && tl.perc >= 0.0
|
||||||
&& tl.perc <= 1.0
|
&& tl.perc <= 1.0
|
||||||
}),
|
}),
|
||||||
|
@ -627,7 +626,7 @@ mod track {
|
||||||
assert_eq!(tracks.len(), 1);
|
assert_eq!(tracks.len(), 1);
|
||||||
|
|
||||||
let track = &tracks[0];
|
let track = &tracks[0];
|
||||||
assert_eq!(track.commontrack_id, 72643758);
|
assert_eq!(track.commontrack_id, 12426476);
|
||||||
assert_eq!(track.track_name, "Satellite");
|
assert_eq!(track.track_name, "Satellite");
|
||||||
assert_eq!(track.artist_name, "Lena");
|
assert_eq!(track.artist_name, "Lena");
|
||||||
}
|
}
|
||||||
|
@ -665,7 +664,6 @@ mod track {
|
||||||
async fn genres() {
|
async fn genres() {
|
||||||
let genres = new_mxm().genres().await.unwrap();
|
let genres = new_mxm().genres().await.unwrap();
|
||||||
assert!(genres.len() > 360);
|
assert!(genres.len() > 360);
|
||||||
dbg!(&genres);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -992,7 +990,7 @@ mod translation {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn no_credentials() {
|
async fn no_credentials() {
|
||||||
let mxm = Musixmatch::builder().no_storage().build().unwrap();
|
let mxm = Musixmatch::builder().no_storage().build();
|
||||||
let err = mxm
|
let err = mxm
|
||||||
.track_lyrics(TrackId::TrackId(205688271))
|
.track_lyrics(TrackId::TrackId(205688271))
|
||||||
.await
|
.await
|
||||||
|
|
Loading…
Reference in a new issue