diff --git a/Cargo.lock b/Cargo.lock index ce1c21c..1a97900 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe0133578c0986e1fe3dfcd4af1cc5b2dd6c3dbf534d69916ce16a2701d40ba" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if 1.0.0", "cipher", @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" dependencies = [ "proc-macro2", "quote", @@ -134,9 +134,15 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" [[package]] name = "binascii" @@ -170,15 +176,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cached" @@ -219,9 +225,9 @@ checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cfg-if" @@ -237,16 +243,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ "iana-time-zone", "js-sys", "num-integer", "num-traits", "serde", - "time 0.1.44", + "time 0.1.45", "wasm-bindgen", "winapi 0.3.9", ] @@ -295,19 +301,19 @@ dependencies = [ [[package]] name = "cookie" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "aes-gcm", - "base64", + "base64 0.20.0", "hkdf", "hmac", "percent-encoding", "rand", "sha2", "subtle", - "time 0.3.15", + "time 0.3.17", "version_check", ] @@ -338,9 +344,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if 1.0.0", ] @@ -367,9 +373,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f83d0ebf42c6eafb8d7c52f7e5f2d3003b89c7aa4fd2b79229209459a849af8" +checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" dependencies = [ "cc", "cxxbridge-flags", @@ -379,9 +385,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d050484b55975889284352b0ffc2ecbda25c0c55978017c132b29ba0818a86" +checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" dependencies = [ "cc", "codespan-reporting", @@ -394,15 +400,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d2199b00553eda8012dfec8d3b1c75fce747cf27c169a270b3b99e3448ab78" +checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" [[package]] name = "cxxbridge-macro" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb67a6de1f602736dd7eaead0080cf3435df806c61b24b13328db128c58868f" +checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" dependencies = [ "proc-macro2", "quote", @@ -429,6 +435,16 @@ dependencies = [ "darling_macro 0.13.4", ] +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core 0.14.2", + "darling_macro 0.14.2", +] + [[package]] name = "darling_core" version = "0.12.4" @@ -457,6 +473,20 @@ dependencies = [ "syn", ] +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + [[package]] name = "darling_macro" version = "0.12.4" @@ -479,6 +509,17 @@ dependencies = [ "syn", ] +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core 0.14.2", + "quote", + "syn", +] + [[package]] name = "derive_builder" version = "0.10.2" @@ -551,9 +592,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer", "crypto-common", @@ -621,14 +662,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" +checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -698,9 +739,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -712,9 +753,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -722,33 +763,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-io" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-sink" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -763,9 +804,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7" +checksum = "d266041a359dfa931b370ef684cceb84b166beb14f7f0421f4a6a3d0c446d12e" dependencies = [ "cc", "libc", @@ -786,9 +827,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if 1.0.0", "libc", @@ -837,9 +878,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -869,6 +910,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hkdf" version = "0.12.3" @@ -929,9 +976,9 @@ checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" [[package]] name = "hyper" -version = "0.14.20" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -951,6 +998,19 @@ dependencies = [ "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" @@ -966,9 +1026,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.51" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1024,9 +1084,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -1088,15 +1148,15 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" @@ -1131,15 +1191,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.135" +version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" [[package]] name = "link-cplusplus" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" dependencies = [ "cc", ] @@ -1199,6 +1259,17 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "mime-db" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7c816ec30c41f873e1eea969aa2261d78756629e468a427244ff8658b75e7d" +dependencies = [ + "reqwest", + "serde", + "tokio", +] + [[package]] name = "mio" version = "0.6.23" @@ -1220,14 +1291,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1268,7 +1339,7 @@ dependencies = [ "log", "memchr", "mime", - "spin", + "spin 0.9.4", "tokio", "tokio-util", "version_check", @@ -1276,9 +1347,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", @@ -1294,9 +1365,9 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.37" +version = "0.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" dependencies = [ "cfg-if 0.1.10", "libc", @@ -1367,28 +1438,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ "hermit-abi", "libc", ] -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - [[package]] name = "once_cell" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -1398,9 +1460,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "29d971fd5722fec23977260f6e81aa67d2f22cadbdc2aa049f1022d9a3be1566" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1430,9 +1492,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.76" +version = "0.9.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" +checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4" dependencies = [ "autocfg", "cc", @@ -1459,15 +1521,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1510,9 +1572,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a" +checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" dependencies = [ "thiserror", "ucd-trie", @@ -1520,9 +1582,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2" +checksum = "cdc078600d06ff90d4ed238f0119d84ab5d43dbaad278b0e33a8820293b32344" dependencies = [ "pest", "pest_generator", @@ -1530,9 +1592,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db" +checksum = "28a1af60b1c4148bb269006a750cff8e2ea36aff34d2d96cf7be0b14d1bed23c" dependencies = [ "pest", "pest_meta", @@ -1543,9 +1605,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d" +checksum = "fec8605d59fc2ae0c6c1aefc0c7c7a9769732017c0ce07f7a9cfffa7b4404f20" dependencies = [ "once_cell", "pest", @@ -1605,9 +1667,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "podbringer" @@ -1617,6 +1679,7 @@ dependencies = [ "cached", "chrono", "enum_dispatch", + "mime-db", "reqwest", "rocket", "rocket_dyn_templates", @@ -1624,6 +1687,7 @@ dependencies = [ "thiserror", "url", "youtube_dl", + "ytextract", ] [[package]] @@ -1640,15 +1704,15 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] @@ -1678,9 +1742,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -1726,18 +1790,18 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12a733f1746c929b4913fe48f8697fcf9c55e3304ba251a79ffb41adfeaf49c2" +checksum = "8c78fb8c9293bcd48ef6fce7b4ca950ceaf21210de6e105a883ee280c0f7b9ed" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5887de4a01acafd221861463be6113e6e87275e79804e56779f4cdc131c60368" +checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f" dependencies = [ "proc-macro2", "quote", @@ -1746,9 +1810,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -1766,9 +1830,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -1781,11 +1845,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" dependencies = [ - "base64", + "base64 0.13.1", "bytes", "encoding_rs", "futures-core", @@ -1794,6 +1858,7 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls", "hyper-tls", "ipnet", "js-sys", @@ -1803,19 +1868,39 @@ dependencies = [ "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", "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 0.3.9", +] + [[package]] name = "rocket" version = "0.5.0-rc.2" @@ -1846,7 +1931,7 @@ dependencies = [ "serde_json", "state", "tempfile", - "time 0.3.15", + "time 0.3.17", "tokio", "tokio-stream", "tokio-util", @@ -1906,7 +1991,7 @@ dependencies = [ "smallvec", "stable-pattern", "state", - "time 0.3.15", + "time 0.3.17", "tokio", "uncased", ] @@ -1924,16 +2009,37 @@ dependencies = [ ] [[package]] -name = "rustversion" -version = "1.0.9" +name = "rustls" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "rustversion" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "same-file" @@ -1951,14 +2057,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" @@ -1968,9 +2074,19 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" + +[[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" @@ -1997,18 +2113,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.145" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", @@ -2017,9 +2133,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.86" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "itoa", "ryu", @@ -2038,6 +2154,34 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time 0.3.17", +] + +[[package]] +name = "serde_with_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa" +dependencies = [ + "darling 0.14.2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sha1" version = "0.10.5" @@ -2118,6 +2262,12 @@ dependencies = [ "winapi 0.3.9", ] +[[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.4" @@ -2156,9 +2306,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.102" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -2212,18 +2362,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -2241,9 +2391,9 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", @@ -2252,21 +2402,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ "itoa", - "libc", - "num_threads", + "serde", + "time-core", "time-macros", ] [[package]] -name = "time-macros" -version = "0.2.4" +name = "time-core" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] [[package]] name = "tinyvec" @@ -2285,28 +2444,28 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.2" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", "libc", "memchr", - "mio 0.8.4", + "mio 0.8.5", "num_cpus", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "winapi 0.3.9", + "windows-sys 0.42.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", @@ -2323,6 +2482,17 @@ dependencies = [ "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-stream" version = "0.1.11" @@ -2350,9 +2520,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" dependencies = [ "serde", ] @@ -2433,9 +2603,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ubyte" @@ -2520,9 +2690,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" @@ -2555,6 +2725,12 @@ dependencies = [ "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" @@ -2703,6 +2879,25 @@ dependencies = [ "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.2.8" @@ -2748,15 +2943,15 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.32.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec" +checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" dependencies = [ - "windows_aarch64_msvc 0.32.0", - "windows_i686_gnu 0.32.0", - "windows_i686_msvc 0.32.0", - "windows_x86_64_gnu 0.32.0", - "windows_x86_64_msvc 0.32.0", + "windows_aarch64_msvc 0.39.0", + "windows_i686_gnu 0.39.0", + "windows_i686_msvc 0.39.0", + "windows_x86_64_gnu 0.39.0", + "windows_x86_64_msvc 0.39.0", ] [[package]] @@ -2773,10 +2968,25 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_msvc" -version = "0.32.0" +name = "windows-sys" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" [[package]] name = "windows_aarch64_msvc" @@ -2785,10 +2995,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] -name = "windows_i686_gnu" -version = "0.32.0" +name = "windows_aarch64_msvc" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" @@ -2797,10 +3013,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] -name = "windows_i686_msvc" -version = "0.32.0" +name = "windows_i686_gnu" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" @@ -2809,10 +3031,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] -name = "windows_x86_64_gnu" -version = "0.32.0" +name = "windows_i686_msvc" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" @@ -2821,10 +3049,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] -name = "windows_x86_64_msvc" -version = "0.32.0" +name = "windows_x86_64_gnu" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" @@ -2832,6 +3072,18 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winreg" version = "0.10.1" @@ -2869,3 +3121,23 @@ dependencies = [ "tokio", "wait-timeout", ] + +[[package]] +name = "ytextract" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23e95563efc0a066ac0e6491ecd7012940ef495ce050c9f09de145a034ccabf" +dependencies = [ + "async-stream", + "base64 0.13.1", + "bytes", + "chrono", + "futures-core", + "log", + "reqwest", + "serde", + "serde_json", + "serde_with", + "thiserror", + "url", +] diff --git a/Cargo.toml b/Cargo.toml index 6c1ea10..9e784bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ async-trait = "0.1.57" cached = { version = "0.39.0", features = ["async"] } chrono = { version = "0.4.19", features = ["serde"] } enum_dispatch = "0.3.8" +mime-db = "1.6.0" reqwest = { version = "0.11.10", features = ["json"] } rocket = { version = "0.5.0-rc.2", features = ["json"] } rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] } @@ -19,6 +20,7 @@ rss = "2.0.1" thiserror = "1.0.31" url = { version = "2.2.2", features = ["serde"] } youtube_dl = { version = "0.7.0", features = ["tokio"] } +ytextract = "0.11.1" [package.metadata.deb] maintainer = "Paul van Tilburg " @@ -29,7 +31,8 @@ Podbringer is a web service that provides podcasts for services that don't offer them (anymore). It provides a way to get the RSS feed for your podcast client and it facilites the downloads of the pods (enclosures). -It currently only supports [Mixcloud](https://mixcloud.com). +It currently only supports [Mixcloud](https://www.mixcloud.com) and +[YouTube](https://www.youtube.com). Other back-ends might be added in the future. """ section = "net" diff --git a/README.md b/README.md index 829e956..6e10fdf 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ Podbringer is a web service that provides podcasts for services that don't offer them (anymore). It provides a way to get the RSS feed for your podcast client and it facilites the downloads of the pods (enclosures). -It currently only supports [Mixcloud](https://mixcloud.com). +It currently only supports [Mixcloud](https://www.mixcloud.com) and +[YouTube](https://www.youtube.com). Other back-ends might be added in the future. ## Building & running @@ -25,8 +26,8 @@ builds when you don't add `--release`.) ### Configuration For now, you will need to provide Rocket with configuration to tell it at which -public URL Podbringer is hosted. This needs to be done even if you are not using a -reverse proxy, in which case you need to provide it with the proxied URL. You +public URL Podbringer is hosted. This needs to be done even if you are not using +a reverse proxy, in which case you need to provide it with the proxied URL. You can also use the configuration to configure a different address and/or port. Just create a `Rocket.toml` file that contains (or copy `Rocket.toml.example`): @@ -44,17 +45,17 @@ configuration, see: . Podbringer currently has no front-end or web interface yet that can help you use it. Until then, you just have to enter the right service-specific RSS feed -URL in your favorite podcast client to start using it. - -Given the Mixcloud URL , the URL you -need to use for Podbringer is comprised of the following parts: +URL in your favorite podcast client to start using it. For example: ```text https://my.domain.tld/podbringer/feed/mixcloud/myfavouriteband - |------------------------------| |-------||--------------| - The Podbringer public URL Service User @ service + |------------------------------| |------| |-------------| + The Podbringer public URL Service Service ID ``` +So, the URL consists of the location of Podbringer, the fact that you want the feed, +the name of the service and the ID that identifies something list on that service. + ### Feed item limit To prevent feeds with a very large number of items, any feed that is returned @@ -62,7 +63,43 @@ contains at most 50 items by default. If you want to have more (or less) items, provide the limit in the URL by setting the `limit` parameter. For example, to get up until 1000 items the URL becomes: -`https://my.domain.tld/podbringer/feed/mixcloud/myfavouriteband?limit=1000` + +```text + https://my.domain.tld/podbringer/feed/mixcloud/myfavouriteband?limit=1000` +``` + +### Service: Mixcloud + +For Mixcloud, a feed can be constructed of everything that a user posted. +Given the Mixcloud URL like , the +`myfavouriteband` part of the URL is the Mixcloud username and can be used as +the service ID. + +```text + https://my.domain.tld/podbringer/feed/mixcloud/myfavouriteband + |------------------------------| |------| |-------------| + The Podbringer public URL Service Username +``` + +### Service: YouTube + +For YouTube, a feed can either be constructed of a channel or a playlist. +Given the YouTube channel URL like , +the `favouritechannel` part of the URL is the YouTube channel ID. +Given the YouTube playlist URL +, the +`PLsomeplaylistidentifier` part of the URL is the YouTube playlist ID. +Either the channel or playlist ID can be used as the service ID. + +```text + https://my.domain.tld/podbringer/feed/youtube/favouritechannel + |------------------------------| |-----| |--------------| + The Podbringer public URL Service Channel ID + + https://my.domain.tld/podbringer/feed/youtube/PLsomeplaylistidentifier + |------------------------------| |-----| |----------------------| + The Podbringer public URL Service Playlist ID +``` ## License diff --git a/src/backends.rs b/src/backends.rs index e0a9746..8253d85 100644 --- a/src/backends.rs +++ b/src/backends.rs @@ -15,19 +15,25 @@ use reqwest::Url; use crate::{Error, Result}; pub(crate) mod mixcloud; +pub(crate) mod youtube; /// Retrieves the back-end for the provided ID (if supported). pub(crate) fn get(backend: &str) -> Result { match backend { "mixcloud" => Ok(Backends::Mixcloud(mixcloud::backend())), + "youtube" => Ok(Backends::YouTube(youtube::backend())), _ => Err(Error::UnsupportedBackend(backend.to_string())), } } -/// The support back-ends. +/// The supported back-ends. #[enum_dispatch(Backend)] pub(crate) enum Backends { + /// Mixcloud () Mixcloud(mixcloud::Backend), + + /// YouTube () + YouTube(youtube::Backend), } /// Functionality of a content back-end. diff --git a/src/backends/mixcloud.rs b/src/backends/mixcloud.rs index 56d32c1..9329144 100644 --- a/src/backends/mixcloud.rs +++ b/src/backends/mixcloud.rs @@ -199,7 +199,8 @@ impl From for Channel { impl From for Item { fn from(cloudcast: Cloudcast) -> Self { let mut file = PathBuf::from(cloudcast.key.trim_end_matches('/')); - file.set_extension("m4a"); // FIXME: Don't hardcoded the extension! + let extension = mime_db::extension(DEFAULT_FILE_TYPE).expect("MIME type has extension"); + file.set_extension(extension); // FIXME: Don't hardcode the description! let description = Some(format!("Taken from Mixcloud: {0}", cloudcast.url)); diff --git a/src/backends/youtube.rs b/src/backends/youtube.rs new file mode 100644 index 0000000..35cc8fc --- /dev/null +++ b/src/backends/youtube.rs @@ -0,0 +1,342 @@ +//! The YouTube back-end. +//! +//! It uses the `ytextract` crate to retrieve the feed (channel or playlist) and items (videos). + +use std::path::{Path, PathBuf}; + +use async_trait::async_trait; +use cached::proc_macro::cached; +use chrono::{DateTime, Utc}; +use reqwest::Url; +use rocket::futures::StreamExt; +use ytextract::playlist::video::{Error as YouTubeVideoError, Video as YouTubePlaylistVideo}; +use ytextract::{ + Channel as YouTubeChannel, Client, Playlist as YouTubePlaylist, Stream as YouTubeStream, + Video as YouTubeVideo, +}; + +use super::{Channel, Enclosure, Item}; +use crate::{Error, Result}; + +/// The base URL for YouTube channels. +const CHANNEL_BASE_URL: &str = "https://www.youtube.com/channel"; + +/// The default item limit. +const DEFAULT_ITEM_LIMIT: usize = 50; + +/// The base URL for YouTube playlists. +const PLAYLIST_BASE_URL: &str = "https://www.youtube.com/channel"; + +/// The base URL for YouTube videos. +const VIDEO_BASE_URL: &str = "https://www.youtube.com/watch"; + +/// Creates a YouTube back-end. +pub(crate) fn backend() -> Backend { + Backend::new() +} + +/// The YouTube back-end. +pub struct Backend { + /// The client capable of interacting with YouTube. + client: Client, +} + +impl Backend { + /// Creates a new YouTube back-end. + fn new() -> Self { + let client = Client::new(); + + Self { client } + } +} + +#[async_trait] +impl super::Backend for Backend { + fn name(&self) -> &'static str { + "YouTube" + } + + async fn channel(&self, channel_id: &str, item_limit: Option) -> Result { + // We assume it is a YouTube playlist ID if the channel ID starts with + // "PL"/"OLAK"/"RDCLAK"; it is considered to be a YouTube channel ID otherwise. + if channel_id.starts_with("PL") + || channel_id.starts_with("OLAK") + || channel_id.starts_with("RDCLAK") + { + let (yt_playlist, yt_videos_w_streams) = + fetch_playlist_videos(&self.client, channel_id, item_limit).await?; + + Ok(Channel::from(YouTubePlaylistWithVideos( + yt_playlist, + yt_videos_w_streams, + ))) + } else { + let (yt_channel, yt_videos_w_streams) = + fetch_channel_videos(&self.client, channel_id, item_limit).await?; + + Ok(Channel::from(YouTubeChannelWithVideos( + yt_channel, + yt_videos_w_streams, + ))) + } + } + + async fn redirect_url(&self, file: &Path) -> Result { + let id_part = file.with_extension(""); + let video_id = id_part.to_string_lossy(); + + retrieve_redirect_url(&self.client, &video_id).await + } +} + +/// A YouTube playlist with its videos. +#[derive(Clone, Debug)] +pub(crate) struct YouTubePlaylistWithVideos(YouTubePlaylist, Vec); + +/// A YouTube channel with its videos. +#[derive(Clone, Debug)] +pub(crate) struct YouTubeChannelWithVideos(YouTubeChannel, Vec); + +/// A YouTube video with its stream. +#[derive(Clone, Debug)] +struct YouTubeVideoWithStream { + /// The information of the YouTube video. + video: YouTubeVideo, + + /// The metadata of the selected YouTube stream. + stream: YouTubeStream, + + /// The content of the selected YouTube stream. + content_length: u64, +} + +impl From for Channel { + fn from( + YouTubeChannelWithVideos(yt_channel, yt_videos_w_streams): YouTubeChannelWithVideos, + ) -> Self { + let mut link = Url::parse(CHANNEL_BASE_URL).expect("valid URL"); + let title = format!("{0} (via YouTube)", yt_channel.name()); + let description = yt_channel.description().to_string(); + link.path_segments_mut() + .expect("valid URL") + .push(&yt_channel.id()); + let author = Some(yt_channel.name().to_string()); + // FIXME: Don't hardcode the category! + let categories = Vec::from([String::from("Channel")]); + let image = yt_channel + .avatar() + .max_by_key(|av| av.width * av.height) + .map(|av| av.url.clone()); + let items = yt_videos_w_streams.into_iter().map(Item::from).collect(); + + Channel { + title, + link, + description, + author, + categories, + image, + items, + } + } +} + +impl From for Channel { + fn from( + YouTubePlaylistWithVideos(yt_playlist, yt_videos_w_streams): YouTubePlaylistWithVideos, + ) -> Self { + let title = format!("{0} (via YouTube)", yt_playlist.title()); + let mut link = Url::parse(PLAYLIST_BASE_URL).expect("valid URL"); + let description = yt_playlist.description().to_string(); + link.query_pairs_mut() + .append_pair("list", &yt_playlist.id().to_string()); + let author = yt_playlist.channel().map(|chan| chan.name().to_string()); + // FIXME: Don't hardcode the category! + let categories = Vec::from([String::from("Playlist")]); + let image = yt_playlist + .thumbnails() + .iter() + .max_by_key(|tn| tn.width * tn.height) + .map(|tn| tn.url.clone()); + let items = yt_videos_w_streams.into_iter().map(Item::from).collect(); + + Channel { + title, + link, + description, + author, + categories, + image, + items, + } + } +} + +impl From for Item { + fn from( + YouTubeVideoWithStream { + video, + stream, + content_length: length, + }: YouTubeVideoWithStream, + ) -> Self { + let id = video.id().to_string(); + + let mime_type = stream.mime_type().to_string(); + // Ignore everything from MIME type parameter seperator on for extension look-up. + let mime_sep = mime_type.find(';').unwrap_or(mime_type.len()); + let extension = mime_db::extension(&mime_type[..mime_sep]).unwrap_or_default(); + let file = PathBuf::from(&id).with_extension(extension); + let enclosure = Enclosure { + file, + mime_type, + length, + }; + + let mut link = Url::parse(VIDEO_BASE_URL).expect("valid URL"); + link.query_pairs_mut().append_pair("v", &id); + let video_description = video.description(); + let description = Some(format!("{video_description}\n\nTaken from YouTube: {link}")); + let categories = video + .hashtags() + .filter(|hashtag| !hashtag.trim().is_empty()) + .map(|hashtag| { + let url = Url::parse(&format!( + "https://www.youtube.com/hashtag/{}", + hashtag.trim_start_matches('#') + )) + .expect("valid URL"); + + (hashtag.to_string(), url) + }) + .collect(); + let duration = Some(video.duration().as_secs() as u32); + let keywords = video.keywords().clone(); + let image = video + .thumbnails() + .iter() + .max_by_key(|tn| tn.width * tn.height) + .map(|tn| tn.url.clone()); + let timestamp = video + .date() + .and_hms_opt(12, 0, 0) + .expect("Invalid hour, minute and/or second"); + let updated_at = DateTime::from_utc(timestamp, Utc); + + Item { + title: video.title().to_string(), + link, + description, + categories, + enclosure, + duration, + guid: id, + keywords, + image, + updated_at, + } + } +} + +/// Fetches the YouTube playlist videos for the given ID. +/// +/// If the result is [`Ok`], the playlist will be cached for 24 hours for the given playlist ID. +#[cached( + key = "(String, Option)", + convert = r#"{ (playlist_id.to_owned(), item_limit) }"#, + time = 86400, + result = true +)] +async fn fetch_playlist_videos( + client: &Client, + playlist_id: &str, + item_limit: Option, +) -> Result<(YouTubePlaylist, Vec)> { + let id = playlist_id.parse()?; + let limit = item_limit.unwrap_or(DEFAULT_ITEM_LIMIT); + let yt_playlist = client.playlist(id).await?; + let yt_videos_w_streams = yt_playlist + .videos() + .filter_map(fetch_stream) + .take(limit) + .collect() + .await; + + Ok((yt_playlist, yt_videos_w_streams)) +} + +/// Fetches the YouTube channel videos for the given ID. +#[cached( + key = "(String, Option)", + convert = r#"{ (channel_id.to_owned(), item_limit) }"#, + time = 86400, + result = true +)] +async fn fetch_channel_videos( + client: &Client, + channel_id: &str, + item_limit: Option, +) -> Result<(YouTubeChannel, Vec)> { + let id = channel_id.parse()?; + let limit = item_limit.unwrap_or(DEFAULT_ITEM_LIMIT); + let yt_channel = client.channel(id).await?; + let yt_videos_w_streams = yt_channel + .uploads() + .await? + .filter_map(fetch_stream) + .take(limit) + .collect() + .await; + + Ok((yt_channel, yt_videos_w_streams)) +} + +/// Fetches the stream and relevant metadata for a YouTube video result. +/// +/// If there is a error retrieving the metadata, the video is discarded/ignored. +/// If there are problems retrieving the streams or metadata, the video is also discarded. +async fn fetch_stream( + yt_video: Result, +) -> Option { + match yt_video { + Ok(video) => { + let video = video.upgrade().await.ok()?; + let stream = video + .streams() + .await + .ok()? + .filter(|v| v.is_audio()) + .max_by_key(|v| v.bitrate())?; + let content_length = stream.content_length().await.ok()?; + + Some(YouTubeVideoWithStream { + video, + stream, + content_length, + }) + } + Err(_) => None, + } +} + +/// Retrieves the redirect URL for the provided YouTube video ID. +/// +/// If the result is [`Ok`], the redirect URL will be cached for 24 hours for the given video ID. +#[cached( + key = "String", + convert = r#"{ video_id.to_owned() }"#, + time = 86400, + result = true +)] +async fn retrieve_redirect_url(client: &Client, video_id: &str) -> Result { + let video_id = video_id.parse()?; + let video = client.video(video_id).await?; + let stream = video + .streams() + .await? + .filter(|v| v.is_audio()) + .max_by_key(|v| v.bitrate()) + .ok_or(Error::NoRedirectUrlFound)?; + + Ok(stream.url().to_string()) +} diff --git a/src/feed.rs b/src/feed.rs index 20d46fc..a932c04 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -28,7 +28,9 @@ pub(crate) fn construct(backend_id: &str, config: &Config, channel: Channel) -> .unwrap_or_default(), ) .build(); - let mut last_build = DateTime::::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc); + let unix_timestamp = NaiveDateTime::from_timestamp_opt(0, 0) + .expect("Out-of-range seconds or invalid nanoseconds"); + let mut last_build = DateTime::from_utc(unix_timestamp, Utc); let generator = String::from(concat!( env!("CARGO_PKG_NAME"), " ", diff --git a/src/lib.rs b/src/lib.rs index 6869f6c..7cef003 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,6 +54,26 @@ pub(crate) enum Error { /// An error occurred in youtube-dl. #[error("Youtube-dl failed: {0}")] YoutubeDl(#[from] youtube_dl::Error), + + /// An YouTube extract error occured. + #[error("YouTube extract error: {0}")] + YtExtract(#[from] ytextract::Error), + + /// An YouTube extract ID parsing error occured. + #[error("YouTube extract ID parsing error: {0}")] + YtExtractId0(#[from] ytextract::error::Id<0>), + + /// An YouTube extract ID parsing error occured. + #[error("YouTube extract ID parsing error: {0}")] + YtExtractId11(#[from] ytextract::error::Id<11>), + + /// An YouTube extract ID parsing error occured. + #[error("YouTube extract ID parsing error: {0}")] + YtExtractId24(#[from] ytextract::error::Id<24>), + + /// An YouTube extract playlist video error occured. + #[error("YouTube extract playlist video error: {0}")] + YtExtractPlaylistVideo(#[from] ytextract::playlist::video::Error), } impl<'r, 'o: 'r> rocket::response::Responder<'r, 'o> for Error { diff --git a/templates/index.html.tera b/templates/index.html.tera index c9a3af7..be7d078 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -5,15 +5,21 @@ URL in your favorite podcast client to start using it.

- Given the Mixcloud URL , the URL you - need to use for Podbringer is comprised of the following parts: + The URL you need to use for Podbringer is comprised of the following parts:

     https://my.domain.tld/podbringer/feed/mixcloud/myfavouriteband
-    |------------------------------|     |-------||--------------|
-     The Podbringer public URL            Service  User @ service
+    |------------------------------|      |------| |-------------|
+     The Podbringer public URL            Service   Service ID
   

- The Podbringer location URL of this instance is: {{ url }} + Supported services are: +

    +
  • Mixcloud (service ID is Mixcloud username)
  • +
  • YouTube (service ID is YouTube channel or playlist ID)
  • +
+

+

+ The Podbringer location URL of this instance is: {{ url }}.