From a3d7ed83d76feaa672c3e2f6b66272d28ad54a77 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Mon, 14 Oct 2024 16:42:46 +0200 Subject: [PATCH] wip spotify api setup --- .gitignore | 3 +- .vscode/settings.json | 3 + Cargo.lock | 1678 +++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 12 +- src/api.rs | 95 +++ src/auth.rs | 125 +++ src/main.rs | 47 ++ src/rt.rs | 25 + src/widgets/image.rs | 92 +++ src/widgets/mod.rs | 1 + 10 files changed, 2015 insertions(+), 66 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/api.rs create mode 100644 src/auth.rs create mode 100644 src/rt.rs create mode 100644 src/widgets/image.rs create mode 100644 src/widgets/mod.rs diff --git a/.gitignore b/.gitignore index 2b28063..efe9773 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target result -http-cacache \ No newline at end of file +http-cacache +refresh_token.txt \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..69b361b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "nixEnvSelector.nixFile": "${workspaceFolder}/flake.nix" +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 1f32848..d98df17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,6 +39,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "ahash" version = "0.8.11" @@ -106,6 +117,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[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" @@ -409,6 +426,28 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + [[package]] name = "async-task" version = "4.7.1" @@ -491,6 +530,33 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "aws-lc-rs" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd82dba44d209fddb11c190e0a94b78651f95299598e472215667417a03ff1d" +dependencies = [ + "aws-lc-sys", + "mirai-annotations", + "paste", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7a4168111d7eb622a31b214057b8509c0a7e1794f44c546d742330dc793972" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -506,6 +572,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.7" @@ -518,6 +590,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bincode" version = "1.3.3" @@ -527,6 +605,29 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote 1.0.37", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.79", + "which", +] + [[package]] name = "bit-set" version = "0.6.0" @@ -623,9 +724,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" dependencies = [ "bytemuck_derive", ] @@ -729,6 +830,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-expr" version = "0.15.8" @@ -757,6 +867,42 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.20" @@ -806,6 +952,15 @@ dependencies = [ "error-code", ] +[[package]] +name = "cmake" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +dependencies = [ + "cc", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -884,6 +1039,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation" version = "0.9.4" @@ -1006,6 +1167,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "cursor-icon" version = "1.1.0" @@ -1081,8 +1251,18 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -1099,17 +1279,48 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote 1.0.37", + "strsim 0.11.1", + "syn 2.0.79", +] + [[package]] name = "darling_macro" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ - "darling_core", + "darling_core 0.14.4", "quote 1.0.37", "syn 1.0.109", ] +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core 0.20.10", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + [[package]] name = "dbus" version = "0.9.7" @@ -1121,6 +1332,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.11" @@ -1141,6 +1363,37 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling 0.20.10", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.79", +] + [[package]] name = "derive_is_enum_variant" version = "0.1.1" @@ -1152,6 +1405,33 @@ dependencies = [ "syn 0.11.11", ] +[[package]] +name = "despot" +version = "0.1.0" +dependencies = [ + "chrono", + "clap", + "color_quant", + "cushy", + "futures-util", + "hsl", + "http-cache-reqwest", + "image", + "itertools 0.10.5", + "librespot-core", + "librespot-oauth", + "librespot-playback", + "librespot-protocol", + "mpris", + "oauth2", + "palette", + "plotters", + "reqwest 0.12.8", + "reqwest-middleware", + "rspotify", + "tokio", +] + [[package]] name = "digest" version = "0.10.7" @@ -1159,7 +1439,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -1198,6 +1480,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "easing-function" version = "0.1.1" @@ -1236,6 +1524,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + [[package]] name = "enumflags2" version = "0.7.10" @@ -1369,6 +1669,12 @@ dependencies = [ "winit", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.34" @@ -1498,12 +1804,18 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55a5e644a80e6d96b2b4910fa7993301d7b7926c045b475b62202b20a36ce69e" dependencies = [ - "darling", + "darling 0.14.4", "proc-macro2", "quote 1.0.37", "syn 1.0.109", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures" version = "0.3.31" @@ -1588,6 +1900,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -1633,8 +1951,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1664,6 +1984,12 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "glow" version = "0.13.1" @@ -1685,6 +2011,24 @@ dependencies = [ "gl_generator", ] +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "rand", + "smallvec", + "spinning_top", +] + [[package]] name = "gpu-alloc" version = "0.6.0" @@ -1737,6 +2081,25 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.6" @@ -1748,7 +2111,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1797,6 +2160,30 @@ dependencies = [ "winapi", ] +[[package]] +name = "headers" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http 1.1.0", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.1.0", +] + [[package]] name = "heck" version = "0.3.3" @@ -1836,12 +2223,41 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "hsl" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "575fb7f1167f3b88ed825e90eb14918ac460461fdeaa3965c6a50951dee1c970" +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -1853,6 +2269,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.1" @@ -1860,7 +2287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -1871,8 +2298,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -1885,7 +2312,7 @@ dependencies = [ "async-trait", "bincode", "cacache", - "http", + "http 1.1.0", "http-cache-semantics", "httpdate", "serde", @@ -1900,10 +2327,10 @@ checksum = "be3e27c4e2e510571cbcc601407b639667146aa9a4e818d5cc1d97c8b4b27d61" dependencies = [ "anyhow", "async-trait", - "http", + "http 1.1.0", "http-cache", "http-cache-semantics", - "reqwest", + "reqwest 0.12.8", "reqwest-middleware", "serde", "url", @@ -1915,7 +2342,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92baf25cf0b8c9246baecf3a444546360a97b569168fdf92563ee6a47829920c" dependencies = [ - "http", + "http 1.1.0", "http-serde", "serde", "time", @@ -1927,7 +2354,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f056c8559e3757392c8d091e796416e4649d8e49e88b8d76df6c002f05027fd" dependencies = [ - "http", + "http 1.1.0", "serde", ] @@ -1943,6 +2370,30 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.4.1" @@ -1952,9 +2403,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", "httparse", "itoa", "pin-project-lite", @@ -1963,6 +2414,60 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-proxy2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9043b7b23fb0bc4a1c7014c27b50a4fc42cc76206f71d34fc0dfe5b28ddc3faf" +dependencies = [ + "bytes", + "futures-util", + "headers", + "http 1.1.0", + "hyper 1.4.1", + "hyper-rustls 0.26.0", + "hyper-util", + "pin-project-lite", + "rustls-native-certs 0.7.3", + "tokio", + "tokio-rustls 0.25.0", + "tower-service", + "webpki", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.30", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", + "log", + "rustls 0.22.4", + "rustls-native-certs 0.7.3", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.25.0", + "tower-service", +] + [[package]] name = "hyper-rustls" version = "0.27.3" @@ -1970,13 +2475,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.1.0", + "hyper 1.4.1", "hyper-util", - "rustls", + "log", + "rustls 0.23.14", + "rustls-native-certs 0.8.0", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.0", "tower-service", ] @@ -1988,7 +2495,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper", + "hyper 1.4.1", "hyper-util", "native-tls", "tokio", @@ -2005,9 +2512,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", "pin-project-lite", "socket2", "tokio", @@ -2015,6 +2522,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[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 = "ident_case" version = "1.0.1" @@ -2080,6 +2610,15 @@ dependencies = [ "hashbrown 0.15.0", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "intentional" version = "0.1.1" @@ -2251,6 +2790,15 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "lebe" @@ -2311,6 +2859,143 @@ dependencies = [ "redox_syscall 0.4.1", ] +[[package]] +name = "librespot-audio" +version = "0.5.0-dev" +source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#029419486fcdbf9f5e004cd7d4ebf0c9be8d6c5c" +dependencies = [ + "aes", + "byteorder", + "bytes", + "ctr", + "futures-core", + "futures-util", + "http-body-util", + "hyper 1.4.1", + "hyper-util", + "librespot-core", + "log", + "parking_lot", + "tempfile", + "thiserror", + "tokio", +] + +[[package]] +name = "librespot-core" +version = "0.5.0-dev" +source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#029419486fcdbf9f5e004cd7d4ebf0c9be8d6c5c" +dependencies = [ + "aes", + "base64 0.22.1", + "byteorder", + "bytes", + "data-encoding", + "flate2", + "form_urlencoded", + "futures-core", + "futures-util", + "governor", + "hmac", + "http 1.1.0", + "http-body-util", + "httparse", + "hyper 1.4.1", + "hyper-proxy2", + "hyper-rustls 0.27.3", + "hyper-util", + "librespot-oauth", + "librespot-protocol", + "log", + "nonzero_ext", + "num-bigint", + "num-derive", + "num-integer", + "num-traits", + "once_cell", + "parking_lot", + "pbkdf2", + "priority-queue", + "protobuf", + "protobuf-json-mapping", + "quick-xml", + "rand", + "rsa", + "serde", + "serde_json", + "sha1", + "shannon", + "sysinfo", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tokio-util", + "url", + "uuid", + "vergen-gitcl", +] + +[[package]] +name = "librespot-metadata" +version = "0.5.0-dev" +source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#029419486fcdbf9f5e004cd7d4ebf0c9be8d6c5c" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "librespot-core", + "librespot-protocol", + "log", + "protobuf", + "serde", + "serde_json", + "thiserror", + "uuid", +] + +[[package]] +name = "librespot-oauth" +version = "0.5.0-dev" +source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#029419486fcdbf9f5e004cd7d4ebf0c9be8d6c5c" +dependencies = [ + "log", + "oauth2", + "thiserror", + "url", +] + +[[package]] +name = "librespot-playback" +version = "0.5.0-dev" +source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#029419486fcdbf9f5e004cd7d4ebf0c9be8d6c5c" +dependencies = [ + "byteorder", + "futures-util", + "librespot-audio", + "librespot-core", + "librespot-metadata", + "log", + "parking_lot", + "rand", + "rand_distr", + "shell-words", + "symphonia", + "thiserror", + "tokio", + "zerocopy", +] + +[[package]] +name = "librespot-protocol" +version = "0.5.0-dev" +source = "git+https://github.com/photovoltex/librespot.git?branch=integrate-dealer#029419486fcdbf9f5e004cd7d4ebf0c9be8d6c5c" +dependencies = [ + "protobuf", + "protobuf-codegen", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -2421,6 +3106,17 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "maybe-async" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + [[package]] name = "maybe-rayon" version = "0.1.1" @@ -2544,6 +3240,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "mirai-annotations" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" + [[package]] name = "mpris" version = "2.0.1" @@ -2653,6 +3355,12 @@ dependencies = [ "memoffset", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nom" version = "7.1.3" @@ -2669,12 +3377,27 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83d3716836932a56eadedb47bd27ee2174dbdd3ac97c585002e2994e162c5b37" +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "noop_proc_macro" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2693,6 +3416,24 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "rand", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", ] [[package]] @@ -2721,6 +3462,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.2" @@ -2763,6 +3515,35 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "oauth2" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" +dependencies = [ + "base64 0.13.1", + "chrono", + "getrandom", + "http 0.2.12", + "rand", + "reqwest 0.11.27", + "serde", + "serde_json", + "serde_path_to_error", + "sha2", + "thiserror", + "url", +] + [[package]] name = "objc" version = "0.2.7" @@ -3114,10 +3895,13 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ + "backtrace", "cfg-if", "libc", + "petgraph", "redox_syscall 0.5.7", "smallvec", + "thread-id", "windows-targets 0.52.6", ] @@ -3127,12 +3911,41 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "phf" version = "0.11.2" @@ -3218,6 +4031,27 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.31" @@ -3276,6 +4110,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "powerfmt" version = "0.2.0" @@ -3297,6 +4137,27 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" +[[package]] +name = "prettyplease" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +dependencies = [ + "proc-macro2", + "syn 2.0.79", +] + +[[package]] +name = "priority-queue" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714c75db297bc88a63783ffc6ab9f830698a6705aa0201416931759ef4c8183d" +dependencies = [ + "autocfg", + "equivalent", + "indexmap", +] + [[package]] name = "proc-macro-crate" version = "3.2.0" @@ -3328,23 +4189,85 @@ dependencies = [ [[package]] name = "profiling" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote 1.0.37", "syn 2.0.79", ] +[[package]] +name = "protobuf" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3018844a02746180074f621e847703737d27d89d7f0721a7a4da317f88b16385" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-codegen" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c15a212b4de05eb8bc989fd066a74c86bd3c04e27d6e86bd7703b806d7734" +dependencies = [ + "anyhow", + "once_cell", + "protobuf", + "protobuf-parse", + "regex", + "tempfile", + "thiserror", +] + +[[package]] +name = "protobuf-json-mapping" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d77c15a1dfbe22d088e5d31acbd6cae25eb15bd707de9ef00c58b508f11c76a" +dependencies = [ + "protobuf", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-parse" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06f45f16b522d92336e839b5e40680095a045e36a1e7f742ba682ddc85236772" +dependencies = [ + "anyhow", + "indexmap", + "log", + "protobuf", + "protobuf-support", + "tempfile", + "thiserror", + "which", +] + +[[package]] +name = "protobuf-support" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf96d872914fcda2b66d66ea3fff2be7c66865d31c7bb2790cff32c0e714880" +dependencies = [ + "thiserror", +] + [[package]] name = "qoi" version = "0.4.1" @@ -3367,6 +4290,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" dependencies = [ "memchr", + "serde", ] [[package]] @@ -3436,6 +4360,16 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "range-alloc" version = "0.1.3" @@ -3612,6 +4546,47 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-rustls 0.24.2", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", + "tokio", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + [[package]] name = "reqwest" version = "0.12.8" @@ -3623,12 +4598,12 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.4.1", + "hyper-rustls 0.27.3", "hyper-tls", "hyper-util", "ipnet", @@ -3639,14 +4614,15 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 2.2.0", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", - "system-configuration", + "sync_wrapper 1.0.1", + "system-configuration 0.6.1", "tokio", "tokio-native-tls", + "tokio-socks", "tower-service", "url", "wasm-bindgen", @@ -3663,8 +4639,8 @@ checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" dependencies = [ "anyhow", "async-trait", - "http", - "reqwest", + "http 1.1.0", + "reqwest 0.12.8", "serde", "thiserror", "tower-service", @@ -3723,22 +4699,81 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" [[package]] -name = "rshell" -version = "0.1.0" +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" dependencies = [ - "clap", - "color_quant", - "cushy", - "hsl", - "http-cache-reqwest", - "image", - "itertools 0.10.5", - "mpris", - "palette", - "plotters", - "reqwest", - "reqwest-middleware", - "tokio", + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rspotify" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71aa4a990ef1bacbed874fbab621e16c61a8b5a56854ada6b2bcccf19acb5795" +dependencies = [ + "async-stream", + "async-trait", + "base64 0.22.1", + "chrono", + "futures", + "getrandom", + "log", + "maybe-async", + "rspotify-http", + "rspotify-macros", + "rspotify-model", + "serde", + "serde_json", + "sha2", + "thiserror", + "url", +] + +[[package]] +name = "rspotify-http" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a193f73ee55ab66aeb0337170d120bc73ec4963b150d9c66d68b28d14bc5ac5f" +dependencies = [ + "async-trait", + "log", + "maybe-async", + "reqwest 0.12.8", + "serde_json", + "thiserror", +] + +[[package]] +name = "rspotify-macros" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b78387b0ebb8da6d4c72e728496b09701b7054c0ef88ea2f4f40e46b9107a6de" + +[[package]] +name = "rspotify-model" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6ce0f0ecf4eb3b0b8ab7c6932328d03040dd77169b1c533a3ead1308985af6" +dependencies = [ + "chrono", + "enum_dispatch", + "serde", + "serde_json", + "strum", + "thiserror", ] [[package]] @@ -3766,19 +4801,82 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls" version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" dependencies = [ + "aws-lc-rs", + "log", "once_cell", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -3794,17 +4892,34 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + [[package]] name = "rustybuzz" version = "0.14.1" @@ -3858,6 +4973,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sctk-adwaita" version = "0.10.1" @@ -3932,6 +5057,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.19" @@ -3997,6 +5132,15 @@ dependencies = [ "digest", ] +[[package]] +name = "shannon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea5b41c9427b56caa7b808cb548a04fb50bb5b9e98590b53f28064ff4174561" +dependencies = [ + "byteorder", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -4006,6 +5150,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shlex" version = "1.3.0" @@ -4021,6 +5171,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -4129,6 +5289,15 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spirv" version = "0.3.0+sdk-1.3.268.0" @@ -4138,6 +5307,16 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "ssri" version = "9.2.0" @@ -4179,6 +5358,28 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote 1.0.37", + "rustversion", + "syn 2.0.79", +] + [[package]] name = "subtle" version = "2.6.1" @@ -4202,6 +5403,90 @@ dependencies = [ "zeno", ] +[[package]] +name = "symphonia" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9" +dependencies = [ + "lazy_static", + "symphonia-bundle-mp3", + "symphonia-codec-vorbis", + "symphonia-core", + "symphonia-format-ogg", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-bundle-mp3" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01c2aae70f0f1fb096b6f0ff112a930b1fb3626178fba3ae68b09dce71706d4" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-codec-vorbis" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a98765fb46a0a6732b007f7e2870c2129b6f78d87db7987e6533c8f164a9f30" +dependencies = [ + "log", + "symphonia-core", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-core" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "symphonia-format-ogg" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-utils-xiph" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe" +dependencies = [ + "symphonia-core", + "symphonia-metadata", +] + [[package]] name = "syn" version = "0.11.11" @@ -4235,6 +5520,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "sync_wrapper" version = "1.0.1" @@ -4262,6 +5553,30 @@ dependencies = [ "libc", ] +[[package]] +name = "sysinfo" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "windows 0.57.0", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys 0.5.0", +] + [[package]] name = "system-configuration" version = "0.6.1" @@ -4270,7 +5585,17 @@ checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.6.0", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.6.0", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] @@ -4344,6 +5669,16 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "thread-id" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe8f25bbdd100db7e1d34acf7fd2dc59c4bf8f7483f505eaa7d4f12f76cc0ea" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -4373,7 +5708,9 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", @@ -4446,6 +5783,7 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", "socket2", "tokio-macros", @@ -4473,17 +5811,50 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.4", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls", + "rustls 0.23.14", "rustls-pki-types", "tokio", ] +[[package]] +name = "tokio-socks" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.16" @@ -4495,6 +5866,22 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "rustls 0.23.14", + "rustls-native-certs 0.8.0", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.12" @@ -4633,6 +6020,26 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5902c5d130972a0000f60860bfbf46f7ca3db5391eddfedd1b8728bd9dc96c0e" +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand", + "rustls 0.23.14", + "rustls-pki-types", + "sha1", + "thiserror", + "utf-8", +] + [[package]] name = "typenum" version = "1.17.0" @@ -4749,12 +6156,28 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", + "rand", +] + [[package]] name = "v_frame" version = "0.3.8" @@ -4778,6 +6201,44 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vergen" +version = "9.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349ed9e45296a581f455bc18039878f409992999bc1d5da12a6800eb18c8752f" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen-lib", +] + +[[package]] +name = "vergen-gitcl" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3a7f91caabecefc3c249fd864b11d4abe315c166fbdb568964421bccfd2b7a" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen", + "vergen-lib", +] + +[[package]] +name = "vergen-lib" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229eaddb0050920816cf051e619affaf18caa3dd512de8de5839ccbc8e53abb0" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", +] + [[package]] name = "version-compare" version = "0.2.0" @@ -5011,6 +6472,22 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "weezl" version = "0.1.8" @@ -5123,6 +6600,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "widestring" version = "1.1.0" @@ -5170,6 +6659,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.58.0" @@ -5189,19 +6688,42 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", "windows-strings", "windows-targets 0.52.6", ] +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + [[package]] name = "windows-implement" version = "0.58.0" @@ -5213,6 +6735,17 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + [[package]] name = "windows-interface" version = "0.58.0" @@ -5230,11 +6763,20 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-strings", "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.2.0" @@ -5250,7 +6792,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-targets 0.52.6", ] @@ -5529,6 +7071,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "x11-dl" version = "2.21.0" diff --git a/Cargo.toml b/Cargo.toml index 584b9f1..b985823 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "rshell" -description = "Another GUI shell" +name = "despot" +description = "Another Spotify client" version = "0.1.0" edition = "2021" @@ -19,3 +19,11 @@ hsl = "0.1.1" itertools = "0.10.0" palette = "0.7.3" clap = { version = "4.5.20", features = ["derive"] } +chrono = "0.4" +librespot-core = { git = "https://github.com/photovoltex/librespot.git", branch = "integrate-dealer" } +librespot-oauth = { git = "https://github.com/photovoltex/librespot.git", branch = "integrate-dealer" } +librespot-playback = { git = "https://github.com/photovoltex/librespot.git", branch = "integrate-dealer" } +librespot-protocol = { git = "https://github.com/photovoltex/librespot.git", branch = "integrate-dealer" } +futures-util = { version = "0.3", features = ["alloc", "bilock", "sink", "unstable"] } +rspotify = { version = "0.13.3" } +oauth2 = "4.4" diff --git a/src/api.rs b/src/api.rs new file mode 100644 index 0000000..5fd0415 --- /dev/null +++ b/src/api.rs @@ -0,0 +1,95 @@ +use std::future::Future; +use std::time::Duration; + +use chrono::TimeDelta; +use librespot_core::Session; +use librespot_oauth::OAuthToken; +use reqwest::StatusCode; +use rspotify::{AuthCodeSpotify, ClientError, ClientResult, Config, Token}; +use rspotify::http::HttpError; + +use crate::auth::{rspotify_scopes, SPOTIFY_REDIRECT_URI}; + + +struct SpotifyContext { + session: Session, + api: AuthCodeSpotify, + token: OAuthToken +} + +impl SpotifyContext { + fn new(session: Session, token: OAuthToken) -> SpotifyContext { + let config = Config { + token_refreshing: false, + ..Default::default() + }; + let api = AuthCodeSpotify::from_token_with_config( + librespot_token_to_rspotify(&token), + rspotify::Credentials::default(), + rspotify::OAuth { + proxies: None, + redirect_uri: SPOTIFY_REDIRECT_URI.to_string(), + scopes: rspotify_scopes(), + state: String::new() + }, + config, + ); + SpotifyContext { session, api, token } + } + + /// Execute `api_call` and retry once if a rate limit occurs. + async fn api_with_retry>, R>(&self, api_call: F) -> Option + where + F: Fn(&AuthCodeSpotify) -> T, + { + let result = { api_call(&self.api).await }; + match result { + Ok(v) => Some(v), + Err(ClientError::Http(error)) => { + dbg!("http error: {:?}", &error); + if let HttpError::StatusCode(response) = error.as_ref() { + match response.status() { + StatusCode::TOO_MANY_REQUESTS => { + let waiting_duration = response + .headers() + .get("Retry-After") + .and_then(|v| v.to_str().ok().and_then(|v| v.parse::().ok())); + dbg!("rate limit hit. waiting {:?} seconds", waiting_duration); + + // sleep with tokio instead + tokio::time::sleep(Duration::from_secs(waiting_duration.unwrap_or(1))).await; + + api_call(&self.api).await.ok() + } + StatusCode::UNAUTHORIZED => { + dbg!("token unauthorized. trying refresh.."); + // self.update_token() + // .and_then(move |_| api_call(&self.api).await.ok()) + None + } + _ => { + eprintln!("unhandled api error: {:?}", response); + None + } + } + } else { + None + } + } + Err(e) => { + eprintln!("unhandled api error: {}", e); + None + } + } + } +} + +fn librespot_token_to_rspotify(token: &OAuthToken) -> Token { + Token { + access_token: token.access_token.clone(), + scopes: rspotify_scopes(), + refresh_token: None, + expires_at: None, + expires_in: TimeDelta::zero() + } +} \ No newline at end of file diff --git a/src/auth.rs b/src/auth.rs new file mode 100644 index 0000000..e9c1451 --- /dev/null +++ b/src/auth.rs @@ -0,0 +1,125 @@ +use std::{collections::HashSet, io::{Read, Write}, time::{Duration, Instant}}; +use librespot_core::SessionConfig; +use librespot_oauth::{get_access_token, OAuthError, OAuthToken}; +use oauth2::{basic::BasicClient, reqwest::http_client, AuthUrl, ClientId, RedirectUrl, RefreshToken, TokenResponse, TokenUrl}; + +pub const SPOTIFY_REDIRECT_URI: &str = "http://127.0.0.1:8898/login"; + +const SPOTIFY_SCOPES: [&str; 16] = [ + "user-read-playback-state", + "user-modify-playback-state", + "user-read-currently-playing", + "app-remote-control", + "streaming", + "playlist-read-private", + "playlist-read-collaborative", + "playlist-modify-private", + "playlist-modify-public", + "user-follow-modify", + "user-follow-read", + "user-read-playback-position", + "user-top-read", + "user-read-recently-played", + "user-library-modify", + "user-library-read", +]; + +pub fn rspotify_scopes() -> HashSet { + HashSet::from_iter(SPOTIFY_SCOPES.map(|t| t.to_string())) +} + +fn get_refresh_token_file_location() -> String { + "./refresh_token.txt".to_string() +} + +fn read_refresh_token() -> Option { + let file = std::fs::File::open(get_refresh_token_file_location()); + if file.is_err() { + return None; + } + + let mut reader = std::io::BufReader::new(file.unwrap()); + let mut token = String::new(); + reader.read_to_string(&mut token).unwrap(); + Some(token) +} + +fn write_refresh_token(token: &str) { + let mut file = std::fs::File::create(get_refresh_token_file_location()).unwrap(); + file.write_all(token.as_bytes()).unwrap(); +} + +fn oauth2_client() -> Result { + let auth_url = AuthUrl::new("https://accounts.spotify.com/authorize".to_string()) + .map_err(|_| OAuthError::InvalidSpotifyUri)?; + let token_url = TokenUrl::new("https://accounts.spotify.com/api/token".to_string()) + .map_err(|_| OAuthError::InvalidSpotifyUri)?; + let redirect_url = + RedirectUrl::new(SPOTIFY_REDIRECT_URI.to_string()).map_err(|e| OAuthError::InvalidRedirectUri { + uri: SPOTIFY_REDIRECT_URI.to_string(), + e, + })?; + let client = BasicClient::new( + ClientId::new(SessionConfig::default().client_id), + None, + auth_url, + Some(token_url), + ); + let client = client.set_redirect_uri(redirect_url); + Ok(client) +} + +fn get_access_token_from_refresh_token(refresh_token: &str) -> Result { + let client = oauth2_client()?; + let token = client + .exchange_refresh_token(&RefreshToken::new(refresh_token.to_string())) + .request(http_client) + .map_err(|e| { dbg!(e); OAuthError::ExchangeCode { e: refresh_token.to_string() } })?; + + let refresh_token = match token.refresh_token() { + Some(t) => t.secret().to_string(), + _ => "".to_string(), // Spotify always provides a refresh token. + }; + + write_refresh_token(&refresh_token); + + Ok(OAuthToken { + access_token: token.access_token().secret().to_string(), + refresh_token, + expires_at: Instant::now() + + token + .expires_in() + .unwrap_or_else(|| Duration::from_secs(3600)), + token_type: format!("{:?}", token.token_type()).to_string(), // Urgh!? + scopes: Vec::from(SPOTIFY_SCOPES.map(|s| s.to_string())), + }) +} + +pub fn get_token() -> Result { + let refresh = read_refresh_token(); + + match refresh { + Some(token) => { + let token = get_access_token_from_refresh_token(&token); + match token { + Ok(token) => return Ok(token), + Err(e) => { + eprintln!("Error refreshing token, trying to relogin. Error: {}", e); + } + } + } + None => {} + }; + + let token = match get_access_token(&SessionConfig::default().client_id, SPOTIFY_REDIRECT_URI, Vec::from(SPOTIFY_SCOPES)) { + Ok(token) => token, + Err(e) => { + eprintln!("Error: {}", e); + return Err(e); + } + }; + + write_refresh_token(&token.refresh_token); + + Ok(token) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 16123f5..77abb05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,61 @@ +use std::thread; + +use auth::get_token; use clap::Parser; use cli::Args; use cushy::{PendingApp, Run, TokioRuntime}; +use librespot_core::{authentication::Credentials, Session, SessionConfig}; +use librespot_playback::{audio_backend, config::{AudioFormat, PlayerConfig}, mixer::NoOpVolume, player::Player}; mod vibrancy; mod theme; mod cli; +mod auth; +mod widgets; +mod rt; +mod api; fn main() -> cushy::Result { let args = Args::parse(); let mut app = PendingApp::new(TokioRuntime::default()); + let token = get_token().unwrap(); + + let session_config = SessionConfig::default(); + let player_config = PlayerConfig::default(); + let audio_format = AudioFormat::default(); + let credentials = Credentials::with_access_token(&token.access_token); + let backend = audio_backend::find(None).unwrap(); + + let session; + + { + let guard = app.cushy().enter_runtime(); + session = Session::new(session_config, None); + + let player = Player::new(player_config, session.clone(), Box::new(NoOpVolume), move || { + backend(None, audio_format) + }); + + tokio::spawn({ let session = session.clone(); async move { + if let Err(e) = session.connect(credentials, false).await { + println!("Error connecting: {}", e); + } + }}); + + thread::spawn(move || { + let mut channel = player.get_player_event_channel(); + loop { + let event = channel.blocking_recv(); + if let Some(event) = event { + dbg!(event); + } else { break; } + } + }); + + drop(guard); + } + dbg!(session.user_data()); + app.run() } \ No newline at end of file diff --git a/src/rt.rs b/src/rt.rs new file mode 100644 index 0000000..d4d4db3 --- /dev/null +++ b/src/rt.rs @@ -0,0 +1,25 @@ +use tokio::runtime; + +pub(crate) fn tokio_runtime() -> &'static runtime::Handle { + use std::sync::OnceLock; + use std::time::Duration; + + static RUNTIME: OnceLock = OnceLock::new(); + RUNTIME.get_or_init(|| { + let rt = runtime::Builder::new_multi_thread() + .enable_all() + .build() + .expect("tokio initialization error"); + let handle = rt.handle().clone(); + std::thread::spawn(move || { + // Replace with the async main loop, or some sync structure to + // control shutting it down if desired. + rt.block_on(async { + loop { + tokio::time::sleep(Duration::from_secs(10000)).await + } + }); + }); + handle + }) +} diff --git a/src/widgets/image.rs b/src/widgets/image.rs new file mode 100644 index 0000000..d4d1c69 --- /dev/null +++ b/src/widgets/image.rs @@ -0,0 +1,92 @@ +use std::sync::Arc; + +use cushy::{kludgine::{AnyTexture, LazyTexture}, value::{CallbackHandle, Destination, Dynamic, Source, Value}, widgets::Image}; +use futures_util::lock::Mutex; +use http_cache_reqwest::{CACacheManager, Cache, CacheMode, HttpCache, HttpCacheOptions}; +use image::imageops::FilterType; +use reqwest::Client; +use reqwest_middleware::ClientBuilder; +use tokio::task::JoinHandle; + +use crate::rt::tokio_runtime; + + +trait ImageExt { + fn new_empty() -> Self; + + fn load_url(&mut self, url: Dynamic>) -> CallbackHandle; +} + +impl ImageExt for Image { + fn new_empty() -> Self { + Image::new(Dynamic::new(get_empty_texture())) + } + + fn load_url(&mut self, url: Dynamic>) -> CallbackHandle { + let client = ClientBuilder::new(Client::new()) + .with(Cache(HttpCache { + mode: CacheMode::Default, + manager: CACacheManager::default(), + options: HttpCacheOptions::default(), + })) + .build(); + + + // let texture = Dynamic::new(get_empty_texture()); + match &mut self.contents { + Value::Constant(_) => self.contents = Value::Dynamic(Dynamic::new(get_empty_texture())), + Value::Dynamic(dynamic) => dynamic.set(get_empty_texture()), + } + let texture = match &self.contents { + Value::Dynamic(dynamic) => dynamic, + _ => unreachable!() + }; + let texture = texture.clone(); + + let prev_request_join = Arc::new(Mutex::new(None::>)); + url.for_each({ + let texture = texture.clone(); + move |url| { + let guard = tokio_runtime().enter(); + let url = url.clone(); + let prev_request_join = prev_request_join.clone(); + let texture = texture.clone(); + let client = client.clone(); + tokio::spawn(async move { + let mut prev_request_join = prev_request_join.lock().await; + if let Some(prev_request_join) = prev_request_join.take() { + prev_request_join.abort(); + } + if let Some(url) = url { + let texture = texture.clone(); + let client = client.clone(); + *prev_request_join = Some(tokio::spawn(async move { + let response = client.get(url).send().await.unwrap(); + let bytes = response.bytes().await.unwrap(); + let image = image::load_from_memory(&bytes).unwrap(); + let image = image.resize(128, 128, FilterType::Lanczos3); + let image_texture = LazyTexture::from_image(image, cushy::kludgine::wgpu::FilterMode::Linear); + let image_texture = AnyTexture::Lazy(image_texture); + texture.set(image_texture); + })); + } else { + texture.set(get_empty_texture()); + } + }); + drop(guard); + } + }) + } +} + + +fn get_empty_texture() -> AnyTexture { + AnyTexture::Lazy( + LazyTexture::from_image( + image::DynamicImage::ImageRgba8( + image::ImageBuffer::new(1, 1) + ), + cushy::kludgine::wgpu::FilterMode::Linear + ) + ) +} \ No newline at end of file diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs new file mode 100644 index 0000000..b1b6b4f --- /dev/null +++ b/src/widgets/mod.rs @@ -0,0 +1 @@ +pub mod image; \ No newline at end of file