Track media server songs list

This commit is contained in:
jude
2023-09-09 20:03:01 +01:00
parent d217dd0b81
commit 9c689d73d6
16 changed files with 361 additions and 25 deletions

View File

@ -1,2 +1,59 @@
struct NavidromeBuilder {
use crate::client::Navidrome;
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
pub struct NavidromeBuilder {
base: Option<String>,
token: Option<String>,
}
#[derive(Debug)]
pub enum NavidromeBuilderError {
MissingParam,
Reqwest(reqwest::Error),
}
impl Display for NavidromeBuilderError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
impl Error for NavidromeBuilderError {}
impl NavidromeBuilder {
pub fn new() -> NavidromeBuilder {
return NavidromeBuilder {
base: None,
token: None,
};
}
pub fn base(&mut self, base: impl ToString) -> &mut NavidromeBuilder {
self.base = Some(base.to_string());
return self;
}
pub fn token(&mut self, token: impl ToString) -> &mut NavidromeBuilder {
self.token = Some(token.to_string());
return self;
}
pub fn build(&self) -> Result<Navidrome, NavidromeBuilderError> {
let client = reqwest::ClientBuilder::new()
.build()
.map_err(|e| NavidromeBuilderError::Reqwest(e))?;
return Ok(Navidrome {
base: self
.base
.clone()
.ok_or(NavidromeBuilderError::MissingParam)?,
http: client,
token: self
.token
.clone()
.ok_or(NavidromeBuilderError::MissingParam)?,
});
}
}

View File

@ -0,0 +1,22 @@
use crate::client::{MediaResult as Result, Navidrome, QualifyPath};
use crate::models::generic::Playlist;
use crate::models::navidrome::{NavidromePlaylist, NavidromeTrack};
use async_trait::async_trait;
#[async_trait]
pub trait Library {
async fn tracks(&self) -> Result<Vec<NavidromeTrack>>;
}
#[async_trait]
impl Library for Navidrome {
async fn tracks(&self) -> Result<Vec<NavidromeTrack>> {
self.http
.get(self.path("api/song"))
.header("X-Nd-Authorization", format!("Bearer {}", self.token))
.send()
.await?
.json::<Vec<NavidromeTrack>>()
.await
}
}

View File

@ -1,8 +1,11 @@
use std::fmt::Display;
pub mod builder;
pub mod library;
pub mod playlists;
trait QualifyPath {
fn path(&self, path: &str) -> String;
fn path(&self, path: impl Display) -> String;
}
pub type MediaResult<U> = Result<U, reqwest::Error>;
@ -14,7 +17,7 @@ pub struct Navidrome {
}
impl QualifyPath for Navidrome {
fn path(&self, path: &str) -> String {
fn path(&self, path: impl Display) -> String {
format!("{}/{}", self.base, path)
}
}

View File

@ -1,12 +1,13 @@
use crate::client::{MediaResult as Result, Navidrome, QualifyPath};
use crate::models::generic::Playlist;
use crate::models::navidrome::NavidromePlaylist;
use crate::models::navidrome::{NavidromePlaylist, NavidromeTrack};
use async_trait::async_trait;
#[async_trait]
pub trait Playlists {
async fn playlists(&self) -> Result<Vec<Playlist>>;
async fn playlist(&self, id: String) -> Result<Playlist>;
async fn tracks(&self, id: String) -> Result<Vec<NavidromeTrack>>;
async fn create_playlist(&self) -> Result<Playlist>;
async fn delete_playlist(&self) -> Result<()>;
async fn update_playlists(&self) -> Result<()>;
@ -26,7 +27,24 @@ impl Playlists for Navidrome {
}
async fn playlist(&self, id: String) -> Result<Playlist> {
todo!()
self.http
.get(self.path(format!("api/playlist/{}", id)))
.header("X-Nd-Authorization", format!("Bearer {}", self.token))
.send()
.await?
.json::<NavidromePlaylist>()
.await
.map(|pv| (&pv).into())
}
async fn tracks(&self, id: String) -> Result<Vec<NavidromeTrack>> {
self.http
.get(self.path(format!("api/playlist/{}/tracks", id)))
.header("X-Nd-Authorization", format!("Bearer {}", self.token))
.send()
.await?
.json::<Vec<NavidromeTrack>>()
.await
}
async fn create_playlist(&self) -> Result<Playlist> {

View File

@ -1,7 +1,6 @@
use crate::models::generic::Playlist;
use chrono::NaiveDateTime;
use serde::Deserialize;
use std::iter::Iterator;
#[derive(Deserialize)]
struct LoginResponse {
@ -34,8 +33,6 @@ pub(crate) struct NavidromePlaylist {
owner_id: String,
#[serde(rename = "ownerName")]
owner_name: String,
#[serde(skip)] // todo fix
rules: Option<NavidromePlaylistRule>,
#[serde(rename = "songCount")]
song_count: u64,
sync: bool,
@ -54,5 +51,20 @@ impl From<&NavidromePlaylist> for Playlist {
}
}
#[derive(Deserialize)]
struct NavidromePlaylistRule {}
#[derive(Deserialize, Clone)]
pub struct NavidromeTrack {
title: String,
artist: String,
#[serde(rename = "albumArtist")]
album_artist: String,
album: String,
#[serde(rename = "albumId")]
album_id: String,
#[serde(rename = "artistId")]
artist_id: String,
id: String,
#[serde(rename = "mbzTrackId")]
pub musicbrainz_track_id: Option<String>,
#[serde(rename = "mbzReleaseTrackId")]
musicbrainz_release_track_id: Option<String>,
}