Structure
This commit is contained in:
parent
0024150376
commit
41fcffb43d
78
.gitignore
vendored
78
.gitignore
vendored
@ -1,3 +1,81 @@
|
|||||||
/target
|
/target
|
||||||
/navidrome/target
|
/navidrome/target
|
||||||
/listenbrainz/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"
|
tokio = "1.30.0"
|
||||||
sqlx = "0.7.1"
|
sqlx = "0.7.1"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[package.metadata.deb]
|
[package.metadata.deb]
|
||||||
depends = "$auto"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
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]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -83,6 +109,22 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
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]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
@ -306,6 +348,29 @@ dependencies = [
|
|||||||
"tokio-native-tls",
|
"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]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -399,7 +464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -425,10 +490,21 @@ dependencies = [
|
|||||||
name = "navidrome"
|
name = "navidrome"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"chrono",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.31.1"
|
version = "0.31.1"
|
||||||
@ -729,6 +805,17 @@ dependencies = [
|
|||||||
"windows-sys",
|
"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]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
@ -862,6 +949,12 @@ dependencies = [
|
|||||||
"try-lock",
|
"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]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
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]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
@ -4,5 +4,7 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = "0.11.18"
|
reqwest = { version = "0.11.18", features = ["json"] }
|
||||||
serde = { version = "1.0.183", features = ["derive"] }
|
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,
|
base: String,
|
||||||
http: reqwest::Client,
|
http: reqwest::Client,
|
||||||
|
token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl QualifyPath for Navidrome {
|
||||||
|
fn path(&self, path: &str) -> String {
|
||||||
impl Client {
|
format!("{}/{}", self.base, path)
|
||||||
fn playlists() {
|
|
||||||
const
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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