diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f857c4..0801b22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,17 +3,6 @@ All notable changes to this project will be documented in this file. -## [v0.4.0](https://codeberg.org/ThetaDev/musixmatch-inofficial/compare/musixmatch-inofficial/v0.3.0..musixmatch-inofficial/v0.4.0) - 2025-12-19 - -### 🚀 Features - -- Add richsync API (word-by-word lyrics) - ([16e4440](https://codeberg.org/ThetaDev/musixmatch-inofficial/commit/16e4440a5d31cf8078c1327d8168975576d4db1f)) - -### 🐛 Bug Fixes - -- Mark structs non-exhaustive, add weekly charts, update URLs to new MXM documentation - ([e044cfc](https://codeberg.org/ThetaDev/musixmatch-inofficial/commit/e044cfcbd231380e11c14cab31e46b651a942819)) - - ## [v0.3.0](https://codeberg.org/ThetaDev/musixmatch-inofficial/compare/musixmatch-inofficial/v0.2.1..musixmatch-inofficial/v0.3.0) - 2025-12-08 ### 🚀 Features diff --git a/Cargo.toml b/Cargo.toml index b2875fb..0d3ead1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "musixmatch-inofficial" -version = "0.4.0" +version = "0.3.0" rust-version = "1.70.0" edition.workspace = true authors.workspace = true @@ -23,7 +23,7 @@ keywords = ["music", "lyrics"] categories = ["api-bindings", "multimedia"] [workspace.dependencies] -musixmatch-inofficial = { version = "0.4.0", path = ".", default-features = false } +musixmatch-inofficial = { version = "0.3.0", path = ".", default-features = false } [features] default = ["default-tls"] diff --git a/README.md b/README.md index a67328c..cd5c568 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ commercially. You will get in trouble if you use this client to create a public lyrics site/app. If you want to use Musixmatch data for this purpose, you will have to give them money (see their [commercial plans](https://developer.musixmatch.com/plans)) and use their -[official API](https://docs.musixmatch.com/lyrics-api). +[official API](https://developer.musixmatch.com/documentation). ## Development info diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 28bdae4..9c882bc 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -3,17 +3,6 @@ All notable changes to this project will be documented in this file. -## [v0.4.0](https://codeberg.org/ThetaDev/musixmatch-inofficial/compare/musixmatch-cli/v0.3.1..musixmatch-cli/v0.4.0) - 2025-12-19 - -### 🚀 Features - -- Add richsync support to CLI - ([4d1fbab](https://codeberg.org/ThetaDev/musixmatch-inofficial/commit/4d1fbabaa8ff3268c83bd3725412e48d81b3f7c1)) - -### 🐛 Bug Fixes - -- Mark structs non-exhaustive, add weekly charts, update URLs to new MXM documentation - ([e044cfc](https://codeberg.org/ThetaDev/musixmatch-inofficial/commit/e044cfcbd231380e11c14cab31e46b651a942819)) - - ## [v0.3.1](https://codeberg.org/ThetaDev/musixmatch-inofficial/compare/musixmatch-cli/v0.3.0..musixmatch-cli/v0.3.1) - 2025-12-08 ### 🐛 Bug Fixes diff --git a/cli/Cargo.toml b/cli/Cargo.toml index fea8aa0..6543bc5 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "musixmatch-cli" -version = "0.4.0" +version = "0.3.1" rust-version = "1.70.0" edition.workspace = true authors.workspace = true diff --git a/cli/src/main.rs b/cli/src/main.rs index da4a38c..84e26b9 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -50,17 +50,6 @@ enum Commands { #[clap(long)] lang: Option, }, - /// Get richsync (word-by-word synced lyrics) - Richsync { - #[clap(flatten)] - ident: TrackIdentifiers, - /// Track length - #[clap(short, long)] - length: Option, - /// Maximum deviation from track length (Default: 1s) - #[clap(long)] - max_deviation: Option, - }, /// Get track metadata Track { #[clap(flatten)] @@ -329,34 +318,6 @@ async fn run(cli: Cli) -> Result<()> { println!("{}", subtitles.subtitle_body); } } - Commands::Richsync { - ident, - length, - max_deviation, - } => { - let track_id = get_track_id(ident, &mxm).await?; - let richsync = mxm - .track_richsync(track_id.clone(), length, max_deviation.or(Some(1.0))) - .await?; - - eprintln!("Richsync ID: {}", richsync.richsync_id); - eprintln!( - "Language: {}", - richsync.richsync_language.as_deref().unwrap_or(NA_STR) - ); - eprintln!("Length: {}", richsync.richsync_length); - eprintln!( - "Copyright: {}", - richsync - .lyrics_copyright - .as_deref() - .map(|s| s.trim()) - .unwrap_or(NA_STR) - ); - - eprintln!(); - println!("{}", richsync.richsync_body); - } Commands::Track { ident } => { let track = get_track(ident, &mxm, false).await?; println!("{}", serde_json::to_string_pretty(&track)?) diff --git a/src/apis/album_api.rs b/src/apis/album_api.rs index 88c175a..c95fead 100644 --- a/src/apis/album_api.rs +++ b/src/apis/album_api.rs @@ -10,7 +10,7 @@ impl Musixmatch { /// - `id`: [Album ID](crate::models::AlbumId) /// /// # Reference - /// + /// pub async fn album(&self, id: AlbumId<'_>) -> Result { let mut url = self.new_url("album.get"); { @@ -35,7 +35,7 @@ impl Musixmatch { /// - `page`: Define the page number for paginated results, starting from 1. /// /// # Reference - /// + /// pub async fn artist_albums( &self, artist_id: ArtistId<'_>, @@ -65,7 +65,7 @@ impl Musixmatch { .collect()) } - /// This api provides you the list of the newly released albums of a given country. + /// This api provides you the list of the top albums of a given country. /// /// # Parameters /// - `country`: A valid country code (default: "US") diff --git a/src/apis/artist_api.rs b/src/apis/artist_api.rs index 664c603..024c6bc 100644 --- a/src/apis/artist_api.rs +++ b/src/apis/artist_api.rs @@ -10,7 +10,7 @@ impl Musixmatch { /// - `id`: [Artist ID](crate::models::ArtistId) /// /// # Reference - /// + /// pub async fn artist(&self, id: ArtistId<'_>) -> Result { let mut url = self.new_url("artist.get"); { @@ -34,7 +34,7 @@ impl Musixmatch { /// - `page`: Define the page number for paginated results, starting from 1. /// /// # Reference - /// + /// pub async fn artist_search( &self, q_artist: &str, @@ -67,7 +67,7 @@ impl Musixmatch { /// - `page`: Define the page number for paginated results, starting from 1. /// /// # Reference - /// + /// pub async fn chart_artists( &self, country: &str, diff --git a/src/apis/lyrics_api.rs b/src/apis/lyrics_api.rs index f1e0cc2..d9a5038 100644 --- a/src/apis/lyrics_api.rs +++ b/src/apis/lyrics_api.rs @@ -12,7 +12,7 @@ impl Musixmatch { /// - `q_artist`: Artist of the track /// /// # Reference - /// + /// pub async fn matcher_lyrics(&self, q_track: &str, q_artist: &str) -> Result { let mut url = self.new_url("matcher.lyrics.get"); { @@ -37,7 +37,7 @@ impl Musixmatch { /// - `id`: [Track ID](crate::models::TrackId) /// /// # Reference - /// + /// pub async fn track_lyrics(&self, id: TrackId<'_>) -> Result { let mut url = self.new_url("track.lyrics.get"); { @@ -58,9 +58,9 @@ impl Musixmatch { /// - `id`: [Track ID](crate::models::TrackId) /// - `selected_language`: The language of the translated lyrics /// [(ISO 639‑1)](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) - /// /// # Reference - /// + /// None, the [public translation API](https://developer.musixmatch.com/documentation/api-reference/track-lyrics-translation-get) + /// is only available on commercial plans pub async fn track_lyrics_translation( &self, id: TrackId<'_>, diff --git a/src/apis/mod.rs b/src/apis/mod.rs index 6efe0e9..fcde0df 100644 --- a/src/apis/mod.rs +++ b/src/apis/mod.rs @@ -1,7 +1,6 @@ mod album_api; mod artist_api; mod lyrics_api; -mod richsync_api; mod snippet_api; mod subtitle_api; mod track_api; diff --git a/src/apis/richsync_api.rs b/src/apis/richsync_api.rs deleted file mode 100644 index 2d726e3..0000000 --- a/src/apis/richsync_api.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::error::Result; -use crate::models::richsync::{RichsyncBody, RichsyncLyrics}; -use crate::models::TrackId; -use crate::Musixmatch; - -impl Musixmatch { - /// Get the richsync (word-by-word synchronized lyrics) for a track specified by its ID. - /// - /// # Parameters - /// - `id`: [Track ID](crate::models::TrackId) - /// - `f_richsync_length`: Optional richsync length (track duration) in seconds - /// - `f_richsync_length_max_deviation`: Optional maximum amount of seconds the richsync length - /// is allowed to deviate from the given value. The Musixmatch app sets this value to 1, - /// so this should be the recommended value. - /// - /// # Reference - /// - pub async fn track_richsync( - &self, - id: TrackId<'_>, - f_richsync_length: Option, - f_richsync_length_max_deviation: Option, - ) -> Result { - let mut url = self.new_url("track.richsync.get"); - { - let mut url_query = url.query_pairs_mut(); - - let id_param = id.to_param(); - url_query.append_pair(id_param.0, &id_param.1); - if let Some(f_richsync_length) = f_richsync_length { - url_query.append_pair("f_richsync_length", &f_richsync_length.to_string()); - } - if let Some(f_richsync_length_max_deviation) = f_richsync_length_max_deviation { - url_query.append_pair( - "f_richsync_length_max_deviation", - &f_richsync_length_max_deviation.to_string(), - ); - } - url_query.finish(); - } - - let richsync_body = self.execute_get_request::(&url).await?; - Ok(richsync_body.richsync) - } -} diff --git a/src/apis/snippet_api.rs b/src/apis/snippet_api.rs index cf0fdfd..c8b3591 100644 --- a/src/apis/snippet_api.rs +++ b/src/apis/snippet_api.rs @@ -14,7 +14,7 @@ impl Musixmatch { /// - `id`: [Track ID](crate::models::TrackId) /// /// # Reference - /// + /// pub async fn track_snippet(&self, id: TrackId<'_>) -> Result { let mut url = self.new_url("track.snippet.get"); { diff --git a/src/apis/subtitle_api.rs b/src/apis/subtitle_api.rs index 656e0c2..904f028 100644 --- a/src/apis/subtitle_api.rs +++ b/src/apis/subtitle_api.rs @@ -16,7 +16,7 @@ impl Musixmatch { /// so this should be the recommended value. /// /// # Reference - /// + /// pub async fn matcher_subtitle( &self, q_track: &str, @@ -65,7 +65,7 @@ impl Musixmatch { /// so this should be the recommended value. /// /// # Reference - /// + /// pub async fn track_subtitle( &self, id: TrackId<'_>, diff --git a/src/apis/track_api.rs b/src/apis/track_api.rs index 7ab24b3..1c25975 100644 --- a/src/apis/track_api.rs +++ b/src/apis/track_api.rs @@ -18,7 +18,7 @@ impl Musixmatch { /// instead of [ISO 639‑1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) codes. /// /// # Reference - /// + /// pub async fn matcher_track( &self, q_track: &str, @@ -77,7 +77,7 @@ impl Musixmatch { /// instead of [ISO 639‑1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) codes. /// /// # Reference - /// + /// pub async fn track( &self, id: TrackId<'_>, @@ -126,7 +126,7 @@ impl Musixmatch { /// - `page`: Define the page number for paginated results, starting from 1. /// /// # Reference - /// + /// pub async fn album_tracks( &self, id: AlbumId<'_>, @@ -166,7 +166,7 @@ impl Musixmatch { /// - `page`: Define the page number for paginated results, starting from 1. /// /// # Reference - /// + /// pub async fn chart_tracks( &self, country: &str, @@ -202,7 +202,7 @@ impl Musixmatch { /// Get the list of the music genres the Musixmatch catalogue. /// /// # Reference - /// + /// pub async fn genres(&self) -> Result> { let url = self.new_url("music.genres.get"); let genres = self.execute_get_request::(&url).await?; @@ -225,7 +225,7 @@ impl Musixmatch { /// ``` /// /// # Reference - /// + /// pub fn track_search(&self) -> TrackSearchQuery<'_> { TrackSearchQuery { mxm: self.clone(), diff --git a/src/models/album.rs b/src/models/album.rs index 6389836..9d4e8f7 100644 --- a/src/models/album.rs +++ b/src/models/album.rs @@ -83,7 +83,7 @@ pub struct Album { /// Album type /// -/// Source: +/// Source: #[allow(missing_docs)] #[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum AlbumType { diff --git a/src/models/id.rs b/src/models/id.rs index c91fe5c..3753c49 100644 --- a/src/models/id.rs +++ b/src/models/id.rs @@ -103,7 +103,6 @@ impl SortOrder { /// Musixmatch fully qualified ID #[derive(Clone, Copy, PartialEq, Eq)] -#[allow(clippy::exhaustive_structs)] pub struct Fqid { /// Numeric Musixmatch ID pub id: u64, diff --git a/src/models/mod.rs b/src/models/mod.rs index f381bbe..8aef72e 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,5 +1,4 @@ //! Musixmatch API models -#![warn(clippy::exhaustive_structs)] pub(crate) mod subtitle; pub use subtitle::Subtitle; @@ -19,11 +18,6 @@ pub use id::TrackId; pub(crate) mod lyrics; pub use lyrics::Lyrics; -pub(crate) mod richsync; -pub use richsync::RichsyncLine; -pub use richsync::RichsyncLyrics; -pub use richsync::RichsyncWord; - pub(crate) mod translation; pub use translation::Translation; pub use translation::TranslationList; diff --git a/src/models/richsync.rs b/src/models/richsync.rs deleted file mode 100644 index 94a4007..0000000 --- a/src/models/richsync.rs +++ /dev/null @@ -1,83 +0,0 @@ -use serde::{Deserialize, Serialize}; -use time::OffsetDateTime; - -use crate::error::Error; - -#[derive(Debug, Deserialize)] -pub(crate) struct RichsyncBody { - pub richsync: RichsyncLyrics, -} - -/// Lyrics synced word-by-word -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[non_exhaustive] -pub struct RichsyncLyrics { - /// Unique Musixmatch richsync ID - pub richsync_id: u64, - /// Richsync JSON data - /// - /// List of [`RichsyncLine`] - pub richsync_body: String, - /// Language code (e.g. "en") - /// - /// Note that this field has a typo and is called `richssync_language` in the Musixmatch implementation. - #[serde( - default, - deserialize_with = "crate::api_model::null_if_empty", - alias = "richssync_language" - )] - pub richsync_language: Option, - /// Language name (e.g. "English") - #[serde(default, deserialize_with = "crate::api_model::null_if_empty")] - pub richsync_language_description: Option, - /// Duration of the synced track in seconds - pub richsync_length: u32, - /// Copyright text of the lyrics - /// - /// Ends with a newline. - /// - /// Example: - /// ```text - /// Writer(s): David Hodges - /// Copyright: Emi Blackwood Music Inc., 12.06 Publishing, Hipgnosis Sfh I Limited, Hifi Music Ip Issuer L.p. - /// ``` - #[serde(default, deserialize_with = "crate::api_model::null_if_empty")] - pub lyrics_copyright: Option, - /// Date and time when the lyrics were last updated - #[serde(with = "time::serde::rfc3339")] - pub updated_time: OffsetDateTime, -} - -/// Line of word-by-word synchronized lyrics -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] -pub struct RichsyncLine { - /// Line start timestamp in seconds - pub ts: f32, - /// Line end timestamp in seconds - pub te: f32, - /// Words in the line - #[serde(default)] - pub l: Vec, - /// Text content of the line - pub x: String, -} - -/// Single word of word-by-word synchronized lyrics -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] -pub struct RichsyncWord { - /// Word content - pub c: String, - /// Time offset from the line timestamp in seconds - /// - /// Position of the word in the track is line.ts + o. - pub o: f32, -} - -impl RichsyncLyrics { - /// Get the synchronized lyrics lines - pub fn get_lines(&self) -> Result, Error> { - serde_json::from_str(&self.richsync_body).map_err(Error::from) - } -} diff --git a/src/models/snippet.rs b/src/models/snippet.rs index 05edfe8..fa9944b 100644 --- a/src/models/snippet.rs +++ b/src/models/snippet.rs @@ -15,7 +15,6 @@ pub(crate) struct SnippetBody { /// Example: "There's not a thing that I would change" #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[allow(missing_docs)] -#[non_exhaustive] pub struct Snippet { /// Unique Musixmatch Snippet ID pub snippet_id: u64, diff --git a/src/models/subtitle.rs b/src/models/subtitle.rs index a79fee3..0ff3b09 100644 --- a/src/models/subtitle.rs +++ b/src/models/subtitle.rs @@ -323,7 +323,6 @@ fn escape_xml(input: &str) -> String { /// Single subtitle line #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[allow(clippy::exhaustive_structs)] pub struct SubtitleLine { /// Subtitle line text pub text: String, @@ -333,7 +332,6 @@ pub struct SubtitleLine { /// Position of a subtitle line in the track #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[allow(clippy::exhaustive_structs)] pub struct SubtitleTime { /// Minute component of the timestamp pub minutes: u32, diff --git a/src/models/track.rs b/src/models/track.rs index 4104273..bfb1980 100644 --- a/src/models/track.rs +++ b/src/models/track.rs @@ -160,7 +160,6 @@ pub struct TrackLyricsTranslationStatus { /// Lyrics parts marked with the performer who is singing them #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] pub struct TrackPerformerTagging { /// Musixmatch user ID of the user who added the performer tags /// @@ -186,7 +185,6 @@ pub struct TrackPerformerTagging { /// Performer-tagged lyrics part #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] pub struct PerformerTaggingPart { /// Part of the lyrics text /// @@ -202,7 +200,6 @@ pub struct PerformerTaggingPart { /// Lyrics performer #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] pub struct Performer { /// artist / unknown #[serde(rename = "type")] @@ -222,7 +219,6 @@ pub struct Performer { /// Artists (and possibly other objects) that are referenced by the tagged parts #[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(default)] -#[non_exhaustive] pub struct PerformerTaggingResources { /// List of artists tagged as performers pub artists: Vec, @@ -230,16 +226,11 @@ pub struct PerformerTaggingResources { /// Available track charts #[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[non_exhaustive] pub enum ChartName { /// Editorial chart Top, /// Most viewed lyrics in the last 2 hours Hot, - /// Most viewed lyrics in the last 7 days - MxmWeekly, - /// Most viewed lyrics in the last 7 days, limited to new releases only. - MxmWeeklyNew, } impl ChartName { @@ -247,8 +238,6 @@ impl ChartName { match self { ChartName::Top => "top", ChartName::Hot => "hot", - ChartName::MxmWeekly => "mxmweekly", - ChartName::MxmWeeklyNew => "mxmweekly_new", } } } diff --git a/testfiles/richsync.json b/testfiles/richsync.json deleted file mode 100644 index 02b14ab..0000000 --- a/testfiles/richsync.json +++ /dev/null @@ -1,422 +0,0 @@ -[ - { - "ts": 3.94, - "te": 7.24, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.33 - }, - { - "c": "birthday", - "o": 0.66 - }, - { - "c": " ", - "o": 1.8 - }, - { - "c": "to", - "o": 1.92 - }, - { - "c": " ", - "o": 2.235 - }, - { - "c": "you", - "o": 2.55 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 8.0399, - "te": 11.34, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.33 - }, - { - "c": "birthday", - "o": 0.66 - }, - { - "c": " ", - "o": 1.26 - }, - { - "c": "to", - "o": 1.86 - }, - { - "c": " ", - "o": 2.205 - }, - { - "c": "you", - "o": 2.55 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 11.88, - "te": 15.57, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.315 - }, - { - "c": "birthday,", - "o": 0.63 - }, - { - "c": " ", - "o": 1.275 - }, - { - "c": "happy", - "o": 1.92 - }, - { - "c": " ", - "o": 2.25 - }, - { - "c": "birthday", - "o": 2.58 - } - ], - "x": "Happy birthday, happy birthday" - }, - { - "ts": 15.74, - "te": 19.01, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.315 - }, - { - "c": "birthday", - "o": 0.63 - }, - { - "c": " ", - "o": 1.185 - }, - { - "c": "to", - "o": 1.74 - }, - { - "c": " ", - "o": 2.145 - }, - { - "c": "you", - "o": 2.55 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 19.71, - "te": 23.07, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.344 - }, - { - "c": "birthday", - "o": 0.689 - }, - { - "c": " ", - "o": 1.274 - }, - { - "c": "to", - "o": 1.86 - }, - { - "c": " ", - "o": 2.22 - }, - { - "c": "you", - "o": 2.58 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 23.57, - "te": 26.96, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.33 - }, - { - "c": "birthday", - "o": 0.66 - }, - { - "c": " ", - "o": 1.26 - }, - { - "c": "to", - "o": 1.86 - }, - { - "c": " ", - "o": 2.235 - }, - { - "c": "you", - "o": 2.61 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 27.52, - "te": 31.21, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.315 - }, - { - "c": "birthday,", - "o": 0.63 - }, - { - "c": " ", - "o": 1.29 - }, - { - "c": "happy", - "o": 1.95 - }, - { - "c": " ", - "o": 2.28 - }, - { - "c": "birthday", - "o": 2.61 - } - ], - "x": "Happy birthday, happy birthday" - }, - { - "ts": 31.42, - "te": 34.42, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.315 - }, - { - "c": "birthday", - "o": 0.63 - }, - { - "c": " ", - "o": 1.2 - }, - { - "c": "to", - "o": 1.77 - }, - { - "c": " ", - "o": 2.175 - }, - { - "c": "you", - "o": 2.58 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 37.44, - "te": 40.59, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.315 - }, - { - "c": "birthday", - "o": 0.63 - }, - { - "c": " ", - "o": 1.74 - }, - { - "c": "to", - "o": 1.86 - }, - { - "c": " ", - "o": 2.22 - }, - { - "c": "you", - "o": 2.58 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 41.26, - "te": 44.38, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.3 - }, - { - "c": "birthday", - "o": 0.6 - }, - { - "c": " ", - "o": 1.2 - }, - { - "c": "to", - "o": 1.8 - }, - { - "c": " ", - "o": 2.145 - }, - { - "c": "you", - "o": 2.49 - } - ], - "x": "Happy birthday to you" - }, - { - "ts": 45.17, - "te": 50.24, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.315 - }, - { - "c": "birthday,", - "o": 0.63 - }, - { - "c": " ", - "o": 1.275 - }, - { - "c": "happy", - "o": 1.92 - }, - { - "c": " ", - "o": 2.264 - }, - { - "c": "birthday", - "o": 2.61 - } - ], - "x": "Happy birthday, happy birthday" - }, - { - "ts": 50.99, - "te": 54.11, - "l": [ - { - "c": "Happy", - "o": 0.0 - }, - { - "c": " ", - "o": 0.315 - }, - { - "c": "birthday", - "o": 0.63 - }, - { - "c": " ", - "o": 1.2 - }, - { - "c": "to", - "o": 1.77 - }, - { - "c": " ", - "o": 2.13 - }, - { - "c": "you", - "o": 2.49 - } - ], - "x": "Happy birthday to you" - } -] \ No newline at end of file diff --git a/tests/tests.rs b/tests/tests.rs index 5365d6b..70d1fc8 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -647,8 +647,6 @@ mod track { #[rstest] #[case::top(ChartName::Top)] #[case::hot(ChartName::Hot)] - #[case::weekly(ChartName::MxmWeekly)] - #[case::weekly_new(ChartName::MxmWeeklyNew)] #[tokio::test] async fn charts(#[case] chart_name: ChartName, #[future] mxm: Musixmatch) { let tracks = mxm @@ -1073,106 +1071,6 @@ mod translation { } } -mod richsync { - use std::{fs::File, io::BufWriter}; - - use super::*; - - #[rstest] - #[case::trackid(TrackId::TrackId(205688271))] - #[case::commontrack(TrackId::Commontrack(118480583))] - #[case::vanity(TrackId::CommontrackVanity("aespa/Black-Mamba".into()))] - #[case::isrc(TrackId::Isrc("KRA302000590".into()))] - #[case::spotify(TrackId::Spotify("1t2qYCAjUAoGfeFeoBlK51".into()))] - #[tokio::test] - async fn from_id(#[case] track_id: TrackId<'_>, #[future] mxm: Musixmatch) { - let richsync = mxm - .await - .track_richsync(track_id, Some(175.0), Some(1.0)) - .await - .unwrap(); - let lines = richsync.get_lines().unwrap(); - - assert_eq!(richsync.richsync_id, 8298962); - assert_eq!(richsync.richsync_language.unwrap(), "ko"); - assert_eq!(richsync.richsync_language_description.unwrap(), "korean"); - let copyright = richsync.lyrics_copyright.unwrap(); - assert!( - copyright.contains("Kenneth Scott Chesak"), - "copyright: {copyright}", - ); - assert_eq!(richsync.richsync_length, 175); - assert!(richsync.updated_time > datetime!(2022-8-27 0:00 UTC)); - - assert_eq!(lines.len(), 67); - for line in &lines { - assert!(!line.l.is_empty()); - } - } - - /// This track has no lyrics - #[rstest] - #[tokio::test] - async fn instrumental(#[future] mxm: Musixmatch) { - let err = mxm - .await - .track_richsync(TrackId::Commontrack(126454494), Some(246.0), Some(1.0)) - .await - .unwrap_err(); - - assert!(matches!(err, Error::NotFound), "got: {err:?}"); - } - - /// This track has not been synced - #[rstest] - #[tokio::test] - async fn unsynced(#[future] mxm: Musixmatch) { - let err = mxm - .await - .track_richsync( - TrackId::Spotify("6oaWIABGL7eeiMILEDyGX1".into()), - Some(213.0), - Some(1.0), - ) - .await - .unwrap_err(); - - assert!(matches!(err, Error::NotFound), "got: {err:?}"); - } - - /// Try to get subtitles with wrong length parameter - #[rstest] - #[tokio::test] - async fn wrong_length(#[future] mxm: Musixmatch) { - let err = mxm - .await - .track_richsync(TrackId::Commontrack(118480583), Some(200.0), Some(1.0)) - .await - .unwrap_err(); - - assert!(matches!(err, Error::NotFound), "got: {err:?}"); - } - - #[rstest] - #[tokio::test] - async fn download_testdata(#[future] mxm: Musixmatch) { - let json_path = testfile("richsync.json"); - if json_path.exists() { - return; - } - - let richsync = mxm - .await - .track_richsync(TrackId::Commontrack(26134491), None, None) - .await - .unwrap(); - let lines = richsync.get_lines().unwrap(); - - let json_file = File::create(json_path).unwrap(); - serde_json::to_writer_pretty(BufWriter::new(json_file), &lines).unwrap(); - } -} - #[track_caller] fn assert_imgurl(url: &Option, ends_with: &str) { assert!(