cover art api
This commit is contained in:
parent
e52adda2ed
commit
2b9b6ee6c7
3 changed files with 46 additions and 55 deletions
|
@ -27,8 +27,6 @@ mod imp {
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
track: Cell<i64>,
|
track: Cell<i64>,
|
||||||
|
|
||||||
#[property(get, set)]
|
|
||||||
cover_art_url: RefCell<String>,
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
stream_url: RefCell<String>,
|
stream_url: RefCell<String>,
|
||||||
|
|
||||||
|
@ -83,8 +81,7 @@ impl Song {
|
||||||
.property("album", &song.album)
|
.property("album", &song.album)
|
||||||
.property("genre", &song.genre)
|
.property("genre", &song.genre)
|
||||||
.property("duration", song.duration as i64)
|
.property("duration", song.duration as i64)
|
||||||
//.property("track", song.track)
|
.property("track", song.track.map(i64::from).unwrap_or(-1))
|
||||||
.property("cover-art-url", api.cover_art_url(&song.id, 0).as_str())
|
|
||||||
.property("stream-url", api.stream_url(&song.id).as_str())
|
.property("stream-url", api.stream_url(&song.id).as_str())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -96,7 +93,7 @@ impl Song {
|
||||||
.thumbnail_loading
|
.thumbnail_loading
|
||||||
.replace(Some(glib::spawn_future_local(async move {
|
.replace(Some(glib::spawn_future_local(async move {
|
||||||
let bytes = api
|
let bytes = api
|
||||||
.cover_art(&id, 50) // TODO: constify thumbnail size, maybe take dpi into account etc
|
.cover_art(&id, Some(50)) // TODO: WidgetExt::scale_factor
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let song = match song_weak.upgrade() {
|
let song = match song_weak.upgrade() {
|
||||||
|
|
|
@ -153,10 +153,51 @@ impl Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_bytes(&self, request: reqwest::RequestBuilder) -> Result<Bytes, Error> {
|
fn url(&self, path: &[&str], query: &[(&str, &str)]) -> url::Url {
|
||||||
|
let mut url = self.base_url.clone();
|
||||||
|
url.path_segments_mut()
|
||||||
|
// literally can't fail
|
||||||
|
.unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() })
|
||||||
|
.extend(path);
|
||||||
|
url.query_pairs_mut().extend_pairs(query);
|
||||||
|
url
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get<T: serde::de::DeserializeOwned + Send + 'static>(
|
||||||
|
&self,
|
||||||
|
path: &[&str],
|
||||||
|
query: &[(&str, &str)],
|
||||||
|
) -> Result<T, Error> {
|
||||||
|
self.send(self.client.get(self.url(path, query))).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn ping(&self) -> Result<(), Error> {
|
||||||
|
self.get(&["rest", "ping"], &[]).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_random_songs(&self, size: u32) -> Result<Vec<schema::Child>, Error> {
|
||||||
|
self.get::<schema::RandomSongsOuter>(
|
||||||
|
&["rest", "getRandomSongs"],
|
||||||
|
&[("size", &size.to_string())],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|response| response.random_songs.song)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cover_art_url(&self, id: &str, size: Option<u32>) -> url::Url {
|
||||||
|
match size {
|
||||||
|
None => self.url(&["rest", "getCoverArt"], &[("id", id)]),
|
||||||
|
Some(size) => self.url(
|
||||||
|
&["rest", "getCoverArt"],
|
||||||
|
&[("id", id), ("size", &size.to_string())],
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn cover_art(&self, id: &str, size: Option<u32>) -> Result<Bytes, Error> {
|
||||||
let (sender, receiver) = async_channel::bounded(1);
|
let (sender, receiver) = async_channel::bounded(1);
|
||||||
|
|
||||||
let future = request.send();
|
let future = self.client.get(self.cover_art_url(id, size)).send();
|
||||||
runtime().spawn(async move {
|
runtime().spawn(async move {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
response: Result<reqwest::Response, reqwest::Error>,
|
response: Result<reqwest::Response, reqwest::Error>,
|
||||||
|
@ -197,53 +238,6 @@ impl Client {
|
||||||
.expect("could not receive cover art bytes from tokio")
|
.expect("could not receive cover art bytes from tokio")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn url(&self, path: &[&str], query: &[(&str, &str)]) -> url::Url {
|
|
||||||
let mut url = self.base_url.clone();
|
|
||||||
url.path_segments_mut()
|
|
||||||
// literally can't fail
|
|
||||||
.unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() })
|
|
||||||
.extend(path);
|
|
||||||
url.query_pairs_mut().extend_pairs(query);
|
|
||||||
url
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get<T: serde::de::DeserializeOwned + Send + 'static>(
|
|
||||||
&self,
|
|
||||||
path: &[&str],
|
|
||||||
query: &[(&str, &str)],
|
|
||||||
) -> Result<T, Error> {
|
|
||||||
self.send(self.client.get(self.url(path, query))).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn ping(&self) -> Result<(), Error> {
|
|
||||||
self.get(&["rest", "ping"], &[]).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_random_songs(&self, size: u32) -> Result<Vec<schema::Child>, Error> {
|
|
||||||
self.get::<schema::RandomSongsOuter>(
|
|
||||||
&["rest", "getRandomSongs"],
|
|
||||||
&[("size", &size.to_string())],
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|response| response.random_songs.song)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cover_art_url(&self, id: &str, size: u32) -> url::Url {
|
|
||||||
if size == 0 {
|
|
||||||
self.url(&["rest", "getCoverArt"], &[("id", id)])
|
|
||||||
} else {
|
|
||||||
self.url(
|
|
||||||
&["rest", "getCoverArt"],
|
|
||||||
&[("id", id), ("size", &size.to_string())],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn cover_art(&self, id: &str, size: u32) -> Result<Bytes, Error> {
|
|
||||||
self.send_bytes(self.client.get(self.cover_art_url(id, size)))
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stream_url(&self, id: &str) -> url::Url {
|
pub fn stream_url(&self, id: &str) -> url::Url {
|
||||||
self.url(&["rest", "stream"], &[("id", id)])
|
self.url(&["rest", "stream"], &[("id", id)])
|
||||||
}
|
}
|
||||||
|
|
|
@ -482,7 +482,7 @@ mod imp {
|
||||||
.replace(Some(glib::spawn_future_local(async move {
|
.replace(Some(glib::spawn_future_local(async move {
|
||||||
let api = window.imp().api.borrow().as_ref().unwrap().clone();
|
let api = window.imp().api.borrow().as_ref().unwrap().clone();
|
||||||
let bytes = api
|
let bytes = api
|
||||||
.cover_art(&song_id, 0) // 0: full size
|
.cover_art(&song_id, None) // full size
|
||||||
.await
|
.await
|
||||||
.expect("could not load cover art for song {song_id}");
|
.expect("could not load cover art for song {song_id}");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue