Compare commits
2 commits
b2a72dd067
...
b3bf3f62a7
Author | SHA1 | Date | |
---|---|---|---|
b3bf3f62a7 | |||
0c4ab0a01d |
6 changed files with 110 additions and 5 deletions
|
@ -2,6 +2,7 @@
|
|||
name = "codegen"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
reqwest = "0.11.11"
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -64,6 +64,13 @@ pub struct Track {
|
|||
pub band_name: Option<String>,
|
||||
/// 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<String, String>,
|
||||
pub track_num: u16,
|
||||
}
|
||||
|
|
|
@ -38,6 +38,28 @@ struct SearchResultWrapper {
|
|||
auto: SearchResult,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum ResponseWrapper<T> {
|
||||
Ok(T),
|
||||
Error { error_message: String },
|
||||
}
|
||||
|
||||
impl<T> ResponseWrapper<T> {
|
||||
fn convert(self) -> Result<T> {
|
||||
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<Band> {
|
||||
let req = BandRequest { band_id };
|
||||
|
@ -50,9 +72,15 @@ impl Bandcamp {
|
|||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json().await?)
|
||||
resp.json::<ResponseWrapper<Band>>().await?.convert()
|
||||
}
|
||||
|
||||
/// 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,
|
||||
|
@ -73,7 +101,7 @@ impl Bandcamp {
|
|||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json().await?)
|
||||
resp.json::<ResponseWrapper<Album>>().await?.convert()
|
||||
}
|
||||
|
||||
pub async fn album_uid<S: AsRef<str>>(&self, uid: S) -> Result<Album> {
|
||||
|
@ -103,7 +131,11 @@ impl Bandcamp {
|
|||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json::<SearchResultWrapper>().await?.auto)
|
||||
Ok(resp
|
||||
.json::<ResponseWrapper<SearchResultWrapper>>()
|
||||
.await?
|
||||
.convert()?
|
||||
.auto)
|
||||
}
|
||||
|
||||
pub async fn feed(&self) -> Result<Feed> {
|
||||
|
@ -117,7 +149,7 @@ impl Bandcamp {
|
|||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json().await?)
|
||||
resp.json::<ResponseWrapper<Feed>>().await?.convert()
|
||||
}
|
||||
|
||||
pub async fn feed_cont<S: AsRef<str>>(&self, token: S) -> Result<Feed> {
|
||||
|
@ -134,7 +166,7 @@ impl Bandcamp {
|
|||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json().await?)
|
||||
resp.json::<ResponseWrapper<Feed>>().await?.convert()
|
||||
}
|
||||
|
||||
pub async fn band_id_from_url<U: IntoUrl>(&self, url: U) -> Result<u64> {
|
||||
|
|
44
tests/snapshots/tests__album_track.snap
Normal file
44
tests/snapshots/tests__album_track.snap
Normal file
|
@ -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,
|
||||
),
|
||||
],
|
||||
)
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue