initial api impl
parent
666d8b8766
commit
10a13d3daa
|
@ -236,6 +236,61 @@ dependencies = [
|
||||||
"paste",
|
"paste",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum"
|
||||||
|
version = "0.7.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"axum-core",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http 1.1.0",
|
||||||
|
"http-body 1.0.1",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper 1.4.1",
|
||||||
|
"hyper-util",
|
||||||
|
"itoa",
|
||||||
|
"matchit",
|
||||||
|
"memchr",
|
||||||
|
"mime",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rustversion",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_path_to_error",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"sync_wrapper 1.0.1",
|
||||||
|
"tokio",
|
||||||
|
"tower 0.5.1",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-core"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http 1.1.0",
|
||||||
|
"http-body 1.0.1",
|
||||||
|
"http-body-util",
|
||||||
|
"mime",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rustversion",
|
||||||
|
"sync_wrapper 1.0.1",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.74"
|
version = "0.3.74"
|
||||||
|
@ -652,7 +707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
|
@ -1251,7 +1306,7 @@ dependencies = [
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"indexmap",
|
"indexmap 2.5.0",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
@ -1270,7 +1325,7 @@ dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"indexmap",
|
"indexmap 2.5.0",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
@ -1283,10 +1338,16 @@ version = "0.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f"
|
checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.14.5"
|
||||||
|
@ -1596,6 +1657,19 @@ dependencies = [
|
||||||
"webpki-roots 0.26.6",
|
"webpki-roots 0.26.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-timeout"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793"
|
||||||
|
dependencies = [
|
||||||
|
"hyper 1.4.1",
|
||||||
|
"hyper-util",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
@ -1664,6 +1738,16 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
|
@ -1671,7 +1755,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2108,6 +2192,12 @@ dependencies = [
|
||||||
"regex-automata 0.1.10",
|
"regex-automata 0.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchit"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maybe-async"
|
name = "maybe-async"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
|
@ -2517,7 +2607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fixedbitset",
|
"fixedbitset",
|
||||||
"indexmap",
|
"indexmap 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2753,7 +2843,7 @@ checksum = "714c75db297bc88a63783ffc6ab9f830698a6705aa0201416931759ef4c8183d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"indexmap",
|
"indexmap 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2765,6 +2855,59 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"prost-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-build"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"heck 0.5.0",
|
||||||
|
"itertools",
|
||||||
|
"log",
|
||||||
|
"multimap",
|
||||||
|
"once_cell",
|
||||||
|
"petgraph",
|
||||||
|
"prettyplease",
|
||||||
|
"prost",
|
||||||
|
"prost-types",
|
||||||
|
"regex",
|
||||||
|
"syn 2.0.79",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-derive"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"itertools",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.79",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-types"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670"
|
||||||
|
dependencies = [
|
||||||
|
"prost",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "protobuf"
|
name = "protobuf"
|
||||||
version = "3.5.1"
|
version = "3.5.1"
|
||||||
|
@ -2798,7 +2941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b0e9b447d099ae2c4993c0cbb03c7a9d6c937b17f2d56cfc0b1550e6fcfdb76"
|
checksum = "1b0e9b447d099ae2c4993c0cbb03c7a9d6c937b17f2d56cfc0b1550e6fcfdb76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"indexmap",
|
"indexmap 2.5.0",
|
||||||
"log",
|
"log",
|
||||||
"protobuf",
|
"protobuf",
|
||||||
"protobuf-support",
|
"protobuf-support",
|
||||||
|
@ -3976,6 +4119,8 @@ dependencies = [
|
||||||
"rustls 0.23.13",
|
"rustls 0.23.13",
|
||||||
"serenity",
|
"serenity",
|
||||||
"songbird",
|
"songbird",
|
||||||
|
"spoticord_api",
|
||||||
|
"spoticord_api_grpc",
|
||||||
"spoticord_config",
|
"spoticord_config",
|
||||||
"spoticord_database",
|
"spoticord_database",
|
||||||
"spoticord_player",
|
"spoticord_player",
|
||||||
|
@ -3983,6 +4128,34 @@ dependencies = [
|
||||||
"spoticord_stats",
|
"spoticord_stats",
|
||||||
"spoticord_utils",
|
"spoticord_utils",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tonic",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spoticord_api"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"env_logger",
|
||||||
|
"log",
|
||||||
|
"prost",
|
||||||
|
"spoticord_api_grpc",
|
||||||
|
"spoticord_database",
|
||||||
|
"spoticord_session",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tonic",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spoticord_api_grpc"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"prost",
|
||||||
|
"tokio",
|
||||||
|
"tonic",
|
||||||
|
"tonic-build",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4645,6 +4818,92 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tonic"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
|
||||||
|
dependencies = [
|
||||||
|
"async-stream",
|
||||||
|
"async-trait",
|
||||||
|
"axum",
|
||||||
|
"base64 0.22.1",
|
||||||
|
"bytes",
|
||||||
|
"h2 0.4.6",
|
||||||
|
"http 1.1.0",
|
||||||
|
"http-body 1.0.1",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper 1.4.1",
|
||||||
|
"hyper-timeout",
|
||||||
|
"hyper-util",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project",
|
||||||
|
"prost",
|
||||||
|
"socket2",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tower 0.4.13",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tonic-build"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11"
|
||||||
|
dependencies = [
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"prost-build",
|
||||||
|
"prost-types",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.79",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"indexmap 1.9.3",
|
||||||
|
"pin-project",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rand",
|
||||||
|
"slab",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"pin-project-lite",
|
||||||
|
"sync_wrapper 0.1.2",
|
||||||
|
"tokio",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-layer"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -4870,7 +5129,7 @@ checksum = "5dece5c06268af6a9ff4541788601e560a4284ffebfb357f713d676f13b964db"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
"mini-moka",
|
"mini-moka",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"secrecy",
|
"secrecy",
|
||||||
|
|
|
@ -17,6 +17,8 @@ members = [
|
||||||
"spoticord_session",
|
"spoticord_session",
|
||||||
"spoticord_utils",
|
"spoticord_utils",
|
||||||
"spoticord_stats",
|
"spoticord_stats",
|
||||||
|
"spoticord_api",
|
||||||
|
"spoticord_api_grpc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -30,6 +32,8 @@ spoticord_player = { path = "./spoticord_player" }
|
||||||
spoticord_session = { path = "./spoticord_session" }
|
spoticord_session = { path = "./spoticord_session" }
|
||||||
spoticord_utils = { path = "./spoticord_utils" }
|
spoticord_utils = { path = "./spoticord_utils" }
|
||||||
spoticord_stats = { path = "./spoticord_stats", optional = true }
|
spoticord_stats = { path = "./spoticord_stats", optional = true }
|
||||||
|
spoticord_api = { path = "./spoticord_api"}
|
||||||
|
spoticord_api_grpc = { path = "./spoticord_api_grpc"}
|
||||||
|
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
|
@ -40,6 +44,7 @@ serenity = "0.12.2"
|
||||||
songbird = { version = "0.4.3", features = ["simd-json"] }
|
songbird = { version = "0.4.3", features = ["simd-json"] }
|
||||||
tokio = { version = "1.39.3", features = ["full"] }
|
tokio = { version = "1.39.3", features = ["full"] }
|
||||||
rustls = { version = "0.23.13", features = ["aws-lc-rs"] }
|
rustls = { version = "0.23.13", features = ["aws-lc-rs"] }
|
||||||
|
tonic = "0.12.3"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "spoticord_api"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
spoticord_database = { path = "../spoticord_database" }
|
||||||
|
spoticord_session = { path = "../spoticord_session" }
|
||||||
|
spoticord_api_grpc = { path = "../spoticord_api_grpc"}
|
||||||
|
prost = "0.13.3"
|
||||||
|
tokio = {version = "1.38.0", features = ["io-util", "net", "rt-multi-thread"]}
|
||||||
|
axum = "0.7.5"
|
||||||
|
env_logger = "0.11.3"
|
||||||
|
log = "0.4.21"
|
||||||
|
thiserror = "1.0.61"
|
||||||
|
tonic = "0.12.3"
|
|
@ -0,0 +1,39 @@
|
||||||
|
use log::info;
|
||||||
|
use spoticord_api_grpc::spoticord_api::service::PlayPlaylistRequest;
|
||||||
|
use spoticord_session::manager::{SessionManager, SessionQuery};
|
||||||
|
use tonic::{Request, Response, Status};
|
||||||
|
|
||||||
|
pub struct SpoticordApi {
|
||||||
|
pub session: SessionManager,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tonic::async_trait]
|
||||||
|
impl spoticord_api_grpc::spoticord_api::service::spoticord_api_server::SpoticordApi
|
||||||
|
for SpoticordApi
|
||||||
|
{
|
||||||
|
async fn play_playlist(
|
||||||
|
&self,
|
||||||
|
request: Request<PlayPlaylistRequest>,
|
||||||
|
) -> Result<Response<spoticord_api_grpc::spoticord_api::service::Response>, Status> {
|
||||||
|
let playlist = request.into_inner();
|
||||||
|
info!(
|
||||||
|
"Playing {} for {}",
|
||||||
|
playlist.playlist_uri, playlist.discord_user_id
|
||||||
|
);
|
||||||
|
|
||||||
|
let session = self
|
||||||
|
.session
|
||||||
|
.get_session(SessionQuery::Owner(playlist.discord_user_id.into()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
session.queue_playlist(playlist.playlist_uri).await.unwrap();
|
||||||
|
|
||||||
|
let response = spoticord_api_grpc::spoticord_api::service::Response {
|
||||||
|
resp: Option::from(
|
||||||
|
spoticord_api_grpc::spoticord_api::service::response::Resp::Success(true),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Response::new(response))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "spoticord_api_grpc"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bytes = "1.6.0"
|
||||||
|
tonic = "0.12.3"
|
||||||
|
prost = "0.13.3"
|
||||||
|
tokio = {version = "1.38.0", features = ["io-util", "test-util"]}
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tonic-build = "0.12.3"
|
|
@ -0,0 +1,6 @@
|
||||||
|
use std::io::Result;
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
tonic_build::configure().compile_protos(&["src/service.proto"], &["src/"])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
pub mod spoticord_api {
|
||||||
|
pub mod service {
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/spoticord_api.service.rs"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::spoticord_api::service::{PlayModes, PlayPlaylistRequest};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_play_playlist() {
|
||||||
|
let play_playlist = PlayPlaylistRequest {
|
||||||
|
order: PlayModes::InOrder.into(),
|
||||||
|
playlist_uri: "test".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(play_playlist.playlist_uri, "test");
|
||||||
|
assert_eq!(play_playlist.order, PlayModes::InOrder.into());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package spoticord_api.service;
|
||||||
|
|
||||||
|
|
||||||
|
enum PlayModes {
|
||||||
|
SHUFFLE = 0;
|
||||||
|
IN_ORDER = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PlayPlaylistRequest {
|
||||||
|
uint64 discord_user_id = 1;
|
||||||
|
PlayModes order = 2;
|
||||||
|
string playlist_uri = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Error {
|
||||||
|
SpotifyError = 0;
|
||||||
|
BotError = 1;
|
||||||
|
UserNotRegistered = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response {
|
||||||
|
oneof resp {
|
||||||
|
bool success = 1;
|
||||||
|
Error error = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
service SpoticordApi {
|
||||||
|
rpc PlayPlaylist(PlayPlaylistRequest) returns (Response);
|
||||||
|
}
|
|
@ -35,8 +35,4 @@ diesel::table! {
|
||||||
diesel::joinable!(account -> user (user_id));
|
diesel::joinable!(account -> user (user_id));
|
||||||
diesel::joinable!(link_request -> user (user_id));
|
diesel::joinable!(link_request -> user (user_id));
|
||||||
|
|
||||||
diesel::allow_tables_to_appear_in_same_query!(
|
diesel::allow_tables_to_appear_in_same_query!(account, link_request, user,);
|
||||||
account,
|
|
||||||
link_request,
|
|
||||||
user,
|
|
||||||
);
|
|
||||||
|
|
|
@ -2,6 +2,10 @@ pub mod info;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use info::PlaybackInfo;
|
use info::PlaybackInfo;
|
||||||
|
use librespot::connect::spirc::SpircLoadCommand;
|
||||||
|
use librespot::core::SpotifyId;
|
||||||
|
use librespot::metadata::{Metadata, Playlist};
|
||||||
|
use librespot::protocol::spirc::TrackRef;
|
||||||
use librespot::{
|
use librespot::{
|
||||||
connect::{config::ConnectConfig, spirc::Spirc},
|
connect::{config::ConnectConfig, spirc::Spirc},
|
||||||
core::{http_client::HttpClientError, Session as SpotifySession, SessionConfig},
|
core::{http_client::HttpClientError, Session as SpotifySession, SessionConfig},
|
||||||
|
@ -34,6 +38,7 @@ enum PlayerCommand {
|
||||||
|
|
||||||
GetPlaybackInfo(oneshot::Sender<Option<PlaybackInfo>>),
|
GetPlaybackInfo(oneshot::Sender<Option<PlaybackInfo>>),
|
||||||
GetLyrics(oneshot::Sender<Option<Lyrics>>),
|
GetLyrics(oneshot::Sender<Option<Lyrics>>),
|
||||||
|
QueuePlaylist { uri: String },
|
||||||
|
|
||||||
Shutdown,
|
Shutdown,
|
||||||
}
|
}
|
||||||
|
@ -213,6 +218,7 @@ impl Player {
|
||||||
PlayerCommand::GetLyrics(tx) => self.get_lyrics(tx).await,
|
PlayerCommand::GetLyrics(tx) => self.get_lyrics(tx).await,
|
||||||
|
|
||||||
PlayerCommand::Shutdown => self.commands.close(),
|
PlayerCommand::Shutdown => self.commands.close(),
|
||||||
|
PlayerCommand::QueuePlaylist { uri } => self.queue_playlist(uri).await,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +306,34 @@ impl Player {
|
||||||
|
|
||||||
_ = tx.send(Some(lyrics));
|
_ = tx.send(Some(lyrics));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn queue_playlist(&self, playlist_uri: String) {
|
||||||
|
let playlist = Playlist::get(&self.session, &SpotifyId::from_uri(&playlist_uri).unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let tracks = playlist
|
||||||
|
.tracks()
|
||||||
|
.map(|track_id| {
|
||||||
|
let mut track = TrackRef::new();
|
||||||
|
track.set_gid(Vec::from(track_id.to_raw()));
|
||||||
|
track
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.spirc.activate().unwrap();
|
||||||
|
|
||||||
|
self.spirc
|
||||||
|
.load(SpircLoadCommand {
|
||||||
|
context_uri: playlist_uri,
|
||||||
|
start_playing: true,
|
||||||
|
shuffle: true,
|
||||||
|
repeat: true,
|
||||||
|
playing_track_index: 0,
|
||||||
|
tracks,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Player {
|
impl Drop for Player {
|
||||||
|
@ -354,4 +388,11 @@ impl PlayerHandle {
|
||||||
pub async fn shutdown(&self) {
|
pub async fn shutdown(&self) {
|
||||||
_ = self.commands.send(PlayerCommand::Shutdown).await;
|
_ = self.commands.send(PlayerCommand::Shutdown).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn queue_playlist(&self, playlist_uri: String) {
|
||||||
|
self.commands
|
||||||
|
.send(PlayerCommand::QueuePlaylist { uri: playlist_uri })
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ pub enum SessionCommand {
|
||||||
ShutdownPlayer,
|
ShutdownPlayer,
|
||||||
Disconnect,
|
Disconnect,
|
||||||
DisconnectTimedOut,
|
DisconnectTimedOut,
|
||||||
|
QueuePlaylist {
|
||||||
|
playlist_uri: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
|
@ -236,7 +239,6 @@ impl Session {
|
||||||
SessionCommand::GetOwner(sender) => _ = sender.send(self.owner),
|
SessionCommand::GetOwner(sender) => _ = sender.send(self.owner),
|
||||||
SessionCommand::GetPlayer(sender) => _ = sender.send(self.player.clone()),
|
SessionCommand::GetPlayer(sender) => _ = sender.send(self.player.clone()),
|
||||||
SessionCommand::GetActive(sender) => _ = sender.send(self.active),
|
SessionCommand::GetActive(sender) => _ = sender.send(self.active),
|
||||||
|
|
||||||
SessionCommand::CreatePlaybackEmbed(handle, interaction, behavior) => {
|
SessionCommand::CreatePlaybackEmbed(handle, interaction, behavior) => {
|
||||||
match PlaybackEmbed::create(self, handle, interaction, behavior).await {
|
match PlaybackEmbed::create(self, handle, interaction, behavior).await {
|
||||||
Ok(opt_handle) => {
|
Ok(opt_handle) => {
|
||||||
|
@ -290,6 +292,9 @@ impl Session {
|
||||||
|
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
|
SessionCommand::QueuePlaylist { playlist_uri } => {
|
||||||
|
self.player.queue_playlist(playlist_uri).await;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
|
@ -551,6 +556,14 @@ impl SessionHandle {
|
||||||
error!("Failed to send command: {why}");
|
error!("Failed to send command: {why}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn queue_playlist(&self, playlist_uri: String) -> Result<()> {
|
||||||
|
self.commands
|
||||||
|
.send(SessionCommand::QueuePlaylist { playlist_uri })
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|
17
src/bot.rs
17
src/bot.rs
|
@ -4,6 +4,7 @@ use anyhow::{anyhow, Result};
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use poise::{serenity_prelude, Framework, FrameworkContext, FrameworkOptions};
|
use poise::{serenity_prelude, Framework, FrameworkContext, FrameworkOptions};
|
||||||
use serenity::all::{ActivityData, FullEvent, Ready, ShardManager};
|
use serenity::all::{ActivityData, FullEvent, Ready, ShardManager};
|
||||||
|
use spoticord_api::SpoticordApi;
|
||||||
use spoticord_database::Database;
|
use spoticord_database::Database;
|
||||||
use spoticord_session::manager::SessionManager;
|
use spoticord_session::manager::SessionManager;
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ async fn event_handler(
|
||||||
ctx: &serenity_prelude::Context,
|
ctx: &serenity_prelude::Context,
|
||||||
event: &FullEvent,
|
event: &FullEvent,
|
||||||
_framework: FrameworkContext<'_, Data, anyhow::Error>,
|
_framework: FrameworkContext<'_, Data, anyhow::Error>,
|
||||||
_data: &Data,
|
data: &Data,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let FullEvent::Ready { data_about_bot } = event {
|
if let FullEvent::Ready { data_about_bot } = event {
|
||||||
if let Some(shard) = data_about_bot.shard {
|
if let Some(shard) = data_about_bot.shard {
|
||||||
|
@ -95,7 +96,19 @@ async fn event_handler(
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.set_activity(Some(ActivityData::listening(spoticord_config::MOTD)));
|
ctx.set_activity(Some(ActivityData::listening(spoticord_config::MOTD)));
|
||||||
}
|
|
||||||
|
let api_server = SpoticordApi {
|
||||||
|
session: data.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
tonic::transport::Server::builder()
|
||||||
|
.add_service(spoticord_api_grpc::spoticord_api::service::spoticord_api_server::SpoticordApiServer::new(api_server))
|
||||||
|
.serve("127.0.0.1:8080".parse().unwrap())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue