From 30d6607754283f5edd270849a03d9b76fd53ace7 Mon Sep 17 00:00:00 2001 From: Lunarix <3759687+Skarlett@users.noreply.github.com> Date: Sun, 14 May 2023 12:47:02 -0500 Subject: [PATCH] Fix master (#90) * add `check-cache` bin * add pkg `deemix-stream` & `coggie-cleanup-dl` * remove mistakes * add spotify compat * rm sbin/deemix-stream * add features-list-cmd * clean up dead stuff * fix cleanup * rm from ffmpeg * add which hard deletes files after streamed * move into crates/ * fix * workspace * update lock * stablizing * fix `check-cache` & `systemd-enable` * replace `coggiebot-next` with `coggiebot-stable` * fix "no package named `XXX`" --------- Co-authored-by: Skarlett --- Cargo.lock | 645 +++- Cargo.toml | 42 +- crates/coggiebot/Cargo.lock | 2643 +++++++++++++++++ crates/coggiebot/Cargo.toml | 92 + LICENSE => crates/coggiebot/LICENSE | 0 .../coggiebot/src}/controllers/basic.rs | 1 - .../coggiebot/src}/controllers/bookmark.rs | 5 +- crates/coggiebot/src/controllers/features.rs | 44 + .../coggiebot/src}/controllers/help.rs | 0 .../src/controllers/mockingbird/channel.rs | 56 + .../src/controllers/mockingbird/controller.rs | 241 +- .../mockingbird/extractor/deemix.json | 82 + .../mockingbird/extractor/deemix.rs | 392 +++ .../controllers/mockingbird/extractor/mod.rs | 140 + .../controllers/mockingbird/extractor/mp3.rs | 69 + .../controllers/mockingbird/extractor/ytdl.rs | 27 + .../src/controllers/mockingbird/mod.rs | 36 + .../coggiebot/src}/controllers/mod.rs | 26 +- .../coggiebot/src}/controllers/prerelease.rs | 0 {src => crates/coggiebot/src}/main.rs | 46 +- flake.nix | 139 +- iac/coggiebot/default.nix | 252 +- iac/linux/auto-update/default.nix | 134 + iac/linux/auto-update/systemd.nix | 60 + iac/linux/default.nix | 69 + iac/linux/helpers.nix | 57 + iac/linux/systemd.nix | 70 + iac/vanilla-linux/default.nix | 42 - iac/vanilla-linux/systemd.nix | 386 --- sbin/cachectl/default.nix | 208 ++ sbin/cleanup-dl/Makefile.PL | 17 + sbin/cleanup-dl/bin/cleanup-downloads.pl | 22 + sbin/cleanup-dl/cleanup-downloads.pl | 76 + sbin/cleanup-dl/default.nix | 25 + sbin/pipe_demix | 140 - src/config.rs | 57 - src/controllers/features.rs | 115 - src/controllers/mockingbird/demix.rs | 168 -- src/controllers/mockingbird/mod.rs | 9 - src/pkglib.rs | 17 - tickets.md | 11 - 41 files changed, 5258 insertions(+), 1403 deletions(-) create mode 100644 crates/coggiebot/Cargo.lock create mode 100644 crates/coggiebot/Cargo.toml rename LICENSE => crates/coggiebot/LICENSE (100%) rename {src => crates/coggiebot/src}/controllers/basic.rs (97%) rename {src => crates/coggiebot/src}/controllers/bookmark.rs (96%) create mode 100644 crates/coggiebot/src/controllers/features.rs rename {src => crates/coggiebot/src}/controllers/help.rs (100%) create mode 100644 crates/coggiebot/src/controllers/mockingbird/channel.rs rename src/controllers/mockingbird/mockingbird.rs => crates/coggiebot/src/controllers/mockingbird/controller.rs (65%) create mode 100644 crates/coggiebot/src/controllers/mockingbird/extractor/deemix.json create mode 100644 crates/coggiebot/src/controllers/mockingbird/extractor/deemix.rs create mode 100644 crates/coggiebot/src/controllers/mockingbird/extractor/mod.rs create mode 100644 crates/coggiebot/src/controllers/mockingbird/extractor/mp3.rs create mode 100644 crates/coggiebot/src/controllers/mockingbird/extractor/ytdl.rs create mode 100644 crates/coggiebot/src/controllers/mockingbird/mod.rs rename {src => crates/coggiebot/src}/controllers/mod.rs (82%) rename {src => crates/coggiebot/src}/controllers/prerelease.rs (100%) rename {src => crates/coggiebot/src}/main.rs (70%) create mode 100644 iac/linux/auto-update/default.nix create mode 100644 iac/linux/auto-update/systemd.nix create mode 100644 iac/linux/default.nix create mode 100644 iac/linux/helpers.nix create mode 100644 iac/linux/systemd.nix delete mode 100644 iac/vanilla-linux/default.nix delete mode 100644 iac/vanilla-linux/systemd.nix create mode 100644 sbin/cachectl/default.nix create mode 100644 sbin/cleanup-dl/Makefile.PL create mode 100644 sbin/cleanup-dl/bin/cleanup-downloads.pl create mode 100644 sbin/cleanup-dl/cleanup-downloads.pl create mode 100644 sbin/cleanup-dl/default.nix delete mode 100644 sbin/pipe_demix delete mode 100644 src/config.rs delete mode 100644 src/controllers/features.rs delete mode 100644 src/controllers/mockingbird/demix.rs delete mode 100644 src/controllers/mockingbird/mod.rs delete mode 100644 src/pkglib.rs delete mode 100644 tickets.md diff --git a/Cargo.lock b/Cargo.lock index 006855c..221939b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,18 +20,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "arrayvec" @@ -39,6 +39,44 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock", + "autocfg", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + [[package]] name = "async-trait" version = "0.1.68" @@ -66,6 +104,22 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "async-walkdir" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826d88d73e87e7504b635b6e427561faa6a65f4a2f59e75efcbfa51a0876bb90" +dependencies = [ + "async-fs", + "futures-lite", +] + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "audiopus" version = "0.3.0-rc.0" @@ -119,11 +173,26 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "bytemuck" @@ -186,19 +255,25 @@ dependencies = [ [[package]] name = "coggiebot" -version = "1.4.6" +version = "1.4.7" dependencies = [ "anyhow", + "async-walkdir", "derive_builder", + "file-lock", + "reqwest", "serde", "serde_derive", "serde_json", "serenity", "songbird", "structopt", + "tempfile", "thiserror", "tokio", "toml", + "tracing", + "tracing-subscriber", ] [[package]] @@ -212,11 +287,36 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -378,11 +478,57 @@ dependencies = [ "num-traits 0.1.43", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "file-lock" +version = "2.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59be9010c5418713a48aac4c1b897d85dafd958055683dc31bdae553536647b" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "miniz_oxide", @@ -407,6 +553,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -464,6 +625,21 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.28" @@ -507,9 +683,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e" +checksum = "f3e123d9ae7c02966b4d892e550bdc32164f05853cd40ab570650ad600596a8a" dependencies = [ "cc", "libc", @@ -543,9 +719,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -584,6 +760,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "http" version = "0.2.9" @@ -655,6 +837,19 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -681,6 +876,26 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipnet" version = "2.7.2" @@ -695,9 +910,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -716,9 +931,15 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "linux-raw-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "lock_api" @@ -787,9 +1008,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -803,7 +1024,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -815,6 +1036,24 @@ dependencies = [ "getrandom", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -849,7 +1088,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -865,6 +1104,50 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "ordered-float" version = "2.10.0" @@ -880,6 +1163,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + [[package]] name = "parking_lot" version = "0.12.1" @@ -898,9 +1187,9 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -943,9 +1232,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "pnet_base" @@ -1026,9 +1315,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -1072,15 +1361,24 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -1089,7 +1387,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] @@ -1098,11 +1396,17 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + [[package]] name = "reqwest" -version = "0.11.16" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ "base64 0.21.0", "bytes", @@ -1114,11 +1418,13 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", "log", "mime", "mime_guess", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -1128,6 +1434,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-util", "tower-service", @@ -1155,6 +1462,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "rustls" version = "0.20.8" @@ -1198,6 +1519,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -1220,11 +1550,34 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -1241,9 +1594,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", @@ -1530,6 +1883,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -1571,9 +1937,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" dependencies = [ "itoa", "serde", @@ -1583,15 +1949,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ "time-core", ] @@ -1613,9 +1979,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.27.0" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg", "bytes", @@ -1626,20 +1992,30 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", "syn 2.0.15", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.23.4" @@ -1653,9 +2029,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -1720,20 +2096,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -1762,9 +2138,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", @@ -1914,12 +2290,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "want" version = "0.3.0" @@ -1938,9 +2326,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1948,24 +2336,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" dependencies = [ "cfg-if", "js-sys", @@ -1975,9 +2363,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1985,22 +2373,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" [[package]] name = "wasm-streams" @@ -2017,9 +2405,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" dependencies = [ "js-sys", "wasm-bindgen", @@ -2068,11 +2456,26 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.44.0" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows-targets", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -2081,7 +2484,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -2090,13 +2502,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -2105,47 +2532,89 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "winnow" -version = "0.4.1" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index dbb2586..55052c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,40 +1,4 @@ -[package] -name = "coggiebot" -version = "1.4.6" -edition = "2021" - -[dependencies] -serenity = { version = "0.11", default-features=false, features = ["client", "gateway", "rustls_backend", "model", "framework", "standard_framework", "voice", "cache"] } -tokio = { version = "1", features = ["macros", "rt-multi-thread"] } -structopt = { version = "0.3", default-features = false } -derive_builder = "0.12" -thiserror = "1.0" -anyhow = "1.0" -toml = "0.7" -serde = "1.0" -serde_derive = "*" -serde_json = "*" -songbird = { version = "0.3", optional=true, features=["builtin-queue", "yt-dlp"] } - - -[features] -default = ["mockingbird"] -basic-cmds = [] -bookmark = [] -mockingbird = ["dep:songbird"] -dj-room = ["mockingbird"] -demix = ["mockingbird"] -list-feature-cmd = [] - -[package.metadata.nix] -app = true -build = true -library = true -systems = [ - "aarch64-linux", - "aarch64-darwin", - "i686-linux", - "x86_64-darwin", - "x86_64-linux", +[workspace] +members = [ + "crates/coggiebot" ] - diff --git a/crates/coggiebot/Cargo.lock b/crates/coggiebot/Cargo.lock new file mode 100644 index 0000000..d1d2ce2 --- /dev/null +++ b/crates/coggiebot/Cargo.lock @@ -0,0 +1,2643 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", + "rand_core", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock", + "autocfg", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "async-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb" +dependencies = [ + "futures-io", + "futures-util", + "log", + "pin-project-lite", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots", +] + +[[package]] +name = "async-walkdir" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826d88d73e87e7504b635b6e427561faa6a65f4a2f59e75efcbfa51a0876bb90" +dependencies = [ + "async-fs", + "futures-lite", +] + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + +[[package]] +name = "audiopus" +version = "0.3.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab55eb0e56d7c6de3d59f544e5db122d7725ec33be6a276ee8241f3be6473955" +dependencies = [ + "audiopus_sys", +] + +[[package]] +name = "audiopus_sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62314a1546a2064e033665d658e88c620a62904be945f8147e6b16c3db9f8651" +dependencies = [ + "cmake", + "log", + "pkg-config", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + +[[package]] +name = "coggiebot" +version = "1.4.7" +dependencies = [ + "anyhow", + "async-walkdir", + "derive_builder", + "file-lock", + "reqwest", + "serde", + "serde_derive", + "serde_json", + "serenity", + "songbird", + "structopt", + "tempfile", + "thiserror", + "tokio", + "toml", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "command_attr" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d999d4e7731150ee14aee8f619c7a9aa9a4385bca0606c4fa95aa2f36a05d9a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "discortp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb66017646a48220b5ea30d63ac18bb5952f647f1a41ed755880895125d26972" +dependencies = [ + "pnet_macros", + "pnet_macros_support", +] + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum_primitive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" +dependencies = [ + "num-traits 0.1.43", +] + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "file-lock" +version = "2.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59be9010c5418713a48aac4c1b897d85dafd958055683dc31bdae553536647b" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "h2" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "levenshtein" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" + +[[package]] +name = "libc" +version = "0.2.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" + +[[package]] +name = "linux-raw-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.15", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-float" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +dependencies = [ + "num-traits 0.2.15", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "pnet_base" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25488cd551a753dcaaa6fffc9f69a7610a412dd8954425bf7ffad5f7d1156fb8" + +[[package]] +name = "pnet_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30490e0852e58402b8fae0d39897b08a24f493023a4d6cf56b2e30f31ed57548" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "pnet_macros_support" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4714e10f30cab023005adce048f2d30dd4ac4f093662abf2220855655ef8f90" +dependencies = [ + "pnet_base", +] + +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "reqwest" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustix" +version = "0.37.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79bef90eb6d984c72722595b5b1348ab39275a5e5123faca6863bf07d75a4e0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64 0.21.0", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "salsa20" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686" +dependencies = [ + "cipher", + "zeroize", +] + +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serenity" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82fd5e7b5858ad96e99d440138f34f5b98e1b959ebcd3a1036203b30e78eb788" +dependencies = [ + "async-trait", + "async-tungstenite", + "base64 0.13.1", + "bitflags", + "bytes", + "cfg-if", + "command_attr", + "dashmap", + "flate2", + "futures", + "levenshtein", + "mime", + "mime_guess", + "parking_lot", + "percent-encoding", + "reqwest", + "serde", + "serde-value", + "serde_json", + "static_assertions", + "time", + "tokio", + "tracing", + "typemap_rev", + "url", + "uwl", +] + +[[package]] +name = "serenity-voice-model" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be3aec8849ca2fde1e8a5dfbed96fbd68e9b5f4283fbe277d8694ce811d4952" +dependencies = [ + "bitflags", + "enum_primitive", + "serde", + "serde_json", + "serde_repr", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "songbird" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f686a0fd771939de1da3e43cee45169fafe1595770b94680572cf18bdef288" +dependencies = [ + "async-trait", + "async-tungstenite", + "audiopus", + "byteorder", + "dashmap", + "derivative", + "discortp", + "flume", + "futures", + "parking_lot", + "pin-project", + "rand", + "serde", + "serde_json", + "serenity", + "serenity-voice-model", + "streamcatcher", + "symphonia-core", + "tokio", + "tracing", + "tracing-futures", + "typemap_rev", + "url", + "uuid", + "xsalsa20poly1305", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "streamcatcher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71664755c349abb0758fda6218fb2d2391ca2a73f9302c03b145491db4fcea29" +dependencies = [ + "crossbeam-utils", + "futures-util", + "loom", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "symphonia-core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9567e2d8a5f866b2f94f5d366d811e0c6826babcff6d37de9e1a6690d38869" +dependencies = [ + "arrayvec", + "bitflags", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-util" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "rustls", + "sha-1", + "thiserror", + "url", + "utf-8", + "webpki", +] + +[[package]] +name = "typemap_rev" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "uwl" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4bf03e0ca70d626ecc4ba6b0763b934b6f2976e8c744088bb3c1d646fbb1ad0" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "wasm-streams" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "xsalsa20poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68bcb965d6c650091450b95cea12f07dcd299a01c15e2f9433b0813ea3c0886" +dependencies = [ + "aead", + "poly1305", + "rand_core", + "salsa20", + "subtle", + "zeroize", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" diff --git a/crates/coggiebot/Cargo.toml b/crates/coggiebot/Cargo.toml new file mode 100644 index 0000000..0578231 --- /dev/null +++ b/crates/coggiebot/Cargo.toml @@ -0,0 +1,92 @@ +[package] +name = "coggiebot" +version = "1.4.7" +edition = "2021" + +[dependencies] +serenity = { version = "0.11", default-features=false, features = ["client", "gateway", "rustls_backend", "model", "framework", "standard_framework", "voice", "cache"] } +tokio = { version = "1", features = ["macros", "rt-multi-thread"] } +structopt = { version = "0.3", default-features = false } +derive_builder = "0.12" +thiserror = "1.0" +anyhow = "1.0" +toml = "0.7" +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" + +tracing = "0.1" +tracing-subscriber = "0.3" + +songbird = { version = "0.3", optional=true, features = ["builtin-queue"] } +file-lock = { version = "2.1", optional=true } +async-walkdir = { version="0.2.0", optional=true } +reqwest = { version = "0.11", optional = true } +tempfile = { version = "3", optional = true } + +[features] +default = ["mockingbird-core", "mockingbird-deemix", "mockingbird-spotify"] +list-feature-cmd = [] +basic-cmds = [] +bookmark = [] + +################ +# mockingbird features +mockingbird-core = ["dep:songbird", "dep:tempfile"] + +################ +# playback commands queue/play/stop/mute/deafen +mockingbird-playback = ["mockingbird-core"] + +################ +# Setup mocking bird to "own" a channel so users +# may just paste compatiable links into it +mockingbird-channel = ["mockingbird-core"] + +################ +# mockingbird is compatiable with youtube & soundcloud +mockingbird-ytdl = ["mockingbird-core", "songbird?/yt-dlp"] + +################ +# mockingbird compatiable with raw MP3 http uris +mockingbird-mp3 = ["mockingbird-core", "dep:reqwest"] + +################ +# mockingbird compatiable with deep-mixer +mockingbird-deemix = ["mockingbird-core", "dep:async-walkdir", ] + +################ +# mockingbird compatiable with spotify +mockingbird-spotify = ["mockingbird-deemix"] + +################ +# adds capability to clean up files from the system after +# they've been streamed to discord +mockingbird-hard-cleanfs = ["mockingbird-playback"] + +########### +# find similar music, and play playlists +24/7 loop +# mockingbird-dj = ["mockingbird"] + +######### +# write queue file to filesystem +# mockingbird-shm = ["mockingbird", "dep:file-lock"] + +######### +# allow downloads +# add environment variables +# mockingbird-export = ["mockingbird", "mockingbird-shm"] + + +[package.metadata.nix] +app = true +build = true +library = true +systems = [ + "aarch64-linux", + "aarch64-darwin", + "i686-linux", + "x86_64-darwin", + "x86_64-linux", +] + diff --git a/LICENSE b/crates/coggiebot/LICENSE similarity index 100% rename from LICENSE rename to crates/coggiebot/LICENSE diff --git a/src/controllers/basic.rs b/crates/coggiebot/src/controllers/basic.rs similarity index 97% rename from src/controllers/basic.rs rename to crates/coggiebot/src/controllers/basic.rs index 920f15d..f43b182 100644 --- a/src/controllers/basic.rs +++ b/crates/coggiebot/src/controllers/basic.rs @@ -1,6 +1,5 @@ use crate::{ get_rev, VERSION, REPO, - pkglib::{CoggiebotError} }; use serenity::framework::standard::{ diff --git a/src/controllers/bookmark.rs b/crates/coggiebot/src/controllers/bookmark.rs similarity index 96% rename from src/controllers/bookmark.rs rename to crates/coggiebot/src/controllers/bookmark.rs index 86d9386..1f9056e 100644 --- a/src/controllers/bookmark.rs +++ b/crates/coggiebot/src/controllers/bookmark.rs @@ -6,7 +6,7 @@ use serenity::model::{ Timestamp, }; use serenity::framework::standard::{ - Args, CommandResult, macros::{command, group}, + CommandResult, }; @@ -98,8 +98,7 @@ pub async fn bookmark_on_react_add(ctx: &Context, ev: &Reaction) -> CommandResul build_embed(&msg, b, ev); build_message_reply(&msg, b) }) - .await - .unwrap(); + .await?; } } return Ok(()); diff --git a/crates/coggiebot/src/controllers/features.rs b/crates/coggiebot/src/controllers/features.rs new file mode 100644 index 0000000..16a1e44 --- /dev/null +++ b/crates/coggiebot/src/controllers/features.rs @@ -0,0 +1,44 @@ +use crate::REPO; +use serenity::model::prelude::Message; +use serenity::framework::standard::{ + macros::{command, group}, + CommandResult, +}; + +use std::{path::PathBuf, io::BufRead}; +use serenity::prelude::*; + +pub const FEATURES: &'static str = env!("COGGIEBOT_FEATURES"); + +pub fn feature_list() -> Vec<(String, bool)>{ + FEATURES.split(",") + .filter_map(|s| s.split_once("=")) + .map(|(a, b)| (a.to_string(), b.parse::().expect("Invalid value for feature") >= 1)) + .collect() +} + +#[group] +#[commands(features)] +pub struct Features; + +#[command("features")] +async fn features(ctx: &Context, msg: &Message) -> CommandResult { + let features = feature_list(); + + msg.channel_id + .send_message(&ctx.http, |m| + m.add_embed(|e| + e.title("Coggie Bot") + .description("Coggie Bot is an open source \"Discord\" (discord.com) bot.") + .url(REPO) + .fields(features + .iter().map(|r| match r { + (name, true) => (name, "enabled", true), + (name, false) => (name, "disabled", true), + _ => unreachable!(), + }) + ) + ) + ).await?; + Ok(()) +} diff --git a/src/controllers/help.rs b/crates/coggiebot/src/controllers/help.rs similarity index 100% rename from src/controllers/help.rs rename to crates/coggiebot/src/controllers/help.rs diff --git a/crates/coggiebot/src/controllers/mockingbird/channel.rs b/crates/coggiebot/src/controllers/mockingbird/channel.rs new file mode 100644 index 0000000..f0ae870 --- /dev/null +++ b/crates/coggiebot/src/controllers/mockingbird/channel.rs @@ -0,0 +1,56 @@ +#[cfg(feature="mockingbird-channel")] +pub async fn on_dj_channel(ctx: &Context, msg: &Message) -> CommandResult { + let url = match &msg.content + { + url if url.starts_with("http") => url.to_string(), + _ => { + check_msg( + msg.channel_id + .say(&ctx.http, "Must provide a URL to a video or audio") + .await, + ); + + return Ok(()); + }, + }; + + let guild = msg.guild(&ctx.cache).unwrap(); + let guild_id = guild.id; + + let manager = songbird::get(ctx) + .await + .expect("Songbird Voice client placed in at initialisation.") + .clone(); + + if let Some(handler_lock) = manager.get(guild_id) { + let mut handler = handler_lock.lock().await; + + for x in play_source(&url) { + match x { + Ok(src) => handler.enqueue_source(src.into()), + Err(e) => { + tracing::error!("Error Starting source [{:?}]: {:?}", x, e); + } + } + handler.enqueue_source(x.into()); + } + + check_msg( + msg.channel_id + .say( + &ctx.http, + format!("Added song to queue: position {}", handler.queue().len()), + ) + .await, + ); + } + else { + check_msg( + msg.channel_id + .say(&ctx.http, "Not in a voice channel to play in") + .await, + ); + } + + Ok(()) +} diff --git a/src/controllers/mockingbird/mockingbird.rs b/crates/coggiebot/src/controllers/mockingbird/controller.rs similarity index 65% rename from src/controllers/mockingbird/mockingbird.rs rename to crates/coggiebot/src/controllers/mockingbird/controller.rs index 929fb83..30b2bf9 100644 --- a/src/controllers/mockingbird/mockingbird.rs +++ b/crates/coggiebot/src/controllers/mockingbird/controller.rs @@ -1,102 +1,37 @@ -//! Example demonstrating how to make use of individual track audio events, -//! and how to use the `TrackQueue` system. -//! -//! Requires the "cache", "standard_framework", and "voice" features be enabled in your -//! Cargo.toml, like so: -//! -//! ```toml -//! [dependencies.serenity] -//! git = "https://github.com/serenity-rs/serenity.git" -//! features = ["cache", "framework", "standard_framework", "voice"] -//! ``` -//use super::lib::ArlToken; - -use std::{ - sync::Arc, - time::Duration, +use songbird::{ + EventHandler as VoiceEventHandler, + EventContext, + TrackEvent, + Event as VCEvent, + input, + tracks::{create_player, TrackHandle} }; - -use serenity::{ - client::Context, - framework::{ - standard::{ - macros::{command, group}, - Args, - CommandResult, - }, - }, - model::{channel::Message, prelude::ChannelId}, - prelude::Mentionable, - Result as SerenityResult, +use serenity::framework::standard::{ + macros::{command, group}, + CommandResult, Args, }; -use songbird::input::restartable::Restartable; +use serenity::async_trait; +use serenity::model::channel::Message; +use serenity::prelude::*; -#[group] -#[commands( - deafen, join, leave, mute, queue, skip, stop, undeafen, unmute -)] -struct MockingBird; - -#[cfg(feature="dj-room")] -pub async fn on_dj_channel(ctx: &Context, msg: &Message) -> CommandResult { - let url = match &msg.content - { - url if url.starts_with("http") => url.to_string(), - _ => { - check_msg( - msg.channel_id - .say(&ctx.http, "Must provide a URL to a video or audio") - .await, - ); +use std::path::PathBuf; +use std::sync::{Arc, atomic::{AtomicUsize, Ordering}}; +use std::time::Duration; +use std::io::SeekFrom as Seek; - return Ok(()); - }, - }; +use super::extractor::{play_source, PlaySource}; - let guild = msg.guild(&ctx.cache).unwrap(); - let guild_id = guild.id; +#[cfg(feature="mockingbird-deemix")] +use super::extractor::{DxConfigKey, DxConfig}; - let manager = songbird::get(ctx) - .await - .expect("Songbird Voice client placed in at initialisation.") - .clone(); - - if let Some(handler_lock) = manager.get(guild_id) { - let mut handler = handler_lock.lock().await; - // Here, we use lazy restartable sources to make sure that we don't pay - // for decoding, playback on tracks which aren't actually live yet. - let source = match Restartable::ytdl(url, true).await { - Ok(source) => source, - Err(why) => { - println!("Err starting source: {:?}", why); - check_msg(msg.channel_id.say(&ctx.http, "Error sourcing ffmpeg").await); - - return Ok(()); - }, - }; - handler.enqueue_source(source.into()); - - check_msg( - msg.channel_id - .say( - &ctx.http, - format!("Added song to queue: position {}", handler.queue().len()), - ) - .await, - ); - } - else { - check_msg( - msg.channel_id - .say(&ctx.http, "Not in a voice channel to play in") - .await, - ); - } +#[group] +#[commands( + deafen, join, leave, mute, skip, stop, undeafen, unmute, queue +)] +struct Deemix; - Ok(()) -} #[command] async fn deafen(ctx: &Context, msg: &Message) -> CommandResult { @@ -118,7 +53,6 @@ async fn deafen(ctx: &Context, msg: &Message) -> CommandResult { }; let mut handler = handler_lock.lock().await; - if handler.is_deaf() { check_msg(msg.channel_id.say(&ctx.http, "Already deafened").await); } else { @@ -245,6 +179,60 @@ async fn mute(ctx: &Context, msg: &Message) -> CommandResult { Ok(()) } +struct HardDelete(Option); +#[async_trait] +impl VoiceEventHandler for HardDelete { + async fn act(&self, ctx: &EventContext<'_>) -> Option { + if let EventContext::Track(&[(a, track_list)]) = ctx { + if let Some(ref path) = self.0 { + tracing::info!("Deleting {:?}", path); + tokio::fs::remove_file(path).await.unwrap(); + } + } + None + } +} + +// struct FadeOver { +// next: TrackHandle, +// next_playing: Arc, +// songbird: Arc> +// } + +// #[async_trait] +// impl VoiceEventHandler for FadeOver { +// async fn act(&self, ctx: &EventContext<'_>) -> Option { +// if let EventContext::Track(&[(state, track)]) = ctx { +// let first = self.next_playing.fetch_add(1, Ordering::Relaxed); +// if first == 0 { +// let handler = self.songbird.lock().await?; +// let mut handler = self.songbird.get(self.next.guild_id).unwrap().lock().await; + +// self.next.make_playable(); +// self.next.seek_time(Duration::from_secs(0)); + + +// tracing::info!("Playing next track"); +// } + +// if state.volume < 0.2 { +// tracing::info!("Track volume is low, cancelling"); +// track.stop(); +// self.songbird.lock().await?; +// handler.play(self.next); +// self.next.set_volume(1.0); +// self.next.seek_time(Duration::from_secs(9)); +// return Some(VCEvent::Cancel) +// } +// else { +// track.set_volume(state.volume - 0.1); +// self.next.set_volume(1.0 - state.volume); +// } +// } +// None +// } +// } + #[command] #[aliases("play")] #[only_in(guilds)] @@ -280,23 +268,58 @@ async fn queue(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { .expect("Songbird Voice client placed in at initialisation.") .clone(); + if let Some(handler_lock) = manager.get(guild_id) { let mut handler = handler_lock.lock().await; - // Here, we use lazy restartable sources to make sure that we don't pay - // for decoding, playback on tracks which aren't actually live yet. - let source = match Restartable::ytdl(url, true).await { - Ok(source) => source, - Err(why) => { - println!("Err starting source: {:?}", why); - - check_msg(msg.channel_id.say(&ctx.http, "Error sourcing ffmpeg").await); - - return Ok(()); - }, + let req = super::extractor::PlayRequest { + uri: &url, + #[cfg(feature = "mockingbird-deemix")] + dx: { + let dx_lock = ctx.data.read().await; + let dxc: DxConfig = dx_lock.get::().unwrap().clone(); + dxc + } }; - handler.enqueue_source(source.into()); + match play_source(req).await.unwrap() { + PlaySource::Ytdl { uri } => { + let input = input::ytdl(&uri).await.unwrap(); + handler.enqueue_source(input.into()); + } + + PlaySource::FileSystem { errlog, ok_paths } => { + for fp in ok_paths { + match input::ffmpeg(&fp).await + { + Ok(input) => { + let (track, track_handle) = create_player(input); + + // if let Some(x) = handler.queue().current_queue().first() { + // track_handle.add_event( + // VCEvent::Periodic(Duration::from_secs(1), Some(track_handle.metadata().duration.unwrap() - Duration::from_secs(5))), + // FadeOver { + // next: x.clone(), + // next_playing: Arc::new(AtomicUsize::new(0)), + // } + // ); + // } + #[cfg(feature="mockingbird-hard-cleanfs")] + track_handle.add_event( + VCEvent::Track(TrackEvent::End), + HardDelete(Some(fp)) + ); + handler.enqueue(track); + }, + + Err(e) => { + tokio::fs::remove_file(&fp).await.unwrap(); + continue; + } + } + } + } + } check_msg( msg.channel_id @@ -447,20 +470,10 @@ async fn unmute(ctx: &Context, msg: &Message) -> CommandResult { Ok(()) } +use serenity::Result as SerenityResult; /// Checks that a message successfully sent; if not, then logs why to stdout. fn check_msg(result: SerenityResult) { if let Err(why) = result { println!("Error sending message: {:?}", why); } } - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - use std::env::var; - use std::path::PathBuf; - let paths = var("PATH").unwrap(); - assert!(paths.split(':').filter(|p| PathBuf::from(p).join("ffmpeg").exists()).count() == 1); - } -} diff --git a/crates/coggiebot/src/controllers/mockingbird/extractor/deemix.json b/crates/coggiebot/src/controllers/mockingbird/extractor/deemix.json new file mode 100644 index 0000000..fec7cc5 --- /dev/null +++ b/crates/coggiebot/src/controllers/mockingbird/extractor/deemix.json @@ -0,0 +1,82 @@ +{ + "downloadLocation": "/tmp/coggiebot", + "tracknameTemplate": "01 - %artist% - %title%", + "albumTracknameTemplate": "%tracknumber% - %title%", + "playlistTracknameTemplate": "%position% - %artist% - %title%", + "createPlaylistFolder": true, + "playlistNameTemplate": "%playlist%", + "createArtistFolder": false, + "artistNameTemplate": "%artist%", + "createAlbumFolder": true, + "albumNameTemplate": "%artist% - %album%", + "createCDFolder": false, + "createStructurePlaylist": false, + "createSingleFolder": false, + "padTracks": true, + "paddingSize": "0", + "illegalCharacterReplacer": "_", + "queueConcurrency": 3, + "maxBitrate": "3", + "feelingLucky": false, + "fallbackBitrate": false, + "fallbackSearch": false, + "fallbackISRC": false, + "logErrors": false, + "logSearched": false, + "overwriteFile": "n", + "createM3U8File": false, + "playlistFilenameTemplate": "playlist", + "syncedLyrics": false, + "embeddedArtworkSize": 800, + "embeddedArtworkPNG": false, + "localArtworkSize": 1400, + "localArtworkFormat": "jpg", + "saveArtwork": false, + "coverImageTemplate": "cover", + "saveArtworkArtist": false, + "artistImageTemplate": "folder", + "jpegImageQuality": 90, + "dateFormat": "Y-M-D", + "albumVariousArtists": true, + "removeAlbumVersion": false, + "removeDuplicateArtists": false, + "featuredToTitle": "0", + "titleCasing": "nothing", + "artistCasing": "nothing", + "executeCommand": "", + "tags": { + "title": true, + "artist": true, + "artists": true, + "album": true, + "cover": true, + "trackNumber": true, + "trackTotal": false, + "discNumber": true, + "discTotal": false, + "albumArtist": true, + "genre": true, + "year": true, + "date": true, + "explicit": false, + "isrc": false, + "length": true, + "barcode": false, + "bpm": true, + "replayGain": false, + "label": true, + "lyrics": false, + "syncedLyrics": false, + "copyright": false, + "composer": false, + "involvedPeople": false, + "source": false, + "rating": false, + "savePlaylistAsCompilation": false, + "useNullSeparator": false, + "saveID3v1": true, + "multiArtistSeparator": "default", + "singleAlbumArtist": false, + "coverDescriptionUTF8": false + } +} diff --git a/crates/coggiebot/src/controllers/mockingbird/extractor/deemix.rs b/crates/coggiebot/src/controllers/mockingbird/extractor/deemix.rs new file mode 100644 index 0000000..49bc642 --- /dev/null +++ b/crates/coggiebot/src/controllers/mockingbird/extractor/deemix.rs @@ -0,0 +1,392 @@ +use std::path::{Path, PathBuf}; +use serenity::prelude::TypeMapKey; +use tempfile::tempfile; +use thiserror::Error; +use async_walkdir::WalkDir; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tracing::log::warn; +use std::process::Stdio; +use serenity::{ + futures::StreamExt, + client::ClientBuilder +}; +use serde::Serialize; + +pub struct DxConfigKey; +impl TypeMapKey for DxConfigKey { + type Value = DxConfig; +} + +#[derive(Error, Debug)] +pub enum DxError { + #[error("io error")] + BadIO(#[from] std::io::Error), + + #[error("could not parse track sequence")] + TrackParseError(#[from] std::num::ParseIntError), + + #[error("environment missing ARL variable")] + MissingARL, + + #[error("bad cache directory")] + BadCacheDir, +} + +pub fn is_deemix(uri: &str) -> bool { + ["deezer.com", "deezer.page.link"] + .iter() + .any(|x| uri.contains(x)) +} + +pub fn is_spotify(uri: &str) -> bool { + ["spotify.com", "open.spotify"] + .iter() + .any(|x| uri.contains(x)) +} + + +// #[tracing::instrument] +pub async fn deemix( + uri: &str, + rootdir: PathBuf, + dx: &DxConfig +) -> Result +{ + let tmpdir = tempfile::tempdir()?; + + tracing::info!("RUNNING: deemix --portable -p {} {}", &tmpdir.path().display(), uri); + let child = tokio::process::Command::new("deemix") + .current_dir(dx.cache.as_ref().unwrap()) + .arg("--portable") + .arg("-p").arg(&tmpdir.path()) + .arg(uri) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("Failed to start child process"); + + let out = child.wait_with_output().await?; + let mut error_buf = String::new(); + + let error_file = tmpdir.path().join("errors.txt"); + if error_file.exists() { + tokio::io::BufReader::new( + tokio::fs::File::open(error_file).await? + ).read_to_string(&mut error_buf).await?; + } + + tracing::info!("deemix exit code: {}", out.status); + tracing::warn!("deemix stderr: {}", String::from_utf8_lossy(&out.stderr[..])); + tracing::debug!("deemix stdout: {}", String::from_utf8_lossy(&out.stdout[..])); + + let paths = process_dir(&tmpdir.path(), &dx.cache.as_ref().unwrap().join("music") ).await?; + // tokio::fs::remove_dir_all(&tmpdir).await?; + + + return Ok(PlaySource::FileSystem { + errlog: error_buf, + ok_paths: paths, + }); +} + +#[derive(Debug, Clone)] +pub struct DxConfig { + arl: Option, + pub cache: Option, + + #[cfg(feature="mockingbird-spotify")] + spotify: Option, +} + +impl DxConfig { + pub fn new(arl: Option, cache: Option) -> Self { + Self { + arl, + cache, + #[cfg(feature="mockingbird-spotify")] + spotify: None, + } + } + + pub async fn init_cache(&self) -> Result<(), DxError> { + if self.cache.is_none() { + return Err(DxError::BadCacheDir); + } + + let cache = self.cache.as_ref().unwrap(); + + if !cache.exists() { + tracing::info!("creating cache directory: {:?}", cache); + tokio::fs::create_dir_all(&cache).await?; + } + else { + tracing::info!("cache directory exists {:?}", cache); + } + + let test = cache.join("test.json"); + let action = tokio::fs::OpenOptions::new() + .write(true) + .create(true) + .open(&test) + .await? + .write_all(b"{}") + .await; + + tokio::fs::remove_file(&test).await?; + if let Err(why) = action { + tracing::error!("could not write to cache directory: {}", why); + panic!("bad cache directory") + } + + workspace(&self).await?; + Ok(()) + } + +} + +impl Default for DxConfig { + fn default() -> Self { + DxConfig { + arl: None, + cache: None, + + #[cfg(feature="mockingbird-spotify")] + spotify: None, + } + } +} + +use std::env; +use crate::controllers::mockingbird::extractor::PlaySource; +pub async fn init(cfg: ClientBuilder) -> ClientBuilder { + + #[allow(unused_mut)] + let mut dx = DxConfig::new( + env::var("DEEMIX_ARL").ok(), + match env::var("DEEMIX_CACHE") { + Ok(s) => Some(PathBuf::from(s)), + Err(e) => None, + } + ); + + tracing::debug!("INIT DEEMIX-CONFIG: {:?}", dx); + + if dx.arl.is_none() || dx.cache.is_none() { + tracing::error!("deemix based services will not be available: ds incomplete: {:?}", dx); + return cfg.type_map_insert::(DxConfig::default()) + } + + tracing::info!("deemix credentials found, enabling support"); + + #[cfg(feature="mockingbird-spotify")] + let dx = { + let id = env::var("SPOTIFY_CLIENT_ID"); + let key = env::var("SPOTIFY_CLIENT_SECRET"); + + match (id, key) { + (Ok(id), Ok(key)) => { + tracing::info!("Spotify credentials found, enabling spotify support {} {}", id, key); + dx.spotify = Some(DxSpotifyCfg::new(id, key)); + dx + }, + _ => { + tracing::error!("SPOTIFY_CLIENT_ID or SPOTIFY_CLIENT_SECRET is not set, spotify based services will not be available"); + dx + } + } + }; + + tracing::info!("Initializing deemix cache"); + tracing::info!("deemix: {:?}", &dx); + dx.init_cache().await.unwrap(); + + tracing::info!("mockingbird-deemix Initialized"); + + cfg.type_map_insert::(dx) +} + +async fn workspace(dx: &DxConfig) -> Result<(), DxError> { + let conf_data = include_str!("deemix.json"); + + if dx.arl.is_none() { + tracing::error!("ARL is none {:?}", dx.arl); + return Err(DxError::MissingARL) + } + + let root = dx.cache.as_ref().unwrap(); + let pconfig = root.join("config"); + let pbank = root.join("music"); + + let fconfig = pconfig.join("config.json"); + + tracing::info!("Creating deemix workspace: {}", root.display()); + + if ! pconfig.exists() { + tokio::fs::create_dir(&pconfig).await?; + } + + if ! pbank.exists() { + tokio::fs::create_dir(&pbank).await?; + } + + tracing::info!("Creating deemix config: {}", fconfig.display()); + tokio::fs::OpenOptions::new() + .write(true) + .create(true) + .open(fconfig) + .await? + .write_all(conf_data.as_bytes()) + .await?; + + let farl = pconfig.join(".arl"); + + tracing::info!("Creating deemix arl: {}", farl.display()); + tokio::fs::OpenOptions::new() + .write(true) + .create(true) + .open(farl) + .await? + .write_all(dx.arl.as_ref().unwrap().as_bytes()) + .await?; + + #[cfg(feature="mockingbird-spotify")] + if let Some(ref spot_cfg) = dx.spotify { + spotify_workspace(spot_cfg, &pconfig).await?; + } + + return Ok(()) +} + +//#[tracing::instrument] +async fn process_dir(tmpdir: &Path, pbank: &Path) -> Result, DxError> +{ + tracing::info!("Processing deemix output directory: {}", tmpdir.display()); + let mut entries = WalkDir::new(tmpdir); + let mut data: Vec<(u32, async_walkdir::DirEntry)> = Vec::new(); + let mut ret = Vec::new(); + let mut match_tn: u32 = 1; + + while let Some(x) = entries.next().await { + match x { + Ok(entry) => if entry.metadata().await?.is_file() { + tracing::info!("Found file: {}", entry.file_name().to_str().unwrap()); + let track_num = track_number( + entry.file_name().to_str().unwrap() + ); + + let tn = match track_num { + Ok(tn) => { + if match_tn != tn { + match_tn = tn; + } + tn + } + Err(_) => { + tracing::warn!("Failed to parse track number. Assuming value {}", match_tn); + match_tn + } + }; + + match_tn += 1; + data.push((tn, entry)); + }, + Err(e) => tracing::error!("Error: {}", e) + } + } + + data.sort_by(|(n1, _), (n2, _)| { + n1.cmp(&n2) + }); + + for (n, entry) in data { + if entry.metadata().await?.is_file() { + let new_path = pbank.join(entry.file_name()); + + tracing::info!("Queueing: {}: {}", n, entry.path().display()); + + tokio::fs::rename(entry.path(), &new_path).await?; + ret.push(new_path) + } + } + + tracing::info!("moving deemix output to: {}", pbank.display()); + Ok(ret) +} + + +#[cfg(feature="mockingbird-spotify")] +#[derive(Serialize, Debug, Clone)] +#[allow(non_snake_case)] +pub struct DxSpotifyCfg { + clientId: String, + clientSecret: String, + fallbackSearch: bool, +} + +impl DxSpotifyCfg { + #[allow(non_snake_case)] + pub fn new(clientId: String, clientSecret: String) -> Self { + Self { + clientId, + clientSecret, + fallbackSearch: false, + } + } +} + +#[cfg(feature="mockingbird-spotify")] +#[tracing::instrument] +pub async fn spotify_workspace(spotify: &DxSpotifyCfg, pconfig: &PathBuf) -> std::io::Result<()> { + let pspot = pconfig.join("spotify"); + let config = pspot.join("config.json"); + + tracing::debug!("Generating spotify config dir {}", pspot.display()); + + if !pspot.exists() { + tokio::fs::create_dir(pspot).await?; + } + + let spotify = tokio::fs::OpenOptions::new() + .write(true) + .create(true) + .open(&config) + .await? + .write_all(serde_json::to_string(spotify).unwrap().as_bytes()) + .await?; + + tracing::debug!("wrote config {}", config.display()); + Ok(spotify) +} + +fn track_number(name: &str) -> Result { + name.split(" - ").collect::>().get(0).unwrap().parse::() +} + + +#[cfg(test)] +mod tests { + use tempfile::tempfile; + + use super::*; + + #[test] + fn test_deemix() { + let uri = "https://open.spotify.com/track/2YpeDb67231RjR0MgVLzsG?si=8e9e9e9e9e9e9e9e"; + assert!(is_spotify(uri)); + } +} + + +#[cfg(tests)] +mod tests { + use std::env::var; + use std::path::PathBuf; + + #[test] + #[cfg(feature="mockingbird-deemix")] + fn path_deemix() { + let paths = var("PATH").unwrap(); + assert!(paths.split(':').filter(|p| PathBuf::from(p).join("deemix").exists()).count() == 1); + } +} diff --git a/crates/coggiebot/src/controllers/mockingbird/extractor/mod.rs b/crates/coggiebot/src/controllers/mockingbird/extractor/mod.rs new file mode 100644 index 0000000..b208f27 --- /dev/null +++ b/crates/coggiebot/src/controllers/mockingbird/extractor/mod.rs @@ -0,0 +1,140 @@ +use thiserror::Error; +use std::path::PathBuf; +use serenity::client::ClientBuilder; +use songbird::input::Restartable; + +#[cfg(feature="mockingbird-deemix")] +mod deemix; + +#[cfg(feature="mockingbird-deemix")] +pub use deemix::{DxConfig, DxConfigKey, DxError}; + +#[cfg(feature="mockingbird-ytdl")] +mod ytdl; + +#[cfg(feature="mockingbird-mp3")] +pub use mp3::Mp3Error; + +#[cfg(feature="mockingbird-mp3")] +mod mp3; + +#[derive(Debug)] +pub enum PlaySource { + FileSystem { + errlog: String, + ok_paths: Vec, + }, + + Ytdl { + uri: String, + } +} + +impl PlaySource { + pub async fn to_restartable(self) -> Vec { + match self { + PlaySource::FileSystem { errlog, ok_paths } => { + let mut restartables = Vec::new(); + for path in ok_paths { + match Restartable::ffmpeg(path.clone(), true).await + { + Ok(x) => restartables.push(x.into()), + Err(e) => { + tracing::error!("failed to create restartable for {}: {}", path.display(), e); + tracing::error!("error log: {}", errlog); + } + } + } + restartables + } + PlaySource::Ytdl { uri } => { + let restartable = Restartable::ytdl(uri, true).await.unwrap(); + vec![restartable] + } + } + } + + + pub async fn play() { + + } +} + +#[derive(Debug, Error)] +pub enum SourceErrors { + #[error("no extractor for uri")] + NoExtractor, + + #[error("failed to create temporary directory")] + MkTmpFailed(#[from] std::io::Error), + + #[cfg(feature="mockingbird-mp3")] + #[error("mp3 error")] + Mp3Error(#[from] mp3::Mp3Error), + + #[cfg(feature="mockingbird-deemix")] + #[error("deemix error")] + DeemixError(#[from] deemix::DxError) +} + + +pub struct PlayRequest<'a> { + pub uri: &'a str, + + + #[cfg(feature = "mockingbird-deemix")] + pub dx: deemix::DxConfig +} + +pub async fn play_source<'a>( + req: PlayRequest<'a> +) -> Result +{ + const PATH_SZ: usize = 64; + + #[cfg(feature="mockingbird-ytdl")] + if ytdl::is_ytdl(req.uri) { + tracing::info!("streaming with ytdl: {}", req.uri); + return Ok(PlaySource::Ytdl { uri: req.uri.to_owned() }); + } + + let tmpdir = tempfile::tempdir()?; + let mut src = None; + + tracing::debug!("mkdir: {}", tmpdir.path().display()); + + #[cfg(feature="mockingbird-deemix")] + if deemix::is_deemix(req.uri) { + tracing::info!("Downloading deemix from {}", req.uri); + src = Some(deemix::deemix(req.uri, tmpdir.path().to_path_buf(), &req.dx).await?); + } + + #[cfg(feature="mockingbird-spotify")] + if deemix::is_spotify(req.uri) && src.is_none() { + tracing::info!("using spotify index lookup {}", req.uri); + src = Some(deemix::deemix(req.uri, tmpdir.path().to_path_buf(), &req.dx).await?); + } + + #[cfg(feature="mockingbird-mp3")] + if src.is_none() && req.uri.ends_with(".mp3") { + if let (resp, true) = mp3::is_mp3(req.uri).await? { + tracing::info!("Downloading mp3 from {}", req.uri); + src = Some(mp3::download(resp, &tmpdir.path().to_path_buf()).await?); + } + } + + match src { + None => return Err(SourceErrors::NoExtractor), + Some(PlaySource::FileSystem { ref errlog, ref ok_paths }) => + return Ok(src.unwrap()), + _ => unreachable!() + } +} + + +pub async fn init(mut cfg: ClientBuilder) -> ClientBuilder { + tracing::info!("Mockingbird extractors initialized"); + #[cfg(feature="mockingbird-deemix")] + { cfg = deemix::init(cfg).await; } + return cfg +} diff --git a/crates/coggiebot/src/controllers/mockingbird/extractor/mp3.rs b/crates/coggiebot/src/controllers/mockingbird/extractor/mp3.rs new file mode 100644 index 0000000..ef66a8d --- /dev/null +++ b/crates/coggiebot/src/controllers/mockingbird/extractor/mp3.rs @@ -0,0 +1,69 @@ +use tokio::io::{AsyncWriteExt}; +use serenity::futures::StreamExt; +use thiserror::Error; +use std::path::PathBuf; + +use super::PlaySource; + +#[derive(Error, Debug)] +pub enum Mp3Error { + #[error("io error")] + BadIO(#[from] std::io::Error), + + #[error("could not fetch http response")] + BadResponse(#[from] reqwest::Error), +} + +pub fn human_filesize(n: u64) -> String { + let base: u64 = 1024; + let suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + let i = (n as f64).log(base as f64).floor() as u32; + let power = base.pow(i); + let size = n as f64 / power as f64; + return format!("{}{}", size, suffixes[i as usize]); +} + +pub async fn is_mp3(uri: &str) -> Result<(reqwest::Response, bool), Mp3Error> { + let resp = reqwest::get(uri).await?; + let headers = resp.headers(); + let content_type = headers.get("Content-Type").unwrap(); + + if let Ok("audio/mpeg") = content_type.to_str() { + return Ok((resp, true)); + } + + tracing::error!("{}: content type is not audio/mpeg", uri); + return Ok((resp, false)); +} + +pub async fn download(resp: reqwest::Response, tmpdir: &PathBuf) -> Result { + // Content-Disposition: attachment; filename*=UTF-8''Geostigma.mp3 + let headers = resp.headers(); + let content_disposition = headers.get("Content-Disposition").unwrap(); + let filename = content_disposition.to_str().unwrap().split("filename*=UTF-8''").last().unwrap(); + + let fp = tmpdir.join(filename); + + tracing::info!("writing: {}", fp.display()); + let mut fd = tokio::fs::OpenOptions::new() + .write(true) + .create(true) + .open(&fp) + .await?; + + let mut stream = resp.bytes_stream(); + while let Some(item) = stream.next().await { + let chunk = item?; + fd.write_all(&chunk).await?; + } + + fd.flush().await?; + fd.sync_all().await?; + + tracing::info!("wrote: {} [{}]", fp.display(), human_filesize(fd.metadata().await?.len())); + + return Ok(PlaySource::FileSystem { + errlog: String::new(), + ok_paths: vec![fp], + }); +} diff --git a/crates/coggiebot/src/controllers/mockingbird/extractor/ytdl.rs b/crates/coggiebot/src/controllers/mockingbird/extractor/ytdl.rs new file mode 100644 index 0000000..ec8e42c --- /dev/null +++ b/crates/coggiebot/src/controllers/mockingbird/extractor/ytdl.rs @@ -0,0 +1,27 @@ +use songbird::input::Restartable; + +pub fn is_ytdl(uri: &str) -> bool { + const YTDL_HANDLES: [&'static str; 3] = [ + "youtube.com", + "youtu.be", + "soundcloud.com", + ]; + YTDL_HANDLES.iter().any(|x| uri.contains(x)) +} + +pub async fn ytdl(uri: String) -> Result { + Restartable::ytdl(uri, true).await +} + +#[cfg(tests)] +mod tests { + use std::env::var; + use std::path::PathBuf; + + #[test] + #[cfg(feature="mockingbird-ytdl")] + fn path_ytdl() { + let paths = var("PATH").unwrap(); + assert!(paths.split(':').filter(|p| PathBuf::from(p).join("yt-dlp").exists()).count() == 1); + } +} diff --git a/crates/coggiebot/src/controllers/mockingbird/mod.rs b/crates/coggiebot/src/controllers/mockingbird/mod.rs new file mode 100644 index 0000000..41d398c --- /dev/null +++ b/crates/coggiebot/src/controllers/mockingbird/mod.rs @@ -0,0 +1,36 @@ +//! Example demonstrating how to make use of individual track audio events, +//! and how to use the `TrackQueue` system. +//! +//! Requires the "cache", "standard_framework", and "voice" features be enabled in your +//! Cargo.toml, like so: +//! +//! ```toml +//! [dependencies.serenity] +//! git = "https://github.com/serenity-rs/serenity.git" +//! features = ["cache", "framework", "standard_framework", "voice"] +//! ``` +//use super::lib::ArlToken; +// +use serenity::client::ClientBuilder; +use std::path::PathBuf; + +mod extractor; +pub mod controller; + +pub async fn init(cfg: ClientBuilder) -> ClientBuilder { + tracing::info!("Mockingbird initialized"); + return extractor::init(cfg).await; +} + +#[cfg(test)] +mod tests { + + use std::env::var; + use std::path::PathBuf; + + #[test] + fn path_ffmpeg() { + let paths = var("PATH").unwrap(); + assert!(paths.split(':').filter(|p| PathBuf::from(p).join("ffmpeg").exists()).count() >= 1); + } +} diff --git a/src/controllers/mod.rs b/crates/coggiebot/src/controllers/mod.rs similarity index 82% rename from src/controllers/mod.rs rename to crates/coggiebot/src/controllers/mod.rs index d39c3f5..1febf75 100644 --- a/src/controllers/mod.rs +++ b/crates/coggiebot/src/controllers/mod.rs @@ -2,14 +2,14 @@ #[path = "bookmark.rs"] mod bookmark; -#[cfg(feature = "mockingbird")] +#[cfg(feature = "mockingbird-core")] pub mod mockingbird; #[cfg(feature = "basic-cmds")] #[path = "basic.rs"] mod basic; -#[cfg(feature = "basic-cmds")] +#[cfg(feature = "list-feature-cmd")] #[path = "features.rs"] pub mod features; @@ -17,9 +17,9 @@ pub mod features; #[path = "prerelease.rs"] pub mod prerelease; +use serenity::async_trait; use serenity::model::prelude::Message; use serenity::{framework::StandardFramework, client::ClientBuilder}; -use serenity::async_trait; use serenity::model::{channel::Reaction, gateway::Ready}; use serenity::prelude::*; @@ -39,32 +39,28 @@ pub fn setup_framework(mut cfg: StandardFramework) -> StandardFramework { ["mockingbird"] => [mockingbird::MOCKINGBIRD_GROUP], ["basic-cmds"] => [basic::COMMANDS_GROUP], ["prerelease"] => [features::PRERELEASE_GROUP::PRERELEASE_GROUP], - ["list-feature-cmds"] => [features::LIST_FEATURE_CMDS_GROUP], + ["list-feature-cmd"] => [features::FEATURES_GROUP], ["help-cmd"] => [features::HELP_GROUP], - ["mockingbird", "demix"] => [mockingbird::DEMIX_GROUP] + ["mockingbird-core", "mockingbird-playback"] => [mockingbird::controller::DEEMIX_GROUP] } ); cfg } #[allow(unused_mut)] -pub fn setup_state(mut cfg: ClientBuilder) -> ClientBuilder { - #[cfg(feature = "mockingbird")] +pub async fn setup_state(mut cfg: ClientBuilder) -> ClientBuilder { + #[cfg(feature = "mockingbird-core")] { use songbird::SerenityInit; + use mockingbird::init as mockingbird_init; cfg = cfg.register_songbird(); - - #[cfg(feature = "demix")] - { - use mockingbird::demix::{Demix, ArlToken}; - cfg = cfg.type_map_insert::(String::from(arl)); - } + cfg = mockingbird_init(cfg).await; } - cfg } pub struct EvHandler; + #[async_trait] impl EventHandler for EvHandler { @@ -82,7 +78,7 @@ impl EventHandler for EvHandler { #[allow(unused_variables)] async fn message(&self, ctx: Context, msg: Message) { - #[cfg(feature="enable-dj-room")] + #[cfg(feature="mockingbird-channel")] tokio::spawn(async move { const DJ_CHANNEL: u64 = 960044319476179055; let bot_id = ctx.cache.current_user_id().0; diff --git a/src/controllers/prerelease.rs b/crates/coggiebot/src/controllers/prerelease.rs similarity index 100% rename from src/controllers/prerelease.rs rename to crates/coggiebot/src/controllers/prerelease.rs diff --git a/src/main.rs b/crates/coggiebot/src/main.rs similarity index 70% rename from src/main.rs rename to crates/coggiebot/src/main.rs index e792c84..3a47d55 100644 --- a/src/main.rs +++ b/crates/coggiebot/src/main.rs @@ -1,8 +1,30 @@ mod controllers; -mod pkglib; -mod config; use std::env; +// +// TODO: +// arl scraper +// add cleanup-dl-perl systemd service to clean up old downloads +// - use nix to deploy it along side coggiebot +// - add to coggiebot `Wants` systemd service +// +// add dl features +// +// +// Later: +// port deemix to rust +// streaming pass on deemix +// use spotify api to go through a top down priority check list +// for getting retrieving songs +// +// +// feature-list: +// use env var at build-time `COGGIE_FEATURES` +// in the format of a comma separated list +// with boolean values to indicate enabled/disabled features +// example: +// COGGIE_FEATURES="mockingbird-core=1,bookmark=0" + use serenity::framework::standard::StandardFramework; use serenity::http::Http; @@ -43,10 +65,10 @@ struct CLI { #[structopt(long = "license")] license: bool, - // #[cfg(feature="list-feature-cmd")] - // #[structopt(long = "list-features", alias="features-list")] - // /// list all features if enabled - // features: bool, + #[cfg(feature="list-feature-cmd")] + #[structopt(long = "list-features", alias="features-list")] + /// list all features if enabled + features: bool, /// Access Token #[structopt(long = "token", env = EnvVars::DISCORD_TOKEN)] @@ -59,8 +81,6 @@ struct CLI { #[tokio::main] async fn main() -> Result<(), Box> { - let conf = config::Configuration::default(); - let cli = CLI::from_args(); if cli.version { println!("{VERSION}"); @@ -72,14 +92,21 @@ async fn main() -> Result<(), Box> println!("{}", get_rev()); return Ok(()); } + #[cfg(feature="list-feature-cmd")] if cli.features { - println!("{:?}", controllers::features::feature_list()); + println!("{}", controllers::features::feature_list() + .iter() + .map(|(f, toggle)| format!("{}: {}", f, toggle)) + .collect::>() + .join("\n")); return Ok(()); } println!("{}", LICENSE); + tracing_subscriber::fmt::init(); + let http = Http::new(&cli.token); let bot_id = http.get_current_user().await?.id; @@ -99,6 +126,7 @@ async fn main() -> Result<(), Box> Client::builder(&cli.token, GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT) .framework(framework) .event_handler(controllers::EvHandler)) + .await .await?; client.start().await?; diff --git a/flake.nix b/flake.nix index 9c2e4f8..fb2eb24 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,4 @@ { - description = "Open source discord utility bot"; inputs = { nixpkgs.url = "nixpkgs/nixpkgs-unstable"; @@ -26,55 +25,26 @@ recursiveMerge = pkgs.callPackage ./iac/lib.nix {}; cogpkgs = pkgs.callPackage ./iac/coggiebot/default.nix { inherit naerk-lib self recursiveMerge; }; - features = with cogpkgs.features; [ - basic-cmds - bookmark - mockingbird - ]; + features = (with cogpkgs.features; [ + basic-cmds + bookmark + list-feature-cmd + mockingbird + mockingbird-ytdl + mockingbird-deemix + mockingbird-mp3 + mockingbird-playback + mockingbird-spotify + mockingbird-hard-cleanfs + ]); coggiebot-stable = cogpkgs.mkCoggiebot { features-list = features; }; - config = { - prefixes = []; - bookmark_emoji = "\u{1F516}"; - dj_room = [ 123456789 ]; - features = (cogpkgs.which-features coggiebot-stable); - }; - - coggiebot-dummy = hash: stdenv.mkDerivation { - name = "coggiebot"; - phases = "buildPhase"; - buildPhase = '' - mkdir -p $out/bin/ - cat > $out/bin/$name < \$(date +%s) ]]; do - sleep 5 - done - fi - EOF - chmod +x $out/bin/$name - ''; - }; + non-nixos = (pkgs.callPackage ./iac/linux) { features=cogpkgs.features; }; - vanilla-linux = (pkgs.callPackage ./iac/vanilla-linux/default.nix) { + vanilla-linux = non-nixos { inherit installDir; coggiebot = coggiebot-stable; repo = { @@ -85,42 +55,38 @@ }; }; - deploy-dummy = hash: (pkgs.callPackage ./iac/vanilla-linux/default.nix) { - inherit installDir; - update-heartbeat = "2sec"; - coggiebot = (coggiebot-dummy hash); - repo = { - name = "coggie-bot"; - owner = "skarlett"; - branch = "better-ci"; - deploy = "deploy-workflow-ci-stage-2"; - }; + cictl = pkgs.callPackage ./sbin/cachectl { + inherit installDir non-nixos; + flakeUri = "github:skarlett/coggie-bot"; + caches = [ + { cachix = true; + url = "https://coggiebot.cachix.org"; + uid = "coggiebot"; + } + ]; + packages = [{ + ns = "coggiebot-stable"; + drv = coggiebot-stable; + }]; }; - - # Automatically adds a pre-release if able to - # beta-features is hard coded with the purpose of - # each branch specifying the exact features its developing - coggiebot-pre-release = - cogpkgs.mkCoggiebot { - features-list = with cogpkgs.features; - [ mockingbird ]; - }; in - (if (lib.lists.elem cogpkgs.features.pre-release features) - then { packages.coggiebot-pre-release = coggiebot-pre-release; } - else {} // - rec { - packages.deploy-workflow-ci = (deploy-dummy "00000000000000000000000000").deploy; - packages.deploy-workflow-ci-stage-2 = (deploy-dummy (self.rev or "canary")).deploy; - # packages.systemd = vanilla-linux.systemd; - # packages.ci-deploy-stage-1 = deploy-workflow-ci.deploy; - # packages.ci-deploy-stage-2 = deploy-workflow-ci.update; + packages.check-cache = cictl.check; + + packages.deemix-stream = pkgs.callPackage ./sbin/deemix-stream { + inherit (pkgs.python39.pkgs) buildPythonApplication; + }; + packages.cleanup-downloads = pkgs.callPackage ./sbin/cleanup-dl { + perlPackages = pkgs.perl534Packages; + }; + + packages.deploy = vanilla-linux; packages.default = coggiebot-stable; packages.coggiebot-stable = coggiebot-stable; - packages.deploy = vanilla-linux.deploy; - }))) packages; + + packages.coggiebot = coggiebot-stable; + })) packages; nixosModules.coggiebot = {pkgs, lib, config, ...}: with lib; @@ -168,30 +134,5 @@ }; }; }; - - checks = flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; }; - tests = pkgs.callPackage (nixpkgs + "/nixos/lib/testing-python.nix") {}; - in - { - vmTest = tests.makeTest { - nodes = { - - client = { ... }: { - imports = [ ]; - }; - }; - - testScript = - '' - start_all() - client.wait_for_unit("multi-user.target") - assert "Hello Nixers" in client.wait_until_succeeds("curl --fail http://localhost:8080/") - ''; - }; - }); - - }; } diff --git a/iac/coggiebot/default.nix b/iac/coggiebot/default.nix index fb1c715..00f7f99 100644 --- a/iac/coggiebot/default.nix +++ b/iac/coggiebot/default.nix @@ -9,16 +9,7 @@ let debug = expr: builtins.trace expr expr; meta = pkgs.callPackage ./meta.nix { }; - - deemix-extractor = stdenv.mkDerivation { - name = "deemix-extractor"; - installCommand = '' - mkdir -p $out/bin - cp pipe_demix $out/bin/pipe_demix - chmod +x $out/bin/pipe_demix - ''; - # pythonPackages = (py: [ py.deemaix py.click ]); - }; + # deemix-stream = pkgs.callPackage ../sbin/deemix-stream {}; mkCommand = { # list of strings @@ -34,24 +25,28 @@ let }: { inherit action examples doc filters; }; # these are - genericFeature = { - name + genericFeature = args@{ + name, + fname ? null # override function , pkg-override ? (c: c) , maintainers ? [meta.maintainers.lunarix] # list of strings in the features , dependencies ? [] - , commands ? [] - , config ? {} - }: + , rustFeature ? true + , commands ? [] }: { + ${name} = { inherit dependencies pkg-override commands maintainers - config; + rustFeature; featureName = "${name}"; + flagName = + if fname == null then "${name}" + else fname; }; }; @@ -64,8 +59,13 @@ let recursiveMerge ( (lib.foldl (s: x: s ++ [(genericFeature x)]) [] [ - { - name = "basic-cmds"; + { + name = "list-feature-cmd"; + pkg-override = (prev: { + COGGIEBOT_FEATURES = lib.concatStringsSep "," (map (x: "${x.featureName}=${if x.enabled then "1" else "0"}") prev.passthru.available-features); + }); + } + { name = "basic-cmds"; commands = [ mkCommand { aliases = [ "rev" ]; @@ -73,8 +73,7 @@ let default = "canary build"; }]; } - { - name = "pre-release"; + { name = "pre-release"; commands = [ mkCommand { aliases = [ "prerelease" ]; @@ -82,7 +81,6 @@ let examples = [ "@botname prerelease " ]; }]; } - { name = "bookmark"; commands = [(mkCommand { config.emote = "\u{1F516}"; @@ -90,22 +88,20 @@ let action = "emote"; })]; } - { name = "list-feature-cmd"; } { name = "prerelease"; pkg-override = (prev: { prev.buildInputs = prev.buildInputs ++ [ pkgs.git ]; }); } - { - name = "mockingbird"; + { name = "mockingbird"; + fname = "mockingbird-core"; pkg-override = (prev: rec { buildInputs = with pkgs; prev.buildInputs ++ [ libopus ffmpeg - yt-dlp ]; nativeBuildInputs = with pkgs; prev.nativeBuildInputs ++ [ @@ -119,6 +115,7 @@ let --prefix PATH : ${lib.makeBinPath buildInputs} ''; }); + commands = map(x: (mkCommand x)) [ { aliases = ["queue" "play"]; @@ -150,33 +147,75 @@ let doc = "joins the voice channel"; } ]; } + + # { name = "auto-update"; + # rustFeature = false; + # } + # { name = "systemd-helpers"; + # rustFeature = false; + # } + # { name = "systemd-integration-tests"; + # rustFeature = false; + # } + { - name = "demix"; - pkg-override = - (prev: - { - buildInputs = prev.buildInputs ++ [ deemix-extractor ]; - nativeBuildInputs = prev.nativeBuildInputs ++ [pkgs.cmake]; - } - ); + name = "mockingbird-deemix"; + pkg-override = (prev: rec { + buildInputs = prev.buildInputs ++ [ pkgs.python39Packages.deemix ]; + postInstall = prev.postInstall + '' + wrapProgram $out/bin/coggiebot \ + --prefix PATH : ${lib.makeBinPath buildInputs} + ''; + }); dependencies = [ "mockingbird" ]; commands = map(x: (mkCommand x)) - [{ - aliases = ["overlay:queue"]; - doc = "modifies the play/queue commands to use deezer's backend to stream audio"; - examples = [ "@botname " ]; - config = { - arl = { - default = ""; - type = "string"; - description = "deezer arl token"; - }; + [{ + aliases = ["overlay:queue"]; + doc = "modifies the play/queue commands to use deezer's backend to stream audio"; + examples = [ "@botname " ]; + config = { + arl = { + default = ""; + type = "string"; + description = "deezer arl token"; }; - }]; + }; + }]; + } + { name = "mockingbird-hard-cleanfs"; + dependencies = ["mockingbird-playback"]; + } + + { + name = "mockingbird-deemix"; + pkg-override = (prev: rec { + buildInputs = prev.buildInputs ++ [ pkgs.python39Packages.deemix ]; + nativeBuildInputs = prev.nativeBuildInputs ++ [pkgs.cmake pkgs.gcc]; + postInstall = prev.postInstall + '' + wrapProgram $out/bin/coggiebot \ + --prefix PATH : ${lib.makeBinPath buildInputs} + ''; + }); + + dependencies = [ "mockingbird" ]; + commands = map(x: (mkCommand x)) + [{ + aliases = ["overlay:queue"]; + doc = "modifies the play/queue commands to use deezer's backend to stream audio"; + examples = [ "@botname " ]; + config = { + arl = { + default = ""; + type = "string"; + description = "deezer arl token"; + }; + }; + }]; } + { - name = "dj-room"; + name = "mockingbird-channel"; dependencies = [ "mockingbird" ]; commands = map(x: (mkCommand x)) [{ @@ -192,20 +231,57 @@ let }; }]; } + + { + name = "mockingbird-ytdl"; + dependencies = [ "mockingbird" ]; + + pkg-override = (prev: rec { + buildInputs = prev.buildInputs ++ [ pkgs.yt-dlp ]; + + postInstall = prev.postInstall + '' + wrapProgram $out/bin/coggiebot \ + --prefix PATH : ${lib.makeBinPath buildInputs} + ''; + + }); + } + { + name = "mockingbird-playback"; + } + { + + name = "mockingbird-spotify"; + dependencies = [ "mockingbird-deemix" ]; + + } + + { + name = "mockingbird-mp3"; + dependencies= ["mockingbird"]; + pkg-override = (prev: rec { + nativeBuildInputs = + prev.nativeBuildInputs ++ + (with pkgs; [ pkgconfig openssl ]); + }); + } ]) ); all-features-list = lib.mapAttrsToList (_: v: v) features; - # create a list of all features, add a boolean field (enabled) to signify - # if coggiebot has that feature enabled - which-features-list = coggiebot: + which-features-list' = l: lib.foldl (s: f: s - # if the feature is enabled, add a new field and set it to 1 - ++ [({enabled = lib.lists.any (x: x == f) coggiebot.passthru.features-list;} // f)]) + ++ [({enabled = lib.lists.any (x: x == f) l;} // f)]) [] all-features-list; + # create a list of all features, add a boolean field (enabled) to signify + # if coggiebot has that feature enable add a new field named `enabled `and set it to + # 1 for enabled, and 0 for disabled + which-features-list = coggiebot: + which-features-list' coggiebot.passthru.features-list; + coggiebot-default-args = features-list: { name = "coggiebot"; nativeBuildInputs = []; @@ -218,27 +294,29 @@ let postInstall = ""; passthru = { inherit features-list meta; + available-features = which-features-list' features-list; + + hasFeature = feat: builtins.elem feat features-list; }; }; # New line separated. # The suffix number describes if the feature name was enabled. (1: enabled, 0: disabled) # The delimiter ':' is used to separate the feature name from the suffix. - build-profile = - (coggiebot-drv: (pkgs.writeTextDir - "share/coggiebot-profile.json" - builtins.toJSON (meta // { - features = (which-features-list coggiebot-drv); - buildInputs = map (drv: drv.name || drv.pname) coggiebot-drv.buildInputs; - nativeBuildInputs = map (drv: drv.name || drv.pname) coggiebot-drv.nativeBuildInputs; - }))); + # build-profile = + # (coggiebot-drv: (pkgs.writeTextDir + # "share/coggiebot-profile.json" + # builtins.toJSON (meta // { + # features = (which-features-list coggiebot-drv); + # buildInputs = map (drv: drv.name || drv.pname) coggiebot-drv.buildInputs; + # nativeBuildInputs = map (drv: drv.name || drv.pname) coggiebot-drv.nativeBuildInputs; + # }))); in rec { inherit meta which-features-list all-features-list - build-profile genericFeature features; @@ -250,13 +328,13 @@ rec { enabled-filter = lib.filter (f: f.enabled); marked-features-list = which-features-list coggiebot; - marked-features = lib.foldl (s: x: (s // { ${x.featureName} = x;})) - {} + marked-features = lib.foldl (s: x: (s // { ${x.featureName} = x;})) {} marked-features-list; - map-features = map (x: marked-features.${x}); - - deps-on-self = lib.filter (f: lib.lists.any (x: x == f.featureName) f.dependencies) all-features-list; + deps-on-self = + lib.filter + (f: lib.lists.any (x: x == f.featureName) f.dependencies) + all-features-list; recursive-missing = filter: f: let @@ -295,7 +373,6 @@ rec { nonexistent-deps } '' - else if (deps-on-self != []) then throw '' The following features depend on themselves: @@ -304,7 +381,6 @@ rec { deps-on-self } '' - else if ((enabled-features-with-missing-dependencies) != []) then throw '' The following features are enabled but have missing dependencies: @@ -313,12 +389,18 @@ rec { enabled-features-with-missing-dependencies } '' - else coggiebot; - # Force build to have no default features enabled - # MkCoggiebot' { } -> naesrk-lib.buildPackage -> mkDerivation + + # Top level build tool + ###################### + # MkCoggiebot + # +-> apply-features + # | -> buildInputs + # | -> naesrk-lib.buildPackage + # | -> mkDerivation + # +-> Generate systemd services mkCoggiebot = { coggiebot ? coggiebot-default-args, features-list ? [], @@ -326,28 +408,18 @@ rec { }: let coggie = coggiebot features-list; - - pkg = + pkg = # Apply features lib.foldl (c: f: c // (f.pkg-override c)) coggie coggie.passthru.features-list; - - drv = + in (naerk-lib.buildPackage ((dependency-check pkg) // { - cargoBuildOptions= - l: l - ++ ["--no-default-features"] - ++ (lib.optional (pkg.passthru.features-list != []) - ["--features"] ++ [(lib.concatStringsSep "," - (lib.foldl (s: x: s ++ [x.featureName]) [] pkg.passthru.features-list) - )]); + cargoBuildOptions= + l: l + ++ ["--no-default-features"] + ++ (lib.optional (pkg.passthru.features-list != []) + ["--features"] ++ [(lib.concatStringsSep "," + (lib.foldl (s: x: s ++ [x.flagName]) [] + (builtins.filter (x: x.rustFeature) pkg.passthru.features-list)) + )]); })); - in - pkgs.symlinkJoin { - name = "coggiebot"; - paths = [ - drv - # ( build-profile coggie ) - - ]; - }; -} + } diff --git a/iac/linux/auto-update/default.nix b/iac/linux/auto-update/default.nix new file mode 100644 index 0000000..8a99cff --- /dev/null +++ b/iac/linux/auto-update/default.nix @@ -0,0 +1,134 @@ +{ + lib + , pkgs + , stdenv + , coggiebot + , coggiebotd + + , installDir ? "/var/coggiebot" + , repo + , buildFromSrc ? true + , update-heartbeat ? "15min" +}: + +let + migrate = stdenv.mkDerivation rec { + name = "migrate"; + phases = "buildPhase"; + pull = "github:Skarlett/coggie-bot/master#deploy"; + + buildPhase = '' + mkdir -p $out/bin/ + cat >> $out/bin/${name} <> $out/bin/$name <\$LOCKFILE + + if ! flock -x -w 1 \$FD; then + echo "Failed to obtain a lock" + echo "Another instance of `basename \$0` is probably running." + exit 1 + else + echo "Lock acquired" + fi + + # Fetch latest commit + FETCH_DIR=\$(mktemp -d -t "coggie-bot.update.XXXXXXXX") + pushd \$FETCH_DIR + git init . + git remote add origin \$URI + git fetch origin \$BRANCH + LHASH=\$(git show -s --pretty='format:%H' origin/\$BRANCH | sort -r | head -n 1) + popd + rm -rf \$FETCH_DIR + + # hard coded link into nix store + CHASH=\$(${coggiebot}/bin/coggiebot --built-from --token "") + + # + # Dont replace canary (in source build) + # + if [[ \$CHASH == "canary" || \$LHASH == "canary" ]]; then + echo "canary build -- nonapplicable" + exit 0 + fi + + if [[ "\$CHASH" != "\$LHASH" ]]; then + echo "start migrating" + ${migrate}/bin/migrate + echo "migrating finished" + fi + + rm -f \$LOCKFILE + EOF + chmod +x $out/bin/$name + ''; + + nativeBuildInputs = [ + pkgs.coreutils + pkgs.git + coggiebot + migrate + ]; + + PATH = lib.makeBinPath nativeBuildInputs; + }; + + localSystemdFiles = pkgs.callPackage ./systemd.nix { + inherit coggiebot coggiebotd update-heartbeat updater; + }; +in + { inherit updater migrate; } // localSystemdFiles diff --git a/iac/linux/auto-update/systemd.nix b/iac/linux/auto-update/systemd.nix new file mode 100644 index 0000000..14fa63b --- /dev/null +++ b/iac/linux/auto-update/systemd.nix @@ -0,0 +1,60 @@ +{ + config + , lib + , pkgs + , stdenv + , coggiebot + , update-heartbeat + , coggiebotd + , updater +}: +rec { + coggiebotd-update = stdenv.mkDerivation rec { + name = "coggiebotd-update.service"; + phases = "buildPhase"; + buildPhase = '' + #!/bin/sh + mkdir -p $out/etc + cat >> $out/etc/$name <> $out/etc/$name <> $out/bin/$name <> $out/bin/$name <> $out/etc/$name <> $out/etc/$name <> $out/etc/$name <> $out/etc/$name <> $out/bin/$name <> $out/bin/${name} <> $out/bin/$name <\$LOCKFILE - - if ! flock -x -w 1 \$FD; then - echo "Failed to obtain a lock" - echo "Another instance of `basename \$0` is probably running." - exit 1 - else - echo "Lock acquired" - fi - - # Fetch latest commit - FETCH_DIR=\$(mktemp -d -t "coggie-bot.update.XXXXXXXX") - pushd \$FETCH_DIR - git init . - git remote add origin \$URI - git fetch origin \$BRANCH - LHASH=\$(git show -s --pretty='format:%H' origin/\$BRANCH | sort -r | head -n 1) - popd - rm -rf \$FETCH_DIR - - # hard coded link into nix store - CHASH=\$(${coggiebot}/bin/coggiebot --built-from --token "") - - # - # Dont replace canary (in source build) - # - if [[ \$CHASH == "canary" || \$LHASH == "canary" ]]; then - echo "canary build -- nonapplicable" - exit 0 - fi - - if [[ "\$CHASH" != "\$LHASH" ]]; then - echo "start migrating" - PULL="github:\$AUTHOR/\$REPO/\$BRANCH#\$DEPLOY_PKG " . ${migrate}/bin/migrate - echo "migrating finished" - fi - - rm -f \$LOCKFILE - EOF - chmod +x $out/bin/$name - ''; - - nativeBuildInputs = [ - pkgs.coreutils - pkgs.git - coggiebot - migrate - ]; - - PATH = lib.makeBinPath nativeBuildInputs; - }; - - systemd-enable = pkgs.stdenv.mkDerivation rec { - name = "systemd-enable"; - phases = "buildPhase"; - - buildPhase = '' - #!/bin/sh - mkdir -p $out/bin - cat >> $out/bin/$name <> $out/bin/$name <> $out/bin/$name <> $out/bin/$name <> $out/bin/$name <> $out/bin/$name < $out/bin/$name < \$(date +%s) ]]; do + sleep 5 + done + fi + EOF + chmod +x $out/bin/$name + ''; + }; + + dummy-install = attr: non-nixos + ({ + inherit installDir; + update-heartbeat = "5sec"; + coggiebot = coggiebot-dummy "0000000000000000000000"; + repo = { + name = "coggie-bot"; + owner = "skarlett"; + deploy = "deploy-workflow-ci-stage-2"; + }; + } // attr); +in +{ + check = + let name = "check-cache"; + in stdenv.mkDerivation { + inherit name; + phases = "buildPhase"; + buildPhase = '' + mkdir -p $out/bin + cat > $out/bin/$name < 'Coggiebot::cleanupDL', + AUTHOR => q{Coggie }, + VERSION_FROM => 'cleanup-downloads.pl', + ABSTRACT => 'Cleans files (which are not opened) for coggiebot', + ( $ExtUtils::MakeMaker::VERSION >= 6.3002 + ? ( 'LICENSE' => 'perl' ) + : () ), + PL_FILES => {}, + PREREQ_PM => { + 'Set::Object' => 1.40, + } +); diff --git a/sbin/cleanup-dl/bin/cleanup-downloads.pl b/sbin/cleanup-dl/bin/cleanup-downloads.pl new file mode 100644 index 0000000..014267f --- /dev/null +++ b/sbin/cleanup-dl/bin/cleanup-downloads.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +package Coggiebot::cleanupDL; +use strict; +use warnings; +use Set::Object qw(set); + +our $VERSION = 0.1; + +my $inuse=`lsof +D $1 | tr -s ' ' | cut -d ' ' -f 9-`; +my @inuse_arr=split("\n", $inuse); +my $inuse_set = Set::Object->new(); +$inuse_set->insert(@inuse_arr); + +my $old=`find $1 -ctime +30min`; +my @old_arr=split("\n", $old); +my $old_set=Set::Object->new(); +$old_set->insert(@old_arr); + +my $remove=$old_set - $inuse_set; +print(@remove); + + diff --git a/sbin/cleanup-dl/cleanup-downloads.pl b/sbin/cleanup-dl/cleanup-downloads.pl new file mode 100644 index 0000000..2f35039 --- /dev/null +++ b/sbin/cleanup-dl/cleanup-downloads.pl @@ -0,0 +1,76 @@ +#!/usr/bin/env perl +package Coggiebot::cleanupDL; + +use strict; +use warnings; + +use Fcntl ':flock'; # import LOCK_* constants +use Set::Object qw(set); + +our $VERSION = 0.1; + +my $CACHE = $ENV('COG_MCACHE') or die "COG_MCACHE not set"; +my $CACHE_LOOKUP = $ENV('COG_MLOOKUP') or die "COG_MLOOKUP not set"; +my $CACHE_EXPIRE = $ENV('COG_MEXPIRE') or die "COG_MEXPIRE not set"; +my $QUEUED = $ENV('COG_MQUEUE') or die "COG_MQUEUE not set"; + +my $EXCEPTIONS = Set::Object->new(); + +sub except_queued() { + # files queued for playing + open(my $fh, 'r', "$QUEUE" or die $!; + flock($fh, LOCK_EX) or die "Cannot lock playlist queue - $!\n"; + + # read the file and + # convert symlinks to filepath + while (<$fh>) { + chomp; + $EXCEPTION->insert(readlink $_); + } + close($fh) +} + +sub except_opened() { + # Find files still in use + my $inuse=`lsof +D $CACHE | sed -n '1d;p' | tr -s ' ' | cut -d ' ' -f 9- | sort -u`; + my @inuse_arr=split("\n", $inuse); + + $EXCEPTION->insert(@inuse_arr); +} + +sub cleanup() { + # Find all files older than 20 minutes + my $old=`find $CACHE -type f -cmin +$EXPIRE`; + my @old_arr=split("\n", $old); + $old_set->insert(@old_arr); + + # Exclude files that are still in use from being deleted + my $remove = $old_set - $EXCEPTION; + for my $file ($remove->members()) { + if (-f $file) { + print "deleting: $file\n"; + unlink $file; + } + } + + for my $file `ls $CACHE_LOOKUP` { + if (! -e readlink $file) { + print "deleting lookup: $file\n"; + unlink $file; + } + } +} + +sub init() { + `mkdir -p $CACHE $CACHE_LOOKUP`; + if (! -e $QUEUED) { + `touch $QUEUED`; + } +} + +sub main() { + init(); + except_queued(); + except_opened(); + cleanup(); +} diff --git a/sbin/cleanup-dl/default.nix b/sbin/cleanup-dl/default.nix new file mode 100644 index 0000000..ed113bf --- /dev/null +++ b/sbin/cleanup-dl/default.nix @@ -0,0 +1,25 @@ + +{ perlPackages }: +with perlPackages; +buildPerlPackage { + pname = "coggie-cleanup-deemix"; + version = "0.1.0"; + outputs = ["out"]; + + src = ./.; + propagatedBuildInputs = [ SetObject ]; + preConfigure = '' + echo "LIB = ${SetObject.out}/lib" > config.in + ''; + + postInstall = '' + mkdir -p $out/bin + cp cleanup-downloads.pl $out/bin/coggie-cleanup-deemix + chmod +x $out/bin/coggie-cleanup-deemix + ''; + + meta = { + description = "A script to clean up old files in a directory"; + }; + +} diff --git a/sbin/pipe_demix b/sbin/pipe_demix deleted file mode 100644 index 60b7770..0000000 --- a/sbin/pipe_demix +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 -import click -import requests -import sys -from pathlib import Path - -from deezer import Deezer -from deezer import TrackFormats -from deemix.types.Track import Track -from deemix import generateDownloadObject, parseLink -from deemix.settings import DEFAULTS as DEFAULT_SETTINGS, load as loadSettings -from deemix.utils import getBitrateNumberFromText, formatListener -import deemix.utils.localpaths as localpaths -from deemix.downloader import Downloader, getPreferredBitrate, extensions, formatsName, streamTrack, tagID3, tagFLAC -from deemix.itemgen import GenerationError -from deemix.itemgen import generateTrackItem -from deemix.errors import DownloadFailed, MD5NotFound, DownloadCanceled, PreferredBitrateNotFound, TrackNot360, AlbumDoesntExists, DownloadError, ErrorMessages -from deezer.errors import WrongLicense, WrongGeolocation - -try: - from deemix.plugins.spotify import Spotify -except ImportError: - Spotify = None - -dz = Deezer() -settings = DEFAULT_SETTINGS - -def stream_stdout(downloader, extraData, track=None): - returnData = {} - trackAPI = extraData.get('trackAPI') - albumAPI = extraData.get('albumAPI') - playlistAPI = extraData.get('playlistAPI') - trackAPI['size'] = downloader.downloadObject.size - if downloader.downloadObject.isCanceled: raise DownloadCanceled - if int(trackAPI['id']) == 0: raise DownloadFailed("notOnDeezer") - - itemData = { - 'id': trackAPI['id'], - 'title': trackAPI['title'], - 'artist': trackAPI['artist']['name'] - } - - # Create Track object - if not track: - downloader.log(itemData, "getTags") - try: - track = Track().parseData( - dz=downloader.dz, - track_id=trackAPI['id'], - trackAPI=trackAPI, - albumAPI=albumAPI, - playlistAPI=playlistAPI - ) - except AlbumDoesntExists as e: - raise DownloadError('albumDoesntExists') from e - except MD5NotFound as e: - raise DownloadError('notLoggedIn') from e - downloader.log(itemData, "gotTags") - - itemData = { - 'id': track.id, - 'title': track.title, - 'artist': track.mainArtist.name - } - - # Check if track not yet encoded - if track.MD5 == '': raise DownloadFailed("notEncoded", track) - - # Choose the target bitrate - downloader.log(itemData, "getBitrate") - try: - selectedFormat = getPreferredBitrate( - downloader.dz, - track, - downloader.bitrate, - downloader.settings['fallbackBitrate'], downloader.settings['feelingLucky'], - downloader.downloadObject.uuid, downloader.listener - ) - except WrongLicense as e: - raise DownloadFailed("wrongLicense") from e - except WrongGeolocation as e: - raise DownloadFailed("wrongGeolocation", track) from e - except PreferredBitrateNotFound as e: - raise DownloadFailed("wrongBitrate", track) from e - except TrackNot360 as e: - raise DownloadFailed("no360RA") from e - track.bitrate = selectedFormat - track.album.bitrate = selectedFormat - downloader.log(itemData, "gotBitrate") - - # Apply settings - track.applySettings(downloader.settings) - - extension = extensions[track.bitrate] - track.downloadURL = track.urls[formatsName[track.bitrate]] - if not track.downloadURL: raise DownloadFailed('notAvailable', track) - - try: - with open(sys.stdout.fileno(), 'wb') as stream: - streamTrack(stream, track, downloadObject=downloader.downloadObject, listener=downloader.listener) - except requests.exceptions.HTTPError as e: - raise DownloadFailed('notAvailable', track) from e - except OSError as e: - if e.errno == errno.ENOSPC: raise DownloadFailed("noSpaceLeft") from e - raise e - - downloader.log(itemData, "downloaded") - downloader.downloadObject.completeTrackProgress(downloader.listener) - - if track.searched: returnData['searched'] = True - - downloader.downloadObject.downloaded += 1 - if downloader.listener: downloader.listener.send("updateQueue", { - 'uuid': downloader.downloadObject.uuid, - 'downloaded': True, - 'downloadPath': None, - 'extrasPath': str(downloader.downloadObject.extrasPath) - }) - -@click.command() -@click.option('-b', '--bitrate', default=None, help='Overwrites the default bitrate selected') -@click.option('--arl', '-a', help='Deezer ARL Token') -@click.argument('url', nargs=-1, required=True) -def stream(url, arl, bitrate): - assert arl, 'You must provide an ARL token' - assert dz.login_via_arl(arl.strip()), 'Invalid ARL' - if not bitrate: bitrate = settings.get("maxBitrate", TrackFormats.MP3_320) - (link, link_type, link_id) = parseLink(url[0]) - obj = generateTrackItem(dz, link_id, bitrate) - - extraData = { - 'trackAPI': obj.single.get('trackAPI'), - 'albumAPI': obj.single.get('albumAPI') - } - - downloader = Downloader(dz, obj, settings) - stream_stdout(downloader, extraData) - -if __name__ == '__main__': - stream() diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index 25a19c4..0000000 --- a/src/config.rs +++ /dev/null @@ -1,57 +0,0 @@ -use serde::{Deserialize, Serialize}; - - - -#[derive(Debug, Default)] -struct Bookmark { - emote: String, -} - - -#[derive(Debug, Default)] -pub struct Configuration { - prefixes: Vec, - repo: String, - commit: String, - - maintainers: Vec, - - - #[cfg(feature = "bookmark-emoji")] - bookmark: Bookmark, - - #[cfg(feature = "dj-room")] - dj_room: Vec, - - #[cfg(feature="list-feature-cmd")] - features: Vec, -} - -#[derive(Debug, Deserialize)] -struct Maintainer { - discordid: u64, - github: Option, - languages : Vec, -} - -#[derive(Debug, Deserialize)] -struct Feature { - name: String, - dependencies: Vec, - enabled: bool, - maintainers: Vec, -} - -struct Command { - aliases: Vec, - description: String, - example: String, - owner_only: bool, - hidden: bool, - guild_only: bool, - dm_only: bool, - nsfw: bool, - cooldown: u64, - sub_commands: Vec, - config: serde_json::Value, -} diff --git a/src/controllers/features.rs b/src/controllers/features.rs deleted file mode 100644 index ac80f43..0000000 --- a/src/controllers/features.rs +++ /dev/null @@ -1,115 +0,0 @@ -use crate::{REPO, pkglib::{CoggiebotError}}; -use serenity::model::prelude::Message; -use serenity::framework::standard::{ - macros::{command, group}, - CommandResult, -}; - -use std::{path::PathBuf, io::BufRead}; -use serenity::prelude::*; - -pub const FEATURES_FILE_ENV: &'static str = "COGGIEBOT_FEATURES"; - -struct FileFinder { - name: String, - paths: Vec, - env: Vec, -} - -impl FileFinder { - pub fn find_file(&self) -> Result { - let mut paths = self.paths.clone(); - for env_var in &self.env { - if let Ok(path) = std::env::var(env_var) { - paths.push(PathBuf::from(path)); - } - } - for path in paths.iter().rev() { - let file = path.join(&self.name); - if file.exists() { - return Ok(file); - } - } - - Err(CoggiebotError::UserMessage(format!( - "Could not find file {} in paths {:?}", - self.name, self.paths - ))) - } -} - -pub fn feature_list() -> anyhow::Result>> -{ - const STATIC_PATHS: [&'static str; 4] = [ - ".", - "./share", - "/usr/share/coggiebot/", - "/usr/local/share/coggiebot" - ]; - - let finder = FileFinder { - name: "coggiebot-features.lst".to_string(), - paths: STATIC_PATHS.iter().map(|s| PathBuf::from(*s)).collect(), - env: vec![FEATURES_FILE_ENV.to_string()], - }; - - let file = std::fs::File::open(finder.find_file()?)?; - let mut reader = std::io::BufReader::new(file); - let mut line = String::with_capacity(512); - - let mut features = Vec::new(); - while let Ok(nread) = reader.read_line(&mut line) - { - line.clear(); - if nread == 0 { - break; - } - let line = line.trim(); - if line.is_empty() || line.starts_with('#') { - continue; - } - features.push( - match line.split_once(":") { - Some((name, enabled_int)) => - match enabled_int.parse::() - { - Ok(1) => Ok((name.to_owned(), true)), - Ok(0) => Ok((name.to_owned(), false)), - Ok(n) => Err(CoggiebotError::UserMessage(format!("Invalid value for feature {}: {}", name, n))), - Err(_) => Err(CoggiebotError::UserMessage(format!("Expected integer, got: {:?}", enabled_int))), - } - - None => Err(CoggiebotError::UserMessage(format!("Invalid line in enabled-features: {}", line))) - } - ); - } - Ok(features) -} - - -#[group] -#[commands(features)] -pub struct Features; - -#[command("enabled-features")] -async fn features(ctx: &Context, msg: &Message) -> CommandResult { - let features = feature_list()?; - - msg.channel_id - .send_message(&ctx.http, |m| - m.add_embed(|e| - e.title("Coggie Bot") - .description("Coggie Bot is an open source \"Discord\" (discord.com) bot.") - .url(REPO) - .fields(features - .iter().map(|r| match r { - Ok((name, true)) => (name, "enabled", true), - Ok((name, false)) => (name, "disabled", true), - Err(CoggiebotError::UserMessage(msg)) =>(msg, "error", true), - _ => unreachable!(), - }) - ) - ) - ).await?; - Ok(()) -} diff --git a/src/controllers/mockingbird/demix.rs b/src/controllers/mockingbird/demix.rs deleted file mode 100644 index 07b96ed..0000000 --- a/src/controllers/mockingbird/demix.rs +++ /dev/null @@ -1,168 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{ - sync::Arc, - time::Duration, -}; - -use std::{ - io::{BufRead, BufReader, Read}, - process::{Command, Stdio}, - default::Default -}; -use tokio::{process::Command as TokioCommand, task}; - -use std::ffi::OsStr; -use serenity::{ - async_trait, - client::Context, - framework::{ - standard::{ - macros::{command, group}, - Args, - CommandResult, - }, - }, - http::Http, - model::{channel::Message, prelude::ChannelId}, - prelude::Mentionable, - Result as SerenityResult, -}; - -use songbird::{ - input::{ - self, - restartable::{Restartable, Restart}, - Input, - Container, - Codec, - Metadata, - error::Error as InputError, - children_to_reader, - }, - Event, - EventContext, - EventHandler as VoiceEventHandler, - TrackEvent, -}; - -#[group] -struct Demix; - -/// ARL tokens are used for deezer API access -struct ArlToken; -impl TypeMapKey for ArlToken { - type Value = String; -} - -struct DeezerRestarter

-{ - uri: P, - arl: String -} - -struct DeezerConfig -{ - pub arl_token: String, -} - -fn deezer(uri: &str, arl: &str, pre_args: &[&str]) -> Result -{ - let demix_args = [ - "--arl", arl, - "-b", "128000", - uri, - ]; - - let ffmpeg_args = [ - "-f", - "s16le", - "-ac", - "2", - "-ar", - "48000", - "-acodec", - "pcm_f32le", - "-", - ]; - - let mut demix_pipe = Command::new("pipe_demix") - .args(&demix_args) - .stdin(Stdio::null()) - .stderr(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn()?; - - let taken_stdout = demix_pipe.stdout.take().ok_or(InputError::Stdout)?; - let ffmpeg = Command::new("ffmpeg") - .args(pre_args) - .arg("-i") - .arg("-") - .args(&ffmpeg_args) - .stdin(taken_stdout) - .stderr(Stdio::null()) - .stdout(Stdio::piped()) - .spawn()?; - - //let metadata = Metadata::from_ytdl_output(value?); - - Ok(Input::new( - true, - children_to_reader::(vec![demix_pipe, ffmpeg]), - Codec::FloatPcm, - Container::Raw, - None, - )) -} - -#[async_trait] -impl Restart for DeezerRestarter -{ - async fn call_restart(&mut self, time: Option) -> Result - { - deezer(&self.uri, &self.arl, &[]) - } - async fn lazy_init(&mut self) -> Result<(Option, Codec, Container), InputError> - { - //deezer(&self.uri, &self.arl, &["-ss", "0:00:05"]) - todo!() - } -} - - -#[command("arl")] -async fn get_arl(ctx: &Context, msg: &Message) -> CommandResult { - let arl = ctx.data.read().await.get::().expect("Expected CommandCounter in TypeMap.").clone(); - msg.channel_id.say(&ctx.http, arl).await?; - Ok(()) -} - - -fn deezer_hook() { - let arl = match ctx.data.read().await.get::() { - Some(arl) => arl.clone(), - None => { - check_msg( - msg.channel_id - .say(&ctx.http, "No ARL token found") - .await, - ); - - return Ok(()); - } - }; - - let restarter = match deezer(&url, &arl, &[] ){ - Ok(src) => src, - Err(e) => { - check_msg( - msg.channel_id - .say(&ctx.http, format!("Error: {}", e)) - .await, - ); - return Ok(()); - } - }; -} - - - diff --git a/src/controllers/mockingbird/mod.rs b/src/controllers/mockingbird/mod.rs deleted file mode 100644 index f2118a0..0000000 --- a/src/controllers/mockingbird/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod mockingbird; - -#[cfg(feature = "demix")] -pub mod demix; - -static FEATURE: &'static str = "mockingbird"; - - -pub use mockingbird::*; diff --git a/src/pkglib.rs b/src/pkglib.rs deleted file mode 100644 index 1bc831a..0000000 --- a/src/pkglib.rs +++ /dev/null @@ -1,17 +0,0 @@ -use derive_builder::Builder; -use std::path::PathBuf; -use thiserror::Error; -use std::io::{BufReader, BufRead}; - -#[derive(Debug, Error)] -pub enum CoggiebotError { - - #[error("Error while sending request to Discord: {0}")] - UserMessage(String), - - #[error("Serenity error: {0}")] - SerenityError(#[from] serenity::Error), - - #[error("IO Error: {0}")] - IoError(#[from] std::io::Error), -} diff --git a/tickets.md b/tickets.md deleted file mode 100644 index 843281b..0000000 --- a/tickets.md +++ /dev/null @@ -1,11 +0,0 @@ - -- music streaming (deezers/soundcloud/etc) - - sampling feedback for error detection would be great - -- command to append tickets - -- README and Documentation templating engines - -- pair programming using cogit under the hood - -- Automated RFCs (Request for Comments) for projects from github issues