Add cargo-server with liby service draft
It is not smart, fetches everything all the time and totally hardcoded with the tidal client But tidal login and library discovery with tidal should somewhat work.
This commit is contained in:
parent
b5f722f1cb
commit
0af8829987
|
|
@ -46,6 +46,12 @@ dependencies = [
|
|||
"syn 2.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic_refcell"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79d6dc922a2792b006573f60b2648076355daeae5ce9cb59507e5908c9625d31"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
|
|
@ -160,6 +166,16 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8790cf1286da485c72cf5fc7aeba308438800036ec67d89425924c4807268c9"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
|
@ -273,6 +289,24 @@ dependencies = [
|
|||
"tonic-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crabidy-server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"crabidy-core",
|
||||
"flume",
|
||||
"gstreamer",
|
||||
"gstreamer-play",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tidaldy",
|
||||
"tokio",
|
||||
"tonic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.26.1"
|
||||
|
|
@ -504,6 +538,28 @@ version = "0.3.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.28"
|
||||
|
|
@ -523,9 +579,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -551,6 +609,78 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.17.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b1d43b0d7968b48455244ecafe41192871257f5740aa6b095eb19db78e362a5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.17.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7f1de7cbde31ea4f0a919453a2dcece5d54d5b70e08f8ad254dc4840f5f09b6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"gio-sys",
|
||||
"glib-macros",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.17.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a7206c5c03851ef126ea1444990e81fdd6765fb799d5bc694e4897ca01bb97f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck 0.4.1",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.17.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f00ad0a1bf548e61adfff15d83430941d9e1bb620e334f779edd1c745680a5"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.17.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15e75b0000a64632b2d8ca3cf856af9308e3a970844f6e9659bd197f026793d0"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphql-parser"
|
||||
version = "0.4.0"
|
||||
|
|
@ -561,6 +691,131 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer"
|
||||
version = "0.20.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4530401c89be6dc10d77ae1587b811cf455c97dce7abf594cb9164527c7da7fc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"glib",
|
||||
"gstreamer-sys",
|
||||
"libc",
|
||||
"muldiv",
|
||||
"num-integer",
|
||||
"num-rational",
|
||||
"once_cell",
|
||||
"option-operations",
|
||||
"paste",
|
||||
"pretty-hex",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-base"
|
||||
version = "0.20.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b8ff5dfbf7bcaf1466a385b836bad0d8da25759f121458727fdda1f771c69b3"
|
||||
dependencies = [
|
||||
"atomic_refcell",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"glib",
|
||||
"gstreamer",
|
||||
"gstreamer-base-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-base-sys"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26114ed96f6668380f5a1554128159e98e06c3a7a8460f216d7cd6dce28f928c"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gstreamer-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-play"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f752a53171e330c7f56db24ca91d99b7958dc86395ebe91b117226d339b29306"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"glib",
|
||||
"gstreamer",
|
||||
"gstreamer-play-sys",
|
||||
"gstreamer-video",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-play-sys"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b69030bd53c3e5988a1e13bdb55ae8d922f8e9c2b522bfa2442bc13906829fb"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gstreamer-sys",
|
||||
"gstreamer-video-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-sys"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e56fe047adef7d47dbafa8bc1340fddb53c325e16574763063702fc94b5786d2"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-video"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce97769effde2d779dc4f7037b37106457b74e53f2a711bddc90b30ffeb7e06"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"futures-channel",
|
||||
"glib",
|
||||
"gstreamer",
|
||||
"gstreamer-base",
|
||||
"gstreamer-video-sys",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-video-sys"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66ddb6112d438aac0004d2db6053a572f92b1c5e0e9d6ff6c71d9245f7f73e46"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gstreamer-base-sys",
|
||||
"gstreamer-sys",
|
||||
"libc",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.19"
|
||||
|
|
@ -876,6 +1131,12 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "muldiv"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "956787520e75e9bd233246045d19f42fb73242759cc57fba9611d940ae96d4b0"
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
version = "0.8.3"
|
||||
|
|
@ -919,6 +1180,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
|
|
@ -988,6 +1260,15 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "option-operations"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c26d27bb1aeab65138e4bf7666045169d1717febcc9ff870166be8348b223d0"
|
||||
dependencies = [
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ouroboros"
|
||||
version = "0.15.6"
|
||||
|
|
@ -1034,6 +1315,12 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
|
|
@ -1138,6 +1425,12 @@ version = "0.2.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "pretty-hex"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6fa0831dd7cc608c38a5e323422a0077678fa5744aa2be4ad91c4ece8eec8d5"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.1.25"
|
||||
|
|
@ -1148,6 +1441,16 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
|
|
@ -1665,6 +1968,25 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "6.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5fa6fb9ee296c0dc2df41a656ca7948546d061958115ddb0bcaae43ad0d17d2"
|
||||
dependencies = [
|
||||
"cfg-expr",
|
||||
"heck 0.4.1",
|
||||
"pkg-config",
|
||||
"toml 0.7.4",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.5.0"
|
||||
|
|
@ -2055,6 +2377,12 @@ version = "0.2.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
[workspace]
|
||||
members = ["crabidy-core", "crabidy", "cbd-tui", "tidaldy"]
|
||||
members = ["cbd-tui", "crabidy-core", "crabidy-server", "crabidy", "tidaldy"]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "crabidy-server"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.71"
|
||||
gstreamer = "0.20.5"
|
||||
gstreamer-play = "0.20.2"
|
||||
tokio = { version = "1.28.0", features = ["full"] }
|
||||
tidaldy = { path = "../tidaldy" }
|
||||
crabidy-core = { path = "../crabidy-core" }
|
||||
once_cell = "1.17.1"
|
||||
serde_json = "1.0.96"
|
||||
serde = "1.0.163"
|
||||
flume = "0.10.14"
|
||||
tonic = "0.9.2"
|
||||
async-trait = "0.1.68"
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
use anyhow::{Error, Result};
|
||||
use async_trait::async_trait;
|
||||
use crabidy_core::proto::crabidy::{
|
||||
library_service_server::{LibraryService, LibraryServiceServer},
|
||||
playback_server::{Playback, PlaybackServer},
|
||||
queue_server::{Queue, QueueServer},
|
||||
GetLibraryNodeRequest, GetLibraryNodeResponse, GetTrackRequest, GetTrackResponse, LibraryNode,
|
||||
LibraryNodeState,
|
||||
};
|
||||
use crabidy_core::{ProviderClient, ProviderError};
|
||||
use gstreamer_play::{Play, PlayMessage, PlayState, PlayVideoRenderer};
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use tonic::{transport::Server, Request, Response, Status};
|
||||
|
||||
// static CHANNEL: OnceCell<flume::Sender<Input>> = OnceCell::new();
|
||||
static ORCHESTRATOR_CHANNEL: OnceCell<flume::Sender<OrchestratorMessage>> = OnceCell::new();
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let orchestrator = ClientOrchestrator::init("").await.unwrap();
|
||||
orchestrator.run();
|
||||
let addr = "[::1]:50051".parse()?;
|
||||
let crabidy_service = Library::new();
|
||||
|
||||
Server::builder()
|
||||
.add_service(LibraryServiceServer::new(crabidy_service))
|
||||
.serve(addr)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
enum OrchestratorMessage {
|
||||
GetNode {
|
||||
uuid: String,
|
||||
callback: flume::Sender<LibraryNode>,
|
||||
},
|
||||
GetTracksPlaybackUrls {
|
||||
uuid: String,
|
||||
callback: flume::Sender<Vec<String>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ClientOrchestrator {
|
||||
rx: flume::Receiver<OrchestratorMessage>,
|
||||
tidal_client: tidaldy::Client,
|
||||
}
|
||||
|
||||
impl ClientOrchestrator {
|
||||
fn run(self) {
|
||||
tokio::spawn(async move {
|
||||
while let Ok(msg) = self.rx.recv_async().await {
|
||||
match msg {
|
||||
OrchestratorMessage::GetNode { uuid, callback } => {
|
||||
let node = match uuid.as_str() {
|
||||
"/" => self.get_library_root(),
|
||||
_ => self.get_library_node(&uuid).await.unwrap(),
|
||||
};
|
||||
callback.send_async(node).await;
|
||||
}
|
||||
OrchestratorMessage::GetTracksPlaybackUrls { uuid, callback } => {
|
||||
let urls = self.get_urls_for_track(&uuid).await.unwrap();
|
||||
callback.send_async(urls).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ProviderClient for ClientOrchestrator {
|
||||
async fn init(_s: &str) -> Result<Self, ProviderError> {
|
||||
let raw_toml_settings = fs::read_to_string("/tmp/tidaldy.toml").unwrap_or("".to_owned());
|
||||
let tidal_client = tidaldy::Client::init(&raw_toml_settings).await.unwrap();
|
||||
let new_toml_config = tidal_client.settings();
|
||||
fs::write("/tmp/tidaldy.toml", new_toml_config).unwrap();
|
||||
let (tx, rx) = flume::unbounded();
|
||||
ORCHESTRATOR_CHANNEL.set(tx).unwrap();
|
||||
Ok(Self { rx, tidal_client })
|
||||
}
|
||||
fn settings(&self) -> String {
|
||||
"".to_owned()
|
||||
}
|
||||
async fn get_urls_for_track(&self, track_uuid: &str) -> Result<Vec<String>, ProviderError> {
|
||||
self.tidal_client.get_urls_for_track(track_uuid).await
|
||||
}
|
||||
fn get_library_root(&self) -> LibraryNode {
|
||||
let mut root_node = LibraryNode::new();
|
||||
root_node.children.push("tidal".to_owned());
|
||||
root_node
|
||||
}
|
||||
async fn get_library_node(&self, uuid: &str) -> Result<LibraryNode, ProviderError> {
|
||||
if uuid == "tidal" {
|
||||
return Ok(self.tidal_client.get_library_root());
|
||||
}
|
||||
self.tidal_client.get_library_node(uuid).await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Library {
|
||||
known_nodes: RwLock<HashMap<String, LibraryNode>>,
|
||||
clients: Arc<HashMap<String, Box<dyn ProviderClient>>>,
|
||||
}
|
||||
|
||||
impl Library {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
known_nodes: RwLock::new(HashMap::new()),
|
||||
clients: Arc::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl LibraryService for Library {
|
||||
async fn get_library_node(
|
||||
&self,
|
||||
request: Request<GetLibraryNodeRequest>,
|
||||
) -> Result<Response<GetLibraryNodeResponse>, Status> {
|
||||
println!("Got a library node request: {:?}", request);
|
||||
let node_uuid = request.into_inner().uuid;
|
||||
let (tx, rx) = flume::bounded(1);
|
||||
ORCHESTRATOR_CHANNEL
|
||||
.wait()
|
||||
.send_async(OrchestratorMessage::GetNode {
|
||||
uuid: node_uuid,
|
||||
callback: tx,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let node = rx.recv_async().await.unwrap();
|
||||
let resp = GetLibraryNodeResponse { node: Some(node) };
|
||||
Ok(Response::new(resp))
|
||||
}
|
||||
async fn get_track(
|
||||
&self,
|
||||
request: Request<GetTrackRequest>,
|
||||
) -> Result<Response<GetTrackResponse>, Status> {
|
||||
println!("Got a track request: {:?}", request);
|
||||
|
||||
let req = request.into_inner();
|
||||
|
||||
let reply = GetTrackResponse { track: None };
|
||||
Ok(Response::new(reply))
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Debug)]
|
||||
// enum Input {
|
||||
// PlayTrack {
|
||||
// track_id: String,
|
||||
// },
|
||||
// StopTrack {
|
||||
// track_id: String,
|
||||
// },
|
||||
// GetTrack {
|
||||
// track_id: String,
|
||||
// response: tokio::sync::oneshot::Sender<tidaldy::Track>,
|
||||
// },
|
||||
// GetPlaylistList {
|
||||
// response: tokio::sync::oneshot::Sender<Vec<tidaldy::PlaylistAndFavorite>>,
|
||||
// },
|
||||
// TrackOver,
|
||||
// }
|
||||
|
||||
// async fn run() -> Result<(), Error> {
|
||||
// gstreamer::init().unwrap();
|
||||
|
||||
// let play = Play::new(None::<PlayVideoRenderer>);
|
||||
// let bus = play.message_bus();
|
||||
// let (tx, rx) = flume::bounded(64);
|
||||
// let bus_tx = tx.clone();
|
||||
// bus.set_sync_handler(move |_, msg| {
|
||||
// match PlayMessage::parse(msg) {
|
||||
// Ok(PlayMessage::EndOfStream) => {}
|
||||
// Ok(PlayMessage::StateChanged { state }) => {
|
||||
// println!("State changed: {:?}", state);
|
||||
// }
|
||||
// Ok(PlayMessage::PositionUpdated { position }) => {
|
||||
// println!("Position updated: {:?}", position);
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// gstreamer::BusSyncReply::Drop
|
||||
// });
|
||||
// let mut state = PlayState::Stopped;
|
||||
// CHANNEL.set(tx).unwrap();
|
||||
|
||||
// while let Ok(input) = rx.recv_async().await {
|
||||
// match (&mut state, input) {
|
||||
// (_, Input::TrackOver) => {
|
||||
// state = PlayState::Stopped;
|
||||
// println!("Track stopped");
|
||||
// }
|
||||
// (_, Input::StopTrack { track_id }) => {
|
||||
// println!("Stopping track {}", track_id);
|
||||
// play.stop();
|
||||
// state = PlayState::Stopped;
|
||||
// }
|
||||
// (_, Input::GetTrack { track_id, response }) => {
|
||||
// let track = client.get_track(track_id).await.unwrap();
|
||||
// response.send(track).unwrap();
|
||||
// }
|
||||
// (_, Input::GetPlaylistList { response }) => {
|
||||
// println!("Getting playlists");
|
||||
// let user_id = client.get_user_id().unwrap();
|
||||
// println!("Getting playlists for user {}", user_id);
|
||||
// let list = client
|
||||
// .get_users_playlists_and_favorite_playlists(&user_id)
|
||||
// .await
|
||||
// .unwrap();
|
||||
// response.send(list).unwrap();
|
||||
// }
|
||||
// (PlayState::Stopped, Input::PlayTrack { track_id }) => {
|
||||
// println!("Playing track {}", track_id);
|
||||
// let track_playback = client.get_track_playback(&track_id).await.unwrap();
|
||||
// let manifest = track_playback.get_manifest().unwrap();
|
||||
// play.set_uri(Some(&manifest.urls[0]));
|
||||
// play.play();
|
||||
// state = PlayState::Playing;
|
||||
// }
|
||||
// (PlayState::Paused, Input::PlayTrack { track_id }) => {
|
||||
// println!("Unpausing track {}", track_id);
|
||||
// play.play();
|
||||
// state = PlayState::Playing;
|
||||
// }
|
||||
// (PlayState::Playing, Input::PlayTrack { track_id }) => {
|
||||
// println!("Pausing track {}", track_id);
|
||||
// play.pause();
|
||||
// state = PlayState::Paused;
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// }
|
||||
// print!("done");
|
||||
// Ok(())
|
||||
// }
|
||||
|
|
@ -81,7 +81,7 @@ impl crabidy_core::ProviderClient for Client {
|
|||
let mut node = crabidy_core::proto::crabidy::LibraryNode {
|
||||
uuid: "userplaylists".to_string(),
|
||||
name: "playlists".to_string(),
|
||||
parent: Some(format!("{}", global_root.uuid)),
|
||||
parent: Some("tidal".to_string()),
|
||||
state: crabidy_core::proto::crabidy::LibraryNodeState::Unspecified as i32,
|
||||
tracks: Vec::new(),
|
||||
children: Vec::new(),
|
||||
|
|
@ -91,7 +91,8 @@ impl crabidy_core::ProviderClient for Client {
|
|||
.get_users_playlists_and_favorite_playlists(&user_id)
|
||||
.await?
|
||||
{
|
||||
node.children.push(playlist.playlist.uuid);
|
||||
node.children
|
||||
.push(format!("playlist:{}", playlist.playlist.uuid));
|
||||
}
|
||||
node
|
||||
}
|
||||
|
|
@ -117,8 +118,8 @@ impl crabidy_core::ProviderClient for Client {
|
|||
fn split_uuid(uuid: &str) -> (String, String) {
|
||||
let mut split = uuid.splitn(2, ':');
|
||||
(
|
||||
split.next().unwrap().to_string(),
|
||||
split.next().unwrap().to_string(),
|
||||
split.next().unwrap_or("").to_string(),
|
||||
split.next().unwrap_or("").to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -360,10 +361,11 @@ impl Client {
|
|||
pub async fn login_web(&mut self) -> Result<(), ClientError> {
|
||||
let code_response = self.get_device_code().await?;
|
||||
let now = Instant::now();
|
||||
println!("{}", code_response.verification_uri_complete);
|
||||
println!("https://{}", code_response.verification_uri_complete);
|
||||
while now.elapsed().as_secs() <= code_response.expires_in {
|
||||
let login = self.check_auth_status(&code_response.device_code).await;
|
||||
if login.is_err() {
|
||||
// println!("login failed with {:?}", login);
|
||||
sleep(Duration::from_secs(code_response.interval)).await;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -374,7 +376,7 @@ impl Client {
|
|||
self.settings.login.access_token = Some(login_results.access_token);
|
||||
self.settings.login.refresh_token = login_results.refresh_token;
|
||||
self.settings.login.expires_after = Some(login_results.expires_in + timestamp);
|
||||
self.settings.login.user_id = Some(login_results.user.user_id);
|
||||
self.settings.login.user_id = Some(login_results.user.user_id.to_string());
|
||||
self.settings.login.country_code = Some(login_results.user.country_code);
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -493,6 +495,7 @@ impl Client {
|
|||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.send()
|
||||
.await?;
|
||||
// println!("{:#?} -> {}", res.status(), res.status().is_success());
|
||||
if !res.status().is_success() {
|
||||
if res.status().is_client_error() {
|
||||
return Err(ClientError::AuthError(format!(
|
||||
|
|
|
|||
|
|
@ -4,12 +4,6 @@ use serde::{Deserialize, Serialize};
|
|||
use serde_json::Value;
|
||||
use thiserror::Error;
|
||||
|
||||
pub trait Paginated {
|
||||
fn offset(&self) -> usize;
|
||||
fn limit(&self) -> usize;
|
||||
fn total(&self) -> usize;
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Page<T> {
|
||||
|
|
@ -19,27 +13,6 @@ pub struct Page<T> {
|
|||
pub items: Vec<T>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ArtistSearchPage {
|
||||
pub limit: i64,
|
||||
pub offset: i64,
|
||||
pub total_number_of_items: i64,
|
||||
pub items: Vec<Item>,
|
||||
}
|
||||
|
||||
impl Paginated for ArtistSearchPage {
|
||||
fn offset(&self) -> usize {
|
||||
self.offset as usize
|
||||
}
|
||||
fn limit(&self) -> usize {
|
||||
self.limit as usize
|
||||
}
|
||||
fn total(&self) -> usize {
|
||||
self.total_number_of_items as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Item {
|
||||
|
|
@ -127,7 +100,7 @@ pub struct RefreshResponse {
|
|||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct UserResponse {
|
||||
pub user_id: String,
|
||||
pub user_id: u64,
|
||||
pub country_code: String,
|
||||
}
|
||||
|
||||
|
|
@ -349,29 +322,6 @@ pub struct Creator {
|
|||
pub id: i64,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlaylistTracksPage {
|
||||
pub limit: usize,
|
||||
pub offset: usize,
|
||||
pub total_number_of_items: usize,
|
||||
pub items: Vec<PlaylistTrack>,
|
||||
}
|
||||
|
||||
impl Paginated for PlaylistTracksPage {
|
||||
fn offset(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
|
||||
fn limit(&self) -> usize {
|
||||
self.limit
|
||||
}
|
||||
|
||||
fn total(&self) -> usize {
|
||||
self.total_number_of_items
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PlaylistTrack {
|
||||
|
|
|
|||
Loading…
Reference in New Issue