From 0c4ab0a01d2543ce183d26b1ecc1d4285062c309 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Fri, 16 Jun 2023 01:43:18 +0200 Subject: [PATCH 1/2] add album_track test --- codegen/Cargo.toml | 1 + src/requests.rs | 6 ++++ tests/snapshots/tests__album_track.snap | 44 +++++++++++++++++++++++++ tests/tests.rs | 15 +++++++++ 4 files changed, 66 insertions(+) create mode 100644 tests/snapshots/tests__album_track.snap diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index f314152..d9e8f18 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -2,6 +2,7 @@ name = "codegen" version = "0.1.0" edition = "2021" +publish = false [dependencies] reqwest = "0.11.11" diff --git a/src/requests.rs b/src/requests.rs index f593a71..001db6d 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -53,6 +53,12 @@ impl Bandcamp { Ok(resp.json().await?) } + /// Get a album (or a track) from the Bandcamp API + /// + /// # Parameters + /// - `band_id` The Band ID of the album/track + /// - `tralbum_id` Album/Track ID + /// - `tralbum_type` Track/Album pub async fn album( &self, band_id: u64, diff --git a/tests/snapshots/tests__album_track.snap b/tests/snapshots/tests__album_track.snap new file mode 100644 index 0000000..6596342 --- /dev/null +++ b/tests/snapshots/tests__album_track.snap @@ -0,0 +1,44 @@ +--- +source: tests/tests.rs +assertion_line: 69 +expression: "&album" +--- +Album( + id: 716010980, + title: "All Was Well", + art_id: Some(2367528067), + type: t, + tralbum_artist: "Wintergatan", + band: BandInfo( + band_id: 2464198920, + name: "Wintergatan", + bio: "", + image_id: Some(1354613), + location: "Gothenburg, Sweden", + ), + bandcamp_url: "https://wintergatan.bandcamp.com/track/all-was-well", + credits: None, + about: None, + featured_track_id: 716010980, + release_date: 1366761600, + tags: [ + Tag( + name: "Pop", + norm_name: "pop", + isloc: false, + ), + ], + tracks: [ + Track( + track_id: 716010980, + title: "All Was Well", + album_id: 2572654767, + album_title: None, + band_id: 2464198920, + band_name: Some("Wintergatan"), + duration: 183.224, + streaming_url: "[streaming_url]", + track_num: 8, + ), + ], +) diff --git a/tests/tests.rs b/tests/tests.rs index 8f35ec3..9bf1fbb 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -58,6 +58,21 @@ async fn album2() { check_image(&album.img_url().unwrap()).await; } +#[tokio::test] +async fn album_track() { + let bc = Bandcamp::new(); + let album = bc + .album_uid(format!("{}t{}", BAND_WINTERGATAN, 716010980)) + .await + .unwrap(); + + insta::assert_ron_snapshot!(&album, { + ".tracks[].streaming_url" => "[streaming_url]" + }); + check_stream_urls(&album.tracks); + check_image(&album.img_url().unwrap()).await; +} + #[tokio::test] async fn search() { let bc = Bandcamp::new(); From b3bf3f62a7f180c639cf32ee4b0013958c298c50 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 18 Nov 2023 11:54:18 +0100 Subject: [PATCH 2/2] feat: improve error handling --- src/error.rs | 6 ++++++ src/models.rs | 7 +++++++ src/requests.rs | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/error.rs b/src/error.rs index 2f076a7..1cd27cf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -12,6 +12,12 @@ pub enum Error { /// Website parsing error #[error("website parsing error: {0}")] WebsiteParsing(Cow<'static, str>), + /// Item not found on Bandcamp + #[error("{0}")] + NotFound(Cow<'static, str>), + /// Other error from Bandcamp + #[error("{0}")] + Bandcamp(Cow<'static, str>), #[error("invalid bandcamp url")] InvalidUrl, #[error("invalid album uid")] diff --git a/src/models.rs b/src/models.rs index 1e0ed49..832fdca 100644 --- a/src/models.rs +++ b/src/models.rs @@ -64,6 +64,13 @@ pub struct Track { pub band_name: Option, /// Duration in seconds pub duration: f32, + /// Map of audio formats and URLs. + /// + /// 128kbit/s MP3 is currently the only publicly available format. + /// + /// **Example:** + /// + /// `mp3-128` => `https://bandcamp.com/stream_redirect?enc=mp3-128&track_id=4173325157&ts=1686871135&t=a1f7904205e6caca970009ca6744ef0b512f353a` pub streaming_url: BTreeMap, pub track_num: u16, } diff --git a/src/requests.rs b/src/requests.rs index 001db6d..58ac17c 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -38,6 +38,28 @@ struct SearchResultWrapper { auto: SearchResult, } +#[derive(Deserialize)] +#[serde(untagged)] +enum ResponseWrapper { + Ok(T), + Error { error_message: String }, +} + +impl ResponseWrapper { + fn convert(self) -> Result { + match self { + ResponseWrapper::Ok(data) => Ok(data), + ResponseWrapper::Error { error_message } => { + if error_message.starts_with("No such ") || error_message.ends_with(" not found") { + Err(Error::NotFound(error_message.into())) + } else { + Err(Error::Bandcamp(error_message.into())) + } + } + } + } +} + impl Bandcamp { pub async fn band(&self, band_id: u64) -> Result { let req = BandRequest { band_id }; @@ -50,7 +72,7 @@ impl Bandcamp { .await? .error_for_status()?; - Ok(resp.json().await?) + resp.json::>().await?.convert() } /// Get a album (or a track) from the Bandcamp API @@ -79,7 +101,7 @@ impl Bandcamp { .await? .error_for_status()?; - Ok(resp.json().await?) + resp.json::>().await?.convert() } pub async fn album_uid>(&self, uid: S) -> Result { @@ -109,7 +131,11 @@ impl Bandcamp { .await? .error_for_status()?; - Ok(resp.json::().await?.auto) + Ok(resp + .json::>() + .await? + .convert()? + .auto) } pub async fn feed(&self) -> Result { @@ -123,7 +149,7 @@ impl Bandcamp { .await? .error_for_status()?; - Ok(resp.json().await?) + resp.json::>().await?.convert() } pub async fn feed_cont>(&self, token: S) -> Result { @@ -140,7 +166,7 @@ impl Bandcamp { .await? .error_for_status()?; - Ok(resp.json().await?) + resp.json::>().await?.convert() } pub async fn band_id_from_url(&self, url: U) -> Result {