rust subsonic client basics
This commit is contained in:
parent
0320e12206
commit
dee7c2e396
8 changed files with 1126 additions and 20 deletions
1033
Cargo.lock
generated
1033
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -5,8 +5,13 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
adw = { version = "0.7.0", package = "libadwaita", features = ["v1_6"] }
|
||||
async-channel = "2.3.1"
|
||||
gettext-rs = { version = "0.7.2", features = ["gettext-system"] }
|
||||
gtk = { version = "0.9.2", package = "gtk4", features = ["v4_16"] }
|
||||
reqwest = { version = "0.12.9", features = ["json"] }
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
serde_json = "1.0.132"
|
||||
tokio = { version = "1", features = ["rt-multi-thread"] }
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.70.1"
|
||||
|
|
|
@ -11,6 +11,7 @@ pub mod playbin;
|
|||
pub use playbin::Playbin;
|
||||
|
||||
pub mod subsonic;
|
||||
pub mod subsonic_vala;
|
||||
|
||||
use gettextrs::{bind_textdomain_codeset, bindtextdomain, setlocale, textdomain, LocaleCategory};
|
||||
use gtk::prelude::*;
|
||||
|
@ -25,6 +26,13 @@ pub mod mpv;
|
|||
#[link(name = "soup-3.0")]
|
||||
extern "C" {}
|
||||
|
||||
pub fn runtime() -> &'static tokio::runtime::Runtime {
|
||||
static RUNTIME: std::sync::OnceLock<tokio::runtime::Runtime> = std::sync::OnceLock::new();
|
||||
RUNTIME.get_or_init(|| {
|
||||
tokio::runtime::Runtime::new().expect("could not initialize the tokio runtime")
|
||||
})
|
||||
}
|
||||
|
||||
fn main() -> glib::ExitCode {
|
||||
gio::resources_register_include!("audrey.gresource").expect("could not register resources");
|
||||
|
||||
|
|
|
@ -1,5 +1,87 @@
|
|||
mod client;
|
||||
pub use client::Client;
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
// FIXME: can't even return url's ParseError directly.........
|
||||
UrlParseError(String),
|
||||
ReqwestError(reqwest::Error),
|
||||
SubsonicError(SubsonicError),
|
||||
}
|
||||
|
||||
mod song;
|
||||
pub use song::Song;
|
||||
impl From<reqwest::Error> for Error {
|
||||
fn from(err: reqwest::Error) -> Self {
|
||||
Self::ReqwestError(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct SubsonicError {
|
||||
pub code: u32,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct SubsonicResponse<T> {
|
||||
#[serde(rename = "subsonic-response")]
|
||||
inner: SubsonicResponseInner<T>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
#[serde(tag = "status")]
|
||||
pub enum SubsonicResponseInner<T> {
|
||||
#[serde(rename = "ok")]
|
||||
Ok(T),
|
||||
#[serde(rename = "failed")]
|
||||
Failed { error: SubsonicError },
|
||||
}
|
||||
|
||||
impl<T> SubsonicResponseInner<T> {
|
||||
fn fixup(self) -> Result<T, Error> {
|
||||
match self {
|
||||
Self::Ok(t) => Ok(t),
|
||||
Self::Failed { error } => Err(Error::SubsonicError(error)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Client {
|
||||
client: reqwest::Client,
|
||||
base_url: reqwest::Url,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn new(url: &str, username: &str, token: &str, salt: &str) -> Result<Self, Error> {
|
||||
Ok(Client {
|
||||
client: reqwest::Client::builder()
|
||||
.user_agent("audrey/linux") // Audrey.Const.user_agent
|
||||
.build()?,
|
||||
base_url: reqwest::Url::parse_with_params(
|
||||
url,
|
||||
&[
|
||||
("u", username),
|
||||
("t", token),
|
||||
("s", salt),
|
||||
("v", "1.16.1"),
|
||||
("c", "eu.callcc.audrey"),
|
||||
("f", "json"),
|
||||
],
|
||||
)
|
||||
.map_err(|err| Error::UrlParseError(err.to_string()))?,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn ping(&self) -> Result<(), Error> {
|
||||
let mut url = self.base_url.clone();
|
||||
url.path_segments_mut()
|
||||
.expect("can't modify url path segments")
|
||||
.extend(&["rest", "ping"]);
|
||||
|
||||
self.client
|
||||
.get(url)
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?
|
||||
.json::<SubsonicResponse<()>>()
|
||||
.await?
|
||||
.inner
|
||||
.fixup()
|
||||
}
|
||||
}
|
||||
|
|
5
src/subsonic_vala.rs
Normal file
5
src/subsonic_vala.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod client;
|
||||
pub use client::Client;
|
||||
|
||||
mod song;
|
||||
pub use song::Song;
|
|
@ -65,7 +65,10 @@ mod imp {
|
|||
|
||||
child.bind(
|
||||
item.position(),
|
||||
item.item().unwrap().downcast_ref::<crate::playbin::Song>().unwrap(),
|
||||
item.item()
|
||||
.unwrap()
|
||||
.downcast_ref::<crate::playbin::Song>()
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue