Structure
This commit is contained in:
parent
0024150376
commit
41fcffb43d
78
.gitignore
vendored
78
.gitignore
vendored
@ -1,3 +1,81 @@
|
||||
/target
|
||||
/navidrome/target
|
||||
/listenbrainz/target
|
||||
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
1719
Cargo.lock
generated
1719
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -10,5 +10,7 @@ axum = "0.6.20"
|
||||
tokio = "1.30.0"
|
||||
sqlx = "0.7.1"
|
||||
|
||||
|
||||
|
||||
[package.metadata.deb]
|
||||
depends = "$auto"
|
||||
|
104
navidrome/Cargo.lock
generated
104
navidrome/Cargo.lock
generated
@ -17,6 +17,32 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
@ -83,6 +109,22 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"time",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
@ -306,6 +348,29 @@ dependencies = [
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
@ -399,7 +464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
@ -425,10 +490,21 @@ dependencies = [
|
||||
name = "navidrome"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"reqwest",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.31.1"
|
||||
@ -729,6 +805,17 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
@ -862,6 +949,12 @@ dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
@ -966,6 +1059,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
@ -4,5 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
reqwest = "0.11.18"
|
||||
reqwest = { version = "0.11.18", features = ["json"] }
|
||||
serde = { version = "1.0.183", features = ["derive"] }
|
||||
chrono = { version = "0.4.26", features = ["serde"] }
|
||||
async-trait = "0.1.73"
|
||||
|
@ -0,0 +1,2 @@
|
||||
struct NavidromeBuilder {
|
||||
}
|
@ -1,13 +1,20 @@
|
||||
pub mod builder;
|
||||
pub mod playlists;
|
||||
|
||||
pub struct Client {
|
||||
trait QualifyPath {
|
||||
fn path(&self, path: &str) -> String;
|
||||
}
|
||||
|
||||
pub type MediaResult<U> = Result<U, reqwest::Error>;
|
||||
|
||||
pub struct Navidrome {
|
||||
base: String,
|
||||
http: reqwest::Client,
|
||||
token: String,
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Client {
|
||||
fn playlists() {
|
||||
const
|
||||
impl QualifyPath for Navidrome {
|
||||
fn path(&self, path: &str) -> String {
|
||||
format!("{}/{}", self.base, path)
|
||||
}
|
||||
}
|
||||
|
43
navidrome/src/client/playlists.rs
Normal file
43
navidrome/src/client/playlists.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::client::{MediaResult as Result, Navidrome, QualifyPath};
|
||||
use crate::models::generic::Playlist;
|
||||
use crate::models::navidrome::NavidromePlaylist;
|
||||
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 create_playlist(&self) -> Result<Playlist>;
|
||||
async fn delete_playlist(&self) -> Result<()>;
|
||||
async fn update_playlists(&self) -> Result<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Playlists for Navidrome {
|
||||
async fn playlists(&self) -> Result<Vec<Playlist>> {
|
||||
self.http
|
||||
.get(self.path("api/playlist"))
|
||||
.header("X-Nd-Authorization", format!("Bearer {}", self.token))
|
||||
.send()
|
||||
.await?
|
||||
.json::<Vec<NavidromePlaylist>>()
|
||||
.await
|
||||
.map(|pv| pv.iter().map(|p| p.into()).collect())
|
||||
}
|
||||
|
||||
async fn playlist(&self, id: String) -> Result<Playlist> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn create_playlist(&self) -> Result<Playlist> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn delete_playlist(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn update_playlists(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct LoginResponse {
|
||||
id: String, // todo should be a uuid
|
||||
#[serde(rename = "isAdmin")]
|
||||
is_admin: bool,
|
||||
name: String,
|
||||
#[serde(rename = "subsonicSalt")]
|
||||
subsonic_salt: String,
|
||||
#[serde(rename = "subsonicToken")]
|
||||
subsonic_token: String,
|
||||
token: String,
|
||||
username: String,
|
||||
}
|
9
navidrome/src/models/generic.rs
Normal file
9
navidrome/src/models/generic.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use chrono::NaiveDateTime;
|
||||
|
||||
pub struct Playlist {
|
||||
// items: dyn Iterator<Item = Song>,
|
||||
pub name: String,
|
||||
pub comment: Option<String>,
|
||||
pub created_at: Option<NaiveDateTime>,
|
||||
pub file: Option<String>,
|
||||
}
|
2
navidrome/src/models/mod.rs
Normal file
2
navidrome/src/models/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod generic;
|
||||
pub mod navidrome;
|
58
navidrome/src/models/navidrome.rs
Normal file
58
navidrome/src/models/navidrome.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use crate::models::generic::Playlist;
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::Deserialize;
|
||||
use std::iter::Iterator;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct LoginResponse {
|
||||
id: String, // todo should be a uuid
|
||||
#[serde(rename = "isAdmin")]
|
||||
is_admin: bool,
|
||||
name: String,
|
||||
#[serde(rename = "subsonicSalt")]
|
||||
subsonic_salt: String,
|
||||
#[serde(rename = "subsonicToken")]
|
||||
subsonic_token: String,
|
||||
token: String,
|
||||
username: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct NavidromePlaylist {
|
||||
name: String,
|
||||
comment: String,
|
||||
#[serde(rename = "createdAt")]
|
||||
created_at: NaiveDateTime,
|
||||
path: String,
|
||||
public: bool,
|
||||
size: u64,
|
||||
duration: f64,
|
||||
#[serde(rename = "evaluatedAt")]
|
||||
evaluated_at: NaiveDateTime,
|
||||
id: String,
|
||||
#[serde(rename = "ownerId")]
|
||||
owner_id: String,
|
||||
#[serde(rename = "ownerName")]
|
||||
owner_name: String,
|
||||
#[serde(skip)] // todo fix
|
||||
rules: Option<NavidromePlaylistRule>,
|
||||
#[serde(rename = "songCount")]
|
||||
song_count: u64,
|
||||
sync: bool,
|
||||
#[serde(rename = "updatedAt")]
|
||||
updated_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
impl From<&NavidromePlaylist> for Playlist {
|
||||
fn from(value: &NavidromePlaylist) -> Self {
|
||||
Playlist {
|
||||
name: value.name.clone(),
|
||||
comment: Some(value.comment.clone()),
|
||||
created_at: Some(value.created_at),
|
||||
file: Some(value.path.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct NavidromePlaylistRule {}
|
Loading…
Reference in New Issue
Block a user