From 287a61ae3fb1dcff052756cd37699554de71925f Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 23 Nov 2024 12:14:12 -0500 Subject: [PATCH 01/21] Update dependencies, improve startup logging --- Cargo.lock | 1287 ++++++++++++++++++++++++++++++++------------------ Cargo.toml | 18 +- src/files.rs | 2 +- src/main.rs | 34 +- 4 files changed, 856 insertions(+), 485 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb45b19..54d6f26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,14 +4,14 @@ version = 3 [[package]] name = "actix" -version = "0.13.1" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba56612922b907719d4a01cf11c8d5b458e7d3dba946d0435f20f58d6795ed2" +checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b" dependencies = [ "actix-macros", "actix-rt", "actix_derive", - "bitflags 2.4.2", + "bitflags 2.6.0", "bytes", "crossbeam-channel", "futures-core", @@ -29,11 +29,11 @@ dependencies = [ [[package]] name = "actix-codec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "bytes", "futures-core", "futures-sink", @@ -46,15 +46,15 @@ dependencies = [ [[package]] name = "actix-files" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0bdd6ff79de7c9a021f5d9ea79ce23e108d8bfc9b49b5b4a2cf6fad5a35212" +checksum = "0773d59061dedb49a8aed04c67291b9d8cf2fe0b60130a381aab53c6dd86e9be" dependencies = [ "actix-http", "actix-service", "actix-utils", "actix-web", - "bitflags 2.4.2", + "bitflags 2.6.0", "bytes", "derive_more", "futures-core", @@ -69,17 +69,17 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.5.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129d4c88e98860e1758c5de288d1632b07970a16d59bdf7b8d66053d582bb71f" +checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", "ahash", - "base64", - "bitflags 2.4.2", + "base64 0.22.1", + "bitflags 2.6.0", "brotli", "bytes", "bytestring", @@ -113,19 +113,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "actix-multipart" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b960e2aea75f49c8f069108063d12a48d329fc8b60b786dfc7552a9d5918d2d" +checksum = "d5118a26dee7e34e894f7e85aa0ee5080ae4c18bf03c0e30d49a80e418f00a53" dependencies = [ "actix-multipart-derive", "actix-utils", "actix-web", - "bytes", "derive_more", "futures-core", "futures-util", @@ -134,6 +133,7 @@ dependencies = [ "log", "memchr", "mime", + "rand", "serde", "serde_json", "serde_plain", @@ -143,35 +143,37 @@ dependencies = [ [[package]] name = "actix-multipart-derive" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a0a77f836d869f700e5b47ac7c3c8b9c8bc82e4aec861954c6198abee3ebd4d" +checksum = "e11eb847f49a700678ea2fa73daeb3208061afa2b9d1a8527c03390f4c4a1c6b" dependencies = [ "darling", "parse-size", "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "actix-router" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", + "cfg-if", "http", "regex", + "regex-lite", "serde", "tracing", ] [[package]] name = "actix-rt" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" dependencies = [ "actix-macros", "futures-core", @@ -180,16 +182,16 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" dependencies = [ "actix-rt", "actix-service", "actix-utils", "futures-core", "futures-util", - "mio", + "mio 1.0.2", "socket2", "tokio", "tracing", @@ -218,9 +220,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.4.1" +version = "4.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43428f3bf11dee6d166b00ec2df4e3aa8cc1606aaa0b7433c146852e2f4e03b" +checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" dependencies = [ "actix-codec", "actix-http", @@ -240,6 +242,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", + "impl-more", "itoa", "language-tags", "log", @@ -247,6 +250,7 @@ dependencies = [ "once_cell", "pin-project-lite", "regex", + "regex-lite", "serde", "serde_json", "serde_urlencoded", @@ -258,60 +262,62 @@ dependencies = [ [[package]] name = "actix-web-codegen" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "actix-web-prom" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23f332a652836b8f3a6876103c70c9ed436d0e69fa779ab5d7f57b1d5c8d488" +checksum = "56a34f1825c3ae06567a9d632466809bbf34963c86002e8921b64f32d48d289d" dependencies = [ "actix-web", "futures-core", + "log", "pin-project-lite", "prometheus", "regex", + "strfmt", ] [[package]] name = "actix_derive" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3" +checksum = "b6ac1e58cded18cb28ddc17143c4dea5345b3ad575e14f32f66e4054a56eb271" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -322,9 +328,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -360,30 +366,79 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.79" +name = "anstream" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -393,12 +448,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "bcrypt" -version = "0.15.0" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d1c9c15093eb224f0baa400f38fcd713fc1391a6f1c389d886beef146d60a3" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bcrypt" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b1866ecef4f2d06a0bb77880015fdf2b89e25a1c2e5addacb87e459c86dc67e" dependencies = [ - "base64", + "base64 0.22.1", "blowfish", "getrandom", "subtle", @@ -413,9 +474,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -438,9 +499,9 @@ dependencies = [ [[package]] name = "brotli" -version = "3.4.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -449,9 +510,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -459,15 +520,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -477,9 +538,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "bytestring" @@ -492,12 +553,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -508,16 +570,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -536,6 +598,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "convert_case" version = "0.4.0" @@ -555,33 +623,33 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -607,9 +675,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -623,9 +691,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -633,27 +701,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.48", + "syn", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.48", + "syn", ] [[package]] @@ -667,22 +735,22 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn", ] [[package]] name = "diesel" -version = "2.1.4" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" +checksum = "cbf9649c05e0a9dbd6d0b0b8301db5182b972d0fd02f0a7c6736cf632d7c0fd5" dependencies = [ "diesel_derives", "libsqlite3-sys", @@ -691,21 +759,22 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.1.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" +checksum = "e7f2c3de51e2ba6bf2a648285696137aaf0f5f487bcbea93972fe8a364e131a4" dependencies = [ "diesel_table_macro_syntax", + "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "diesel_migrations" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac" +checksum = "8a73ce704bad4231f001bff3314d91dce4aba0770cee8b233991859abc15c1f6" dependencies = [ "diesel", "migrations_internals", @@ -714,11 +783,11 @@ dependencies = [ [[package]] name = "diesel_table_macro_syntax" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn 2.0.48", + "syn", ] [[package]] @@ -732,6 +801,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dotenv" version = "0.15.0" @@ -739,31 +819,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] -name = "either" -version = "1.9.0" +name = "dsl_auto_type" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607" +dependencies = [ + "darling", + "either", + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] -name = "env_logger" -version = "0.10.2" +name = "env_filter" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ - "humantime", - "is-terminal", "log", "regex", - "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", ] [[package]] @@ -774,9 +878,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -784,36 +888,36 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fdeflate" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", - "redox_syscall", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -845,9 +949,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -860,9 +964,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -870,15 +974,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -887,38 +991,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -944,9 +1048,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -957,15 +1061,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -982,15 +1086,21 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hmac" @@ -1003,9 +1113,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1020,9 +1130,9 @@ checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1038,9 +1148,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1059,6 +1169,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1067,19 +1295,30 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "image" -version = "0.24.8" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", @@ -1123,10 +1362,16 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "2.1.0" +name = "impl-more" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "aae21c3177a27788957044151cc2800043d127acaa460a47ebb9b84dfa2c6aa0" + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", @@ -1162,27 +1407,22 @@ dependencies = [ ] [[package]] -name = "is-terminal" -version = "0.4.10" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.52.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -1198,20 +1438,20 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] [[package]] name = "jsonwebtoken" -version = "9.2.0" +version = "9.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" dependencies = [ - "base64", + "base64 0.21.7", "js-sys", "pem", "ring", @@ -1248,21 +1488,32 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall", +] [[package]] name = "libsqlite3-sys" -version = "0.27.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "pkg-config", "vcpkg", @@ -1270,9 +1521,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "local-channel" @@ -1293,9 +1550,9 @@ checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1303,21 +1560,21 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "migrations_internals" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada" +checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" dependencies = [ "serde", "toml", @@ -1325,9 +1582,9 @@ dependencies = [ [[package]] name = "migrations_macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08" +checksum = "ffb161cc72176cb37aa47f1fc520d3ef02263d67d661f44f05d05a079e1237fd" dependencies = [ "migrations_internals", "proc-macro2", @@ -1342,9 +1599,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -1352,19 +1609,19 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", "simd-adler32", ] [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", @@ -1372,13 +1629,26 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "log", + "wasi", + "windows-sys 0.52.0", +] + [[package]] name = "notify" version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "crossbeam-channel", "filetime", "fsevent-sys", @@ -1386,61 +1656,65 @@ dependencies = [ "kqueue", "libc", "log", - "mio", + "mio 0.8.11", "walkdir", "windows-sys 0.48.0", ] [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] -name = "num-integer" -version = "0.1.45" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "object" -version = "0.32.2" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1448,28 +1722,28 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "parse-size" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "944553dd59c802559559161f9816429058b869003836120e262e8caec061b7ae" +checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b" [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-absolutize" @@ -1491,11 +1765,11 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64", + "base64 0.22.1", "serde", ] @@ -1507,9 +1781,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -1519,15 +1793,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.11" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -1544,24 +1818,27 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", @@ -1580,9 +1857,9 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1619,9 +1896,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1639,18 +1916,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1660,9 +1937,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1670,47 +1947,54 @@ dependencies = [ ] [[package]] -name = "regex-syntax" -version = "0.8.2" +name = "regex-lite" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1719,9 +2003,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1740,37 +2024,38 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1786,9 +2071,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -1828,10 +2113,16 @@ dependencies = [ ] [[package]] -name = "signal-hook-registry" -version = "1.4.1" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -1865,18 +2156,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1886,22 +2177,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] -name = "strsim" -version = "0.10.0" +name = "stable_deref_trait" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strfmt" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -1909,66 +2212,58 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.48" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] name = "tempfile" -version = "3.9.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", + "windows-sys 0.59.0", ] [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", ] [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -1983,64 +2278,59 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[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.35.1" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", "libc", - "mio", + "mio 1.0.2", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.7.8" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -2050,18 +2340,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -2098,33 +2388,15 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "untrusted" @@ -2134,15 +2406,33 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "v_htmlescape" version = "0.15.8" @@ -2157,15 +2447,15 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -2179,34 +2469,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2214,61 +2505,39 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" - -[[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" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] -[[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-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -2286,7 +2555,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -2306,17 +2584,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2327,9 +2606,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2339,9 +2618,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2351,9 +2630,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2363,9 +2648,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2375,9 +2660,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2387,9 +2672,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2399,68 +2684,148 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.34" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] [[package]] -name = "zerocopy" -version = "0.7.32" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zstd" -version = "0.13.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.0.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 4b7d638..70aa5dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,26 +14,26 @@ actix = "0.13.1" actix-web = "4" actix-rt = "2.6" actix-files = "0.6" -actix-multipart = "0.6.1" +actix-multipart = "0.7.2" futures = "0.3.5" -jsonwebtoken = "9.2.0" +jsonwebtoken = "9.3.0" serde = "1" serde_json = "1" -diesel = { version = "2.0.2", features = ["sqlite"] } +diesel = { version = "2.2.5", features = ["sqlite"] } diesel_migrations = "2.0.0" hmac = "0.12.1" sha2 = "0.10.8" chrono = "0.4" dotenv = "0.15" -bcrypt = "0.15.0" -image = { version = "0.24.7", default-features = false, features = ["jpeg", "png", "jpeg_rayon"] } +bcrypt = "0.16.0" +image = { version = "0.24.9", default-features = false, features = ["jpeg", "png", "jpeg_rayon"] } walkdir = "2.4.0" rayon = "1.5" notify = "6.1.1" -path-absolutize = "3.0" +path-absolutize = "3.1" log="0.4" -env_logger= "0.10.1" -actix-web-prom = "0.7.0" +env_logger= "0.11.5" +actix-web-prom = "0.9.0" prometheus = "0.13" -lazy_static = "1.1" +lazy_static = "1.5" anyhow = "1.0" diff --git a/src/files.rs b/src/files.rs index 93ceb6c..1e97aa8 100644 --- a/src/files.rs +++ b/src/files.rs @@ -314,7 +314,7 @@ impl Handler for StreamActor { type Result = (); fn handle(&mut self, _msg: RefreshThumbnailsMessage, _ctx: &mut Self::Context) -> Self::Result { - debug!("Refreshing thumbnails after upload"); + info!("Refreshing thumbnails after upload"); create_thumbnails() } } diff --git a/src/main.rs b/src/main.rs index 83106c3..9f9c9a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,6 +26,7 @@ use actix_web::{ web::{self, BufMut, BytesMut}, App, HttpRequest, HttpResponse, HttpServer, Responder, }; +use anyhow::Context; use chrono::Utc; use diesel::sqlite::Sqlite; use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; @@ -139,19 +140,20 @@ async fn upload_image( let mut file_path: Option = None; while let Some(Ok(mut part)) = payload.next().await { - let content_type = part.content_disposition(); - debug!("{:?}", content_type); - if let Some(filename) = content_type.get_filename() { - debug!("Name: {:?}", filename); - file_name = Some(filename.to_string()); + if let Some(content_type) = part.content_disposition() { + debug!("{:?}", content_type); + if let Some(filename) = content_type.get_filename() { + debug!("Name: {:?}", filename); + file_name = Some(filename.to_string()); - while let Some(Ok(data)) = part.next().await { - file_content.put(data); - } - } else if content_type.get_name().map_or(false, |name| name == "path") { - while let Some(Ok(data)) = part.next().await { - if let Ok(path) = std::str::from_utf8(&data) { - file_path = Some(path.to_string()) + while let Some(Ok(data)) = part.next().await { + file_content.put(data); + } + } else if content_type.get_name().map_or(false, |name| name == "path") { + while let Some(Ok(data)) = part.next().await { + if let Ok(path) = std::str::from_utf8(&data) { + file_path = Some(path.to_string()) + } } } } @@ -462,7 +464,9 @@ fn is_video(entry: &DirEntry) -> bool { } fn main() -> std::io::Result<()> { - dotenv::dotenv().ok(); + if let Err(err) = dotenv::dotenv() { + println!("Error parsing .env {:?}", err); + } env_logger::init(); run_migrations(&mut connect()).expect("Failed to run migrations"); @@ -544,7 +548,9 @@ fn watch_files() { let base_str = dotenv::var("BASE_PATH").unwrap(); let base_path = Path::new(&base_str); - watcher.watch(base_path, RecursiveMode::Recursive).unwrap(); + watcher.watch(base_path, RecursiveMode::Recursive) + .context(format!("Unable to watch BASE_PATH: '{}'", base_str)) + .unwrap(); loop { let ev = wrx.recv(); -- 2.49.1 From 698654029538cb4cb9c26b4689e2869feb253c88 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 23 Nov 2024 19:13:25 -0500 Subject: [PATCH 02/21] Add sorting shuffle, and name asc/desc --- Cargo.lock | 1 + Cargo.toml | 1 + src/data/mod.rs | 9 +++++++++ src/files.rs | 35 ++++++++++++++++++++++++++++++++--- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54d6f26..4f587ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1354,6 +1354,7 @@ dependencies = [ "notify", "path-absolutize", "prometheus", + "rand", "rayon", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 70aa5dc..39e32af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,3 +37,4 @@ actix-web-prom = "0.9.0" prometheus = "0.13" lazy_static = "1.5" anyhow = "1.0" +rand = "0.8.5" diff --git a/src/data/mod.rs b/src/data/mod.rs index 55e053a..7ac194a 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -100,6 +100,14 @@ pub struct PhotosResponse { pub dirs: Vec, } +#[derive(Copy, Clone, Deserialize, PartialEq, Debug)] +#[serde(rename_all = "lowercase")] +pub enum SortType { + Shuffle, + NameAsc, + NameDesc, +} + #[derive(Deserialize)] pub struct FilesRequest { pub path: String, @@ -107,6 +115,7 @@ pub struct FilesRequest { pub tag_ids: Option, pub tag_filter_mode: Option, pub recursive: Option, + pub sort: Option, } #[derive(Copy, Clone, Deserialize, PartialEq, Debug)] diff --git a/src/files.rs b/src/files.rs index 1e97aa8..40ba3c3 100644 --- a/src/files.rs +++ b/src/files.rs @@ -16,13 +16,15 @@ use actix_web::{ }; use log::{debug, error, info, trace}; -use crate::data::{Claims, FilesRequest, FilterMode, PhotosResponse}; +use crate::data::{Claims, FilesRequest, FilterMode, PhotosResponse, SortType}; use crate::{create_thumbnails, AppState}; use crate::error::IntoHttpError; use crate::tags::TagDao; use crate::video::StreamActor; use path_absolutize::*; +use rand::prelude::SliceRandom; +use rand::{random, thread_rng}; use serde::Deserialize; pub async fn list_photos( @@ -52,6 +54,14 @@ pub async fn list_photos( return dao .get_files_with_any_tag_ids(tag_ids.clone()) .context(format!("Failed to get files with tag_ids: {:?}", tag_ids)) + .map(|mut tagged_files| { + return if let Some(sort_type) = req.sort { + debug!("Sorting files: {:?}", sort_type); + sort(tagged_files, sort_type) + } else { + tagged_files + }; + }) .map(|tagged_files| match filter_mode { FilterMode::Any => tagged_files .iter() @@ -89,7 +99,7 @@ pub async fn list_photos( if let Ok(files) = file_system.get_files_for_path(search_path) { debug!("Valid search path: {:?}", search_path); - let photos = files + let mut photos = files .iter() .filter(|&f| { f.metadata().map_or_else( @@ -127,6 +137,11 @@ pub async fn list_photos( }) .collect::>(); + if let Some(sort_type) = req.sort { + debug!("Sorting files: {:?}", sort_type); + photos = sort(photos, sort_type) + } + let dirs = files .iter() .filter(|&f| f.metadata().map_or(false, |md| md.is_dir())) @@ -144,6 +159,20 @@ pub async fn list_photos( } } +fn sort(mut files: Vec, sort_type: SortType) -> Vec { + match sort_type { + SortType::Shuffle => files.shuffle(&mut thread_rng()), + SortType::NameAsc => { + files.sort_by(|l, r| l.cmp(&r)); + } + SortType::NameDesc => { + files.sort_by(|l, r| r.cmp(&l)); + } + } + + files +} + pub fn list_files(dir: &Path) -> io::Result> { let files = read_dir(dir)? .filter_map(|res| res.ok()) @@ -425,7 +454,7 @@ mod tests { let body: PhotosResponse = serde_json::from_str(&response.read_to_str()).unwrap(); debug!("{:?}", body); - + assert!(body.photos.contains(&String::from("photo.jpg"))); assert!(body.dirs.contains(&String::from("test-dir"))); assert!(body -- 2.49.1 From 9a32a1cfe728f865dd7e6ba2c334f55dcb88d4cb Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 23 Nov 2024 20:21:19 -0500 Subject: [PATCH 03/21] Allow for excluding certain tags from a file search --- src/data/mod.rs | 1 + src/files.rs | 14 ++++++++++---- src/tags.rs | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/data/mod.rs b/src/data/mod.rs index 7ac194a..acb322e 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -113,6 +113,7 @@ pub struct FilesRequest { pub path: String, // comma separated numbers pub tag_ids: Option, + pub exclude_tag_ids: Option, pub tag_filter_mode: Option, pub recursive: Option, pub sort: Option, diff --git a/src/files.rs b/src/files.rs index 40ba3c3..7416bc9 100644 --- a/src/files.rs +++ b/src/files.rs @@ -24,7 +24,7 @@ use crate::tags::TagDao; use crate::video::StreamActor; use path_absolutize::*; use rand::prelude::SliceRandom; -use rand::{random, thread_rng}; +use rand::{thread_rng}; use serde::Deserialize; pub async fn list_photos( @@ -39,7 +39,7 @@ pub async fn list_photos( let search_recursively = req.recursive.unwrap_or(false); if let Some(tag_ids) = &req.tag_ids { if search_recursively { - let filter_mode = req.tag_filter_mode.unwrap_or(FilterMode::Any); + let filter_mode = &req.tag_filter_mode.unwrap_or(FilterMode::Any); debug!( "Searching for tags: {}. With path: '{}' and filter mode: {:?}", tag_ids, search_path, filter_mode @@ -51,10 +51,16 @@ pub async fn list_photos( .filter_map(|t| t.parse().ok()) .collect::>(); + let exclude_tag_ids = req.exclude_tag_ids.clone() + .unwrap_or(String::new()) + .split(',') + .filter_map(|t| t.parse().ok()) + .collect::>(); + return dao - .get_files_with_any_tag_ids(tag_ids.clone()) + .get_files_with_any_tag_ids(tag_ids.clone(), exclude_tag_ids.clone()) .context(format!("Failed to get files with tag_ids: {:?}", tag_ids)) - .map(|mut tagged_files| { + .map(|tagged_files| { return if let Some(sort_type) = req.sort { debug!("Sorting files: {:?}", sort_type); sort(tagged_files, sort_type) diff --git a/src/tags.rs b/src/tags.rs index 741834d..a1a22ee 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -199,7 +199,11 @@ pub trait TagDao { fn remove_tag(&mut self, tag_name: &str, path: &str) -> anyhow::Result>; fn tag_file(&mut self, path: &str, tag_id: i32) -> anyhow::Result; fn get_files_with_all_tag_ids(&mut self, tag_ids: Vec) -> anyhow::Result>; - fn get_files_with_any_tag_ids(&mut self, tag_ids: Vec) -> anyhow::Result>; + fn get_files_with_any_tag_ids( + &mut self, + tag_ids: Vec, + exclude_tag_ids: Vec, + ) -> anyhow::Result>; } pub struct SqliteTagDao { @@ -348,17 +352,22 @@ impl TagDao for SqliteTagDao { .filter(tagged_photo::tag_id.eq_any(tag_ids.clone())) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) - .having(count(tagged_photo::tag_id).eq(tag_ids.len() as i64)) + .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) .select(tagged_photo::photo_name) .get_results::(&mut self.connection) .with_context(|| format!("Unable to get Tagged photos with ids: {:?}", tag_ids)) } - fn get_files_with_any_tag_ids(&mut self, tag_ids: Vec) -> anyhow::Result> { + fn get_files_with_any_tag_ids( + &mut self, + tag_ids: Vec, + exclude_tag_ids: Vec, + ) -> anyhow::Result> { use diesel::dsl::*; tagged_photo::table .filter(tagged_photo::tag_id.eq_any(tag_ids.clone())) + .filter(tagged_photo::tag_id.ne_all(exclude_tag_ids)) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) .select(tagged_photo::photo_name) -- 2.49.1 From 860e7a97fb5f2c61e4e2c33edd44cf4a2792e28b Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 24 Nov 2024 09:49:03 -0500 Subject: [PATCH 04/21] Use TagDao for improved filtering --- src/files.rs | 68 ++++++++++++++++++++-------------------------------- src/main.rs | 21 ++++++++-------- src/tags.rs | 16 ++++++++++--- 3 files changed, 50 insertions(+), 55 deletions(-) diff --git a/src/files.rs b/src/files.rs index 7416bc9..9b8f7a8 100644 --- a/src/files.rs +++ b/src/files.rs @@ -24,7 +24,7 @@ use crate::tags::TagDao; use crate::video::StreamActor; use path_absolutize::*; use rand::prelude::SliceRandom; -use rand::{thread_rng}; +use rand::thread_rng; use serde::Deserialize; pub async fn list_photos( @@ -51,54 +51,38 @@ pub async fn list_photos( .filter_map(|t| t.parse().ok()) .collect::>(); - let exclude_tag_ids = req.exclude_tag_ids.clone() + let exclude_tag_ids = req + .exclude_tag_ids + .clone() .unwrap_or(String::new()) .split(',') .filter_map(|t| t.parse().ok()) .collect::>(); - return dao - .get_files_with_any_tag_ids(tag_ids.clone(), exclude_tag_ids.clone()) - .context(format!("Failed to get files with tag_ids: {:?}", tag_ids)) - .map(|tagged_files| { - return if let Some(sort_type) = req.sort { - debug!("Sorting files: {:?}", sort_type); - sort(tagged_files, sort_type) - } else { - tagged_files - }; - }) - .map(|tagged_files| match filter_mode { - FilterMode::Any => tagged_files - .iter() - .filter(|file| file.starts_with(search_path)) - .cloned() - .collect(), - FilterMode::All => tagged_files - .iter() - .filter(|&file_path| { - if !file_path.starts_with(search_path) { - return false; - } + match filter_mode { + FilterMode::Any => dao.get_files_with_any_tag_ids(tag_ids.clone(), exclude_tag_ids), + FilterMode::All => dao.get_files_with_all_tag_ids(tag_ids.clone(), exclude_tag_ids), + } + .context(format!( + "Failed to get files with tag_ids: {:?} with filter_mode: {:?}", + tag_ids, filter_mode + )) + .map(|files| { + files + .into_iter() + .filter(|file_path| file_path.starts_with(search_path)) + .collect() + }) + .map(|tagged_files| { + trace!("Found tagged files: {:?}", tagged_files); - let file_tags = dao.get_tags_for_path(file_path).unwrap_or_default(); - tag_ids - .iter() - .all(|id| file_tags.iter().any(|tag| &tag.id == id)) - }) - .cloned() - .collect::>(), + HttpResponse::Ok().json(PhotosResponse { + photos: tagged_files, + dirs: vec![], }) - .map(|tagged_files| { - trace!("Found tagged files: {:?}", tagged_files); - - HttpResponse::Ok().json(PhotosResponse { - photos: tagged_files, - dirs: vec![], - }) - }) - .into_http_internal_err() - .unwrap_or_else(|e| e.error_response()); + }) + .into_http_internal_err() + .unwrap_or_else(|e| e.error_response()); } } diff --git a/src/main.rs b/src/main.rs index 9f9c9a3..6f8d7de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -282,7 +282,7 @@ async fn favorites( .expect("Unable to get FavoritesDao") .get_favorites(claims.sub.parse::().unwrap()) }) - .await + .await { Ok(Ok(favorites)) => { let favorites = favorites @@ -317,7 +317,7 @@ async fn put_add_favorite( .expect("Unable to get FavoritesDao") .add_favorite(user_id, &path) }) - .await + .await { Ok(Err(e)) if e.kind == DbErrorKind::AlreadyExists => { debug!("Favorite: {} exists for user: {}", &body.path, user_id); @@ -356,8 +356,8 @@ async fn delete_favorite( .expect("Unable to get favorites dao") .remove_favorite(user_id, path); }) - .await - .unwrap(); + .await + .unwrap(); info!( "Removing favorite \"{}\" for userid: {}", @@ -391,7 +391,7 @@ fn create_thumbnails() { .parent() .unwrap_or_else(|| panic!("Thumbnail {:?} has no parent?", thumb_path)), ) - .expect("Error creating directory"); + .expect("Error creating directory"); debug!("Generating video thumbnail: {:?}", thumb_path); generate_video_thumbnail(entry.path(), &thumb_path); @@ -526,10 +526,10 @@ fn main() -> std::io::Result<()> { .app_data::>>(Data::new(Mutex::new(tag_dao))) .wrap(prometheus.clone()) }) - .bind(dotenv::var("BIND_URL").unwrap())? - .bind("localhost:8088")? - .run() - .await + .bind(dotenv::var("BIND_URL").unwrap())? + .bind("localhost:8088")? + .run() + .await }) } @@ -548,7 +548,8 @@ fn watch_files() { let base_str = dotenv::var("BASE_PATH").unwrap(); let base_path = Path::new(&base_str); - watcher.watch(base_path, RecursiveMode::Recursive) + watcher + .watch(base_path, RecursiveMode::Recursive) .context(format!("Unable to watch BASE_PATH: '{}'", base_str)) .unwrap(); diff --git a/src/tags.rs b/src/tags.rs index a1a22ee..a8fd969 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -198,7 +198,11 @@ pub trait TagDao { fn create_tag(&mut self, name: &str) -> anyhow::Result; fn remove_tag(&mut self, tag_name: &str, path: &str) -> anyhow::Result>; fn tag_file(&mut self, path: &str, tag_id: i32) -> anyhow::Result; - fn get_files_with_all_tag_ids(&mut self, tag_ids: Vec) -> anyhow::Result>; + fn get_files_with_all_tag_ids( + &mut self, + tag_ids: Vec, + exclude_tag_ids: Vec, + ) -> anyhow::Result>; fn get_files_with_any_tag_ids( &mut self, tag_ids: Vec, @@ -345,11 +349,16 @@ impl TagDao for SqliteTagDao { }) } - fn get_files_with_all_tag_ids(&mut self, tag_ids: Vec) -> anyhow::Result> { + fn get_files_with_all_tag_ids( + &mut self, + tag_ids: Vec, + exclude_tag_ids: Vec, + ) -> anyhow::Result> { use diesel::dsl::*; tagged_photo::table .filter(tagged_photo::tag_id.eq_any(tag_ids.clone())) + .filter(tagged_photo::tag_id.ne_all(exclude_tag_ids)) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) @@ -496,7 +505,8 @@ mod tests { fn get_files_with_all_tag_ids( &mut self, - _tag_ids: Vec, + tag_ids: Vec, + exclude_tag_ids: Vec, ) -> anyhow::Result> { todo!() } -- 2.49.1 From a668b1411649239931ed27518787b12886006e29 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 24 Nov 2024 12:56:21 -0500 Subject: [PATCH 05/21] Update deprecated functions --- src/files.rs | 4 ++-- src/tags.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/files.rs b/src/files.rs index 9b8f7a8..cd6ed72 100644 --- a/src/files.rs +++ b/src/files.rs @@ -73,8 +73,8 @@ pub async fn list_photos( .filter(|file_path| file_path.starts_with(search_path)) .collect() }) - .map(|tagged_files| { - trace!("Found tagged files: {:?}", tagged_files); + .map(|tagged_files: Vec| { + trace!("Found {:?} tagged files: {:?}", tagged_files.len(), tagged_files); HttpResponse::Ok().json(PhotosResponse { photos: tagged_files, diff --git a/src/tags.rs b/src/tags.rs index a8fd969..2474670 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -276,7 +276,7 @@ impl TagDao for SqliteTagDao { .with_context(|| format!("Unable to insert tag {:?} in Sqlite", name)) .and_then(|_| { info!("Inserted tag: {:?}", name); - sql_function! { + define_sql_function! { fn last_insert_rowid() -> diesel::sql_types::Integer; } diesel::select(last_insert_rowid()) @@ -329,7 +329,7 @@ impl TagDao for SqliteTagDao { .with_context(|| format!("Unable to tag file {:?} in sqlite", path)) .and_then(|_| { info!("Inserted tagged photo: {:#} -> {:?}", tag_id, path); - sql_function! { + define_sql_function! { fn last_insert_rowid() -> diesel::sql_types::Integer; } diesel::select(last_insert_rowid()) -- 2.49.1 From 9327208deb56d002ad148235c5b3394b3a81765c Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 25 Nov 2024 21:40:25 -0500 Subject: [PATCH 06/21] Remove filtering when recursively searching with tags --- src/files.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/files.rs b/src/files.rs index cd6ed72..c830745 100644 --- a/src/files.rs +++ b/src/files.rs @@ -67,12 +67,6 @@ pub async fn list_photos( "Failed to get files with tag_ids: {:?} with filter_mode: {:?}", tag_ids, filter_mode )) - .map(|files| { - files - .into_iter() - .filter(|file_path| file_path.starts_with(search_path)) - .collect() - }) .map(|tagged_files: Vec| { trace!("Found {:?} tagged files: {:?}", tagged_files.len(), tagged_files); -- 2.49.1 From 0af7c8f98bd6d12e157404337ebfb149a63c53a4 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 27 Nov 2024 15:43:27 -0500 Subject: [PATCH 07/21] Fix missing return and update test signatures --- src/files.rs | 9 +++++++-- src/tags.rs | 8 ++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/files.rs b/src/files.rs index c830745..9704118 100644 --- a/src/files.rs +++ b/src/files.rs @@ -59,7 +59,7 @@ pub async fn list_photos( .filter_map(|t| t.parse().ok()) .collect::>(); - match filter_mode { + return match filter_mode { FilterMode::Any => dao.get_files_with_any_tag_ids(tag_ids.clone(), exclude_tag_ids), FilterMode::All => dao.get_files_with_all_tag_ids(tag_ids.clone(), exclude_tag_ids), } @@ -67,8 +67,13 @@ pub async fn list_photos( "Failed to get files with tag_ids: {:?} with filter_mode: {:?}", tag_ids, filter_mode )) + .inspect(|files| debug!("Found {:?} files", files.len())) .map(|tagged_files: Vec| { - trace!("Found {:?} tagged files: {:?}", tagged_files.len(), tagged_files); + trace!( + "Found {:?} tagged files: {:?}", + tagged_files.len(), + tagged_files + ); HttpResponse::Ok().json(PhotosResponse { photos: tagged_files, diff --git a/src/tags.rs b/src/tags.rs index 2474670..d7abaca 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -506,12 +506,16 @@ mod tests { fn get_files_with_all_tag_ids( &mut self, tag_ids: Vec, - exclude_tag_ids: Vec, + _exclude_tag_ids: Vec, ) -> anyhow::Result> { todo!() } - fn get_files_with_any_tag_ids(&mut self, tag_ids: Vec) -> anyhow::Result> { + fn get_files_with_any_tag_ids( + &mut self, + _tag_ids: Vec, + _exclude_tag_ids: Vec, + ) -> anyhow::Result> { todo!() } } -- 2.49.1 From d280db8482b4bfed792c62cea4a4f563ab48d830 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 27 Nov 2024 16:42:17 -0500 Subject: [PATCH 08/21] Fix exclude filtering --- src/files.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/files.rs b/src/files.rs index 9704118..121f8d9 100644 --- a/src/files.rs +++ b/src/files.rs @@ -111,10 +111,19 @@ pub async fn list_photos( .filter_map(|t| t.parse().ok()) .collect::>(); + let excluded_tag_ids = &req + .exclude_tag_ids + .clone() + .unwrap_or(String::new()) + .split(',') + .filter_map(|t| t.parse().ok()) + .collect::>(); + let filter_mode = &req.tag_filter_mode.unwrap_or(FilterMode::Any); let file_tags = tag_dao.get_tags_for_path(file_path).unwrap_or_default(); + let excluded = file_tags.iter().any(|t| excluded_tag_ids.contains(&t.id)); - return match filter_mode { + return !excluded && match filter_mode { FilterMode::Any => file_tags.iter().any(|t| tag_ids.contains(&t.id)), FilterMode::All => tag_ids .iter() -- 2.49.1 From b7f13d4cbfaee82cd68835e10c074ae0aa1d293e Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 4 Dec 2024 19:42:00 -0500 Subject: [PATCH 09/21] Fix exclude filtering for any tags --- src/tags.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tags.rs b/src/tags.rs index d7abaca..db28533 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -379,6 +379,7 @@ impl TagDao for SqliteTagDao { .filter(tagged_photo::tag_id.ne_all(exclude_tag_ids)) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) + .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) .select(tagged_photo::photo_name) .get_results::(&mut self.connection) .with_context(|| format!("Unable to get Tagged photos with ids: {:?}", tag_ids)) -- 2.49.1 From 2b2a811cae3b049786499602d0b3dd2413d818af Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 4 Dec 2024 19:50:04 -0500 Subject: [PATCH 10/21] Fix recursive filtering under base path --- src/files.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/files.rs b/src/files.rs index 121f8d9..63a9804 100644 --- a/src/files.rs +++ b/src/files.rs @@ -67,6 +67,12 @@ pub async fn list_photos( "Failed to get files with tag_ids: {:?} with filter_mode: {:?}", tag_ids, filter_mode )) + .map(|tagged_files| { + tagged_files + .into_iter() + .filter(|f| f.starts_with(search_path)) + .collect::>() + }) .inspect(|files| debug!("Found {:?} files", files.len())) .map(|tagged_files: Vec| { trace!( @@ -123,12 +129,13 @@ pub async fn list_photos( let file_tags = tag_dao.get_tags_for_path(file_path).unwrap_or_default(); let excluded = file_tags.iter().any(|t| excluded_tag_ids.contains(&t.id)); - return !excluded && match filter_mode { - FilterMode::Any => file_tags.iter().any(|t| tag_ids.contains(&t.id)), - FilterMode::All => tag_ids - .iter() - .all(|id| file_tags.iter().any(|tag| &tag.id == id)), - }; + return !excluded + && match filter_mode { + FilterMode::Any => file_tags.iter().any(|t| tag_ids.contains(&t.id)), + FilterMode::All => tag_ids + .iter() + .all(|id| file_tags.iter().any(|tag| &tag.id == id)), + }; } true -- 2.49.1 From 0419aa2323bff96c38893030c7f249c6612b56b1 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 5 Dec 2024 20:19:03 -0500 Subject: [PATCH 11/21] Scan and generate Video HLS playlists on startup Refactored and improved video path state. Bumped versions of some dependencies. --- Cargo.lock | 381 +++++++++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 11 +- README.md | 1 + src/main.rs | 24 +++- src/state.rs | 11 ++ src/video.rs | 227 +++++++++++++++++++++++++++++- 6 files changed, 593 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f587ea..18b13c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,6 +335,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -420,12 +426,58 @@ version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" +dependencies = [ + "arrayvec", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -478,6 +530,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + [[package]] name = "block-buffer" version = "0.10.4" @@ -518,6 +576,12 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "built" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" + [[package]] name = "bumpalo" version = "3.16.0" @@ -536,6 +600,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.8.0" @@ -562,6 +632,16 @@ dependencies = [ "shlex", ] +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -592,12 +672,6 @@ dependencies = [ "inout", ] -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "colorchoice" version = "1.0.3" @@ -798,7 +872,6 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", - "subtle", ] [[package]] @@ -1102,15 +1175,6 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - [[package]] name = "http" version = "0.2.12" @@ -1316,16 +1380,18 @@ dependencies = [ [[package]] name = "image" -version = "0.24.9" +version = "0.25.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", - "byteorder", - "color_quant", - "jpeg-decoder", + "byteorder-lite", "num-traits", "png", + "ravif", + "rayon", + "zune-core", + "zune-jpeg", ] [[package]] @@ -1346,7 +1412,6 @@ dependencies = [ "dotenv", "env_logger", "futures", - "hmac", "image", "jsonwebtoken", "lazy_static", @@ -1358,10 +1423,16 @@ dependencies = [ "rayon", "serde", "serde_json", - "sha2", + "tokio", "walkdir", ] +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + [[package]] name = "impl-more" version = "0.1.8" @@ -1407,12 +1478,32 @@ dependencies = [ "generic-array", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.13" @@ -1428,15 +1519,6 @@ dependencies = [ "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" -dependencies = [ - "rayon", -] - [[package]] name = "js-sys" version = "0.3.72" @@ -1499,6 +1581,16 @@ version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +[[package]] +name = "libfuzzer-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libredox" version = "0.1.3" @@ -1565,6 +1657,25 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.7.4" @@ -1608,6 +1719,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -1643,6 +1760,28 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "notify" version = "6.1.1" @@ -1678,6 +1817,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -1687,6 +1837,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1835,6 +1996,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "prometheus" version = "0.13.4" @@ -1856,6 +2036,12 @@ version = "2.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quote" version = "1.0.37" @@ -1895,6 +2081,56 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "rayon" version = "1.10.0" @@ -1959,6 +2195,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + [[package]] name = "ring" version = "0.17.8" @@ -2102,17 +2344,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "shlex" version = "1.3.0" @@ -2134,6 +2365,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "simple_asn1" version = "0.6.2" @@ -2223,6 +2463,25 @@ dependencies = [ "syn", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.14.0" @@ -2299,9 +2558,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -2434,6 +2693,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "v_htmlescape" version = "0.15.8" @@ -2446,6 +2716,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -2831,3 +3107,18 @@ dependencies = [ "cc", "pkg-config", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-jpeg" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" +dependencies = [ + "zune-core", +] diff --git a/Cargo.toml b/Cargo.toml index 39e32af..da54841 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ lto = true actix = "0.13.1" actix-web = "4" actix-rt = "2.6" +tokio = { version = "1.42.0", features = ["default", "process", "sync"] } actix-files = "0.6" actix-multipart = "0.7.2" futures = "0.3.5" @@ -20,19 +21,17 @@ jsonwebtoken = "9.3.0" serde = "1" serde_json = "1" diesel = { version = "2.2.5", features = ["sqlite"] } -diesel_migrations = "2.0.0" -hmac = "0.12.1" -sha2 = "0.10.8" +diesel_migrations = "2.2.0" chrono = "0.4" dotenv = "0.15" bcrypt = "0.16.0" -image = { version = "0.24.9", default-features = false, features = ["jpeg", "png", "jpeg_rayon"] } +image = { version = "0.25.5", default-features = false, features = ["jpeg", "png", "rayon"] } walkdir = "2.4.0" rayon = "1.5" notify = "6.1.1" path-absolutize = "3.1" -log="0.4" -env_logger= "0.11.5" +log = "0.4" +env_logger = "0.11.5" actix-web-prom = "0.9.0" prometheus = "0.13" lazy_static = "1.5" diff --git a/README.md b/README.md index 3c5b5af..0022e18 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ You must have `ffmpeg` installed for streaming video and generating video thumbn - `DATABASE_URL` is a path or url to a database (currently only SQLite is tested) - `BASE_PATH` is the root from which you want to serve images and videos - `THUMBNAILS` is a path where generated thumbnails should be stored +- `VIDEO_PATH` is a path where HLS playlists and video parts should be stored - `BIND_URL` is the url and port to bind to (typically your own IP address) - `SECRET_KEY` is the *hopefully* random string to sign Tokens with - `RUST_LOG` is one of `off, error, warn, info, debug, trace`, from least to most noisy [error is default] diff --git a/src/main.rs b/src/main.rs index 6f8d7de..b46338d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -212,9 +212,9 @@ async fn generate_video( ) -> impl Responder { let filename = PathBuf::from(&body.path); - if let Some(name) = filename.file_stem() { + if let Some(name) = filename.file_name() { let filename = name.to_str().expect("Filename should convert to string"); - let playlist = format!("tmp/{}.m3u8", filename); + let playlist = format!("{}/{}.m3u8", app_state.video_path, filename); if let Some(path) = is_valid_full_path(&app_state.base_path, &body.path, false) { if let Ok(child) = create_playlist(path.to_str().unwrap(), &playlist).await { app_state @@ -243,7 +243,7 @@ async fn stream_video( debug!("Playlist: {}", playlist); // Extract video playlist dir to dotenv - if !playlist.starts_with("tmp") + if !playlist.starts_with(&app_state.video_path) && is_valid_full_path(&app_state.base_path, playlist, false).is_some() { HttpResponse::BadRequest().finish() @@ -259,14 +259,19 @@ async fn get_video_part( request: HttpRequest, _: Claims, path: web::Path, + app_state: Data, ) -> impl Responder { let part = &path.path; debug!("Video part: {}", part); - if let Ok(file) = NamedFile::open(String::from("tmp/") + part) { + let mut file_part = PathBuf::new(); + file_part.push(app_state.video_path.clone()); + file_part.push(part); + // TODO: Do we need to guard against directory attacks here? + if let Ok(file) = NamedFile::open(&file_part) { file.into_response(&request) } else { - error!("Video part not found: tmp/{}", part); + error!("Video part not found: {:?}", file_part); HttpResponse::NotFound().finish() } } @@ -450,6 +455,7 @@ fn is_image(entry: &DirEntry) -> bool { .path() .extension() .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_lowercase()) .map(|ext| ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "nef") .unwrap_or(false) } @@ -459,6 +465,7 @@ fn is_video(entry: &DirEntry) -> bool { .path() .extension() .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_lowercase()) .map(|ext| ext == "mp4" || ext == "mov") .unwrap_or(false) } @@ -493,6 +500,13 @@ fn main() -> std::io::Result<()> { .register(Box::new(VIDEO_GAUGE.clone())) .unwrap(); + let app_state = app_data.clone(); + app_state + .playlist_manager + .do_send(ScanDirectoryMessage { + directory: app_state.base_path.clone(), + }); + HttpServer::new(move || { let user_dao = SqliteUserDao::new(); let favorites_dao = SqliteFavoriteDao::new(); diff --git a/src/state.rs b/src/state.rs index 7e2de74..5f6501c 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,11 +1,14 @@ +use crate::video::{PlaylistGenerator, VideoPlaylistManager}; use crate::StreamActor; use actix::{Actor, Addr}; use std::{env, sync::Arc}; pub struct AppState { pub stream_manager: Arc>, + pub playlist_manager: Arc>, pub base_path: String, pub thumbnail_path: String, + pub video_path: String, } impl AppState { @@ -13,11 +16,18 @@ impl AppState { stream_manager: Arc>, base_path: String, thumbnail_path: String, + video_path: String, ) -> Self { + let playlist_generator = PlaylistGenerator::new(); + let video_playlist_manager = + VideoPlaylistManager::new(video_path.clone(), playlist_generator.start()); + Self { stream_manager, + playlist_manager: Arc::new(video_playlist_manager.start()), base_path, thumbnail_path, + video_path, } } } @@ -28,6 +38,7 @@ impl Default for AppState { Arc::new(StreamActor {}.start()), env::var("BASE_PATH").expect("BASE_PATH was not set in the env"), env::var("THUMBNAILS").expect("THUMBNAILS was not set in the env"), + env::var("VIDEO_PATH").expect("VIDEO_PATH was not set in the env"), ) } } diff --git a/src/video.rs b/src/video.rs index 2280260..bd07f1c 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1,10 +1,13 @@ -use std::io::Result; -use std::path::Path; -use std::process::{Child, Command, ExitStatus, Stdio}; - +use crate::is_video; use actix::prelude::*; -use log::{debug, trace}; - +use futures::TryFutureExt; +use log::{debug, info, trace, warn}; +use std::io::Result; +use std::path::{Path, PathBuf}; +use std::process::{Child, Command, ExitStatus, Stdio}; +use std::sync::Arc; +use tokio::sync::Semaphore; +use walkdir::{DirEntry, WalkDir}; // ffmpeg -i test.mp4 -c:v h264 -flags +cgop -g 30 -hls_time 3 out.m3u8 // ffmpeg -i "filename.mp4" -preset veryfast -c:v libx264 -f hls -hls_list_size 100 -hls_time 2 -crf 24 -vf scale=1080:-2,setsar=1:1 attempt/vid_out.m3u8 @@ -93,3 +96,215 @@ pub fn generate_video_thumbnail(path: &Path, destination: &Path) { .output() .expect("Failure to create video frame"); } + +pub struct VideoPlaylistManager { + playlist_dir: PathBuf, + playlist_generator: Addr, +} + +impl VideoPlaylistManager { + pub fn new>( + playlist_dir: P, + playlist_generator: Addr, + ) -> Self { + Self { + playlist_dir: playlist_dir.into(), + playlist_generator, + } + } +} + +impl Actor for VideoPlaylistManager { + type Context = Context; +} + +impl Handler for VideoPlaylistManager { + type Result = ResponseFuture<()>; + + fn handle(&mut self, msg: ScanDirectoryMessage, _ctx: &mut Self::Context) -> Self::Result { + let start = std::time::Instant::now(); + info!( + "Starting scan directory for video playlist generation: {}", + msg.directory + ); + + let video_files = WalkDir::new(&msg.directory) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| e.file_type().is_file()) + .filter(|e| is_video(e)) + .collect::>(); + + let scan_dir_name = msg.directory.clone(); + let playlist_output_dir = self.playlist_dir.clone(); + let playlist_generator = self.playlist_generator.clone(); + + Box::pin(async move { + for e in video_files { + let path = e.path(); + let path_as_str = path.to_str().unwrap(); + debug!( + "Sending generate playlist message for path: {}", + path_as_str + ); + + match playlist_generator + .send(GeneratePlaylistMessage { + playlist_path: playlist_output_dir.to_str().unwrap().to_string(), + video_path: PathBuf::from(path), + }) + .await + .expect("Failed to send generate playlist message") + { + Ok(_) => {} + Err(e) => { + warn!("Failed to generate playlist for path '{:?}'. {:?}", path, e); + } + } + // .expect("Failed to generate video playlist"); + } + + info!( + "Finished directory scan of '{}' in {:?}", + scan_dir_name, + start.elapsed() + ); + }) + } +} + +#[derive(Message)] +#[rtype(result = "()")] +pub struct ScanDirectoryMessage { + pub(crate) directory: String, +} + +#[derive(Message)] +#[rtype(result = "Result")] +struct GeneratePlaylistMessage { + video_path: PathBuf, + playlist_path: String, +} + +pub struct PlaylistGenerator { + semaphore: Arc, +} + +impl PlaylistGenerator { + pub(crate) fn new() -> Self { + PlaylistGenerator { + semaphore: Arc::new(Semaphore::new(2)), + } + } +} + +impl Actor for PlaylistGenerator { + type Context = Context; +} + +impl Handler for PlaylistGenerator { + type Result = ResponseFuture>; + + fn handle(&mut self, msg: GeneratePlaylistMessage, _ctx: &mut Self::Context) -> Self::Result { + let video_file = msg.video_path.to_str().unwrap().to_owned(); + let playlist_path = msg.playlist_path.as_str().to_owned(); + let semaphore = self.semaphore.clone(); + + let playlist_file = format!( + "{}/{}.m3u8", + playlist_path, + msg.video_path.file_name().unwrap().to_str().unwrap() + ); + Box::pin(async move { + let wait_start = std::time::Instant::now(); + let permit = semaphore + .acquire_owned() + .await + .expect("Unable to acquire semaphore"); + + debug!( + "Waited for {:?} before starting ffmpeg", + wait_start.elapsed() + ); + + if Path::new(&playlist_file).exists() { + debug!("Playlist already exists: {}", playlist_file); + return Err(std::io::Error::from(std::io::ErrorKind::AlreadyExists)); + } + + tokio::spawn(async move { + let ffmpeg_result = tokio::process::Command::new("ffmpeg") + .arg("-i") + .arg(&video_file) + .arg("-c:v") + .arg("h264") + .arg("-crf") + .arg("21") + .arg("-preset") + .arg("veryfast") + .arg("-hls_time") + .arg("3") + .arg("-hls_list_size") + .arg("100") + .arg("-vf") + .arg("scale=1080:-2,setsar=1:1") + .arg(playlist_file) + .stdout(Stdio::null()) + .stderr(Stdio::piped()) + .status() + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) + .await; + + // Hang on to the permit until we're done decoding and then explicitly drop + drop(permit); + + ffmpeg_result + }); + + Ok("meeee".to_string()) + // .spawn() + // .expect("Failed to spawn ffmpeg process"); + + // .expect("Failed to spawn child process") + // .wait() + // .await + // .inspect_err(|e| error!("Failed to wait on child process: {}", e)); + + /* .map(|exit_status| { + debug!( + "Finished waiting for playlist generate process for file '{}' with code: {}", + video_file, + exit_status + ); + + exit_status.to_string() + }) + */ + + /* if let Some(stderr) = ffmpeg.stderr { + tokio::spawn(async move { + let mut reader = BufReader::new(stderr).lines(); + while let Ok(Some(line)) = reader.next_line().await { + println!("ffmpeg line: {:?}", line); + } + }); + }*/ + + /* ffmpeg.wait().await.map(|exit_status| { + debug!( + "Finished waiting for playlist generate process for file '{}' with code: {}", + video_file, exit_status + ); + + exit_status.to_string() + }) + */ + // ffmpeg + // .wait_with_output() + // .await + // .expect("TODO: panic message") + // + // Ok(video_file) + }) + } +} -- 2.49.1 From 8daa35b5a74d7ecaf053e6f1a6b9dd41a5006318 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 5 Dec 2024 20:19:38 -0500 Subject: [PATCH 12/21] Fix recursive search when beneath top level directory --- src/files.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/files.rs b/src/files.rs index 63a9804..e6feb99 100644 --- a/src/files.rs +++ b/src/files.rs @@ -70,7 +70,7 @@ pub async fn list_photos( .map(|tagged_files| { tagged_files .into_iter() - .filter(|f| f.starts_with(search_path)) + .filter(|f| f.starts_with(&format!("{}/", search_path).to_string())) .collect::>() }) .inspect(|files| debug!("Found {:?} files", files.len())) -- 2.49.1 From 9c2cd2566fdcb885a44702905dca08e3143cb1a0 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 5 Dec 2024 20:25:00 -0500 Subject: [PATCH 13/21] Prepare for rust edition 2021 --- src/files.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/files.rs b/src/files.rs index e6feb99..7eba0d4 100644 --- a/src/files.rs +++ b/src/files.rs @@ -396,7 +396,7 @@ mod tests { } fn move_file>(&self, from: P, destination: P) -> anyhow::Result<()> { - todo!() + } } @@ -449,6 +449,7 @@ mod tests { Arc::new(StreamActor {}.start()), String::from("/tmp"), String::from("/tmp/thumbs"), + String::from("/tmp/video"), )), Data::new(RealFileSystem::new(String::from("/tmp"))), Data::new(Mutex::new(SqliteTagDao::default())), @@ -490,6 +491,7 @@ mod tests { Arc::new(StreamActor {}.start()), String::from("/tmp"), String::from("/tmp/thumbs"), + String::from("/tmp/video"), )), Data::new(RealFileSystem::new(String::from("./"))), Data::new(Mutex::new(SqliteTagDao::default())), @@ -536,6 +538,7 @@ mod tests { Arc::new(StreamActor {}.start()), String::from(""), String::from("/tmp/thumbs"), + String::from("/tmp/video"), )), Data::new(FakeFileSystem::new(files)), Data::new(Mutex::new(tag_dao)), @@ -593,6 +596,7 @@ mod tests { Arc::new(StreamActor {}.start()), String::from(""), String::from("/tmp/thumbs"), + String::from("/tmp/video"), )), Data::new(FakeFileSystem::new(files)), Data::new(Mutex::new(tag_dao)), -- 2.49.1 From 18ba5796b0cfd3760a78d3ea0f137b2fc006b621 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 5 Dec 2024 20:27:01 -0500 Subject: [PATCH 14/21] Update to rust 2021 Fix tests --- Cargo.toml | 2 +- src/files.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index da54841..9f12df3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "image-api" version = "0.1.0" authors = ["Cameron Cordes "] -edition = "2018" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/files.rs b/src/files.rs index 7eba0d4..c9cc529 100644 --- a/src/files.rs +++ b/src/files.rs @@ -396,7 +396,7 @@ mod tests { } fn move_file>(&self, from: P, destination: P) -> anyhow::Result<()> { - + todo!() } } -- 2.49.1 From 04a7cb417f6bc91af7a27c66cc9ff89e38662d80 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 5 Dec 2024 20:30:45 -0500 Subject: [PATCH 15/21] Bump app version to 0.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18b13c8..dca8e11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1396,7 +1396,7 @@ dependencies = [ [[package]] name = "image-api" -version = "0.1.0" +version = "0.2.0" dependencies = [ "actix", "actix-files", diff --git a/Cargo.toml b/Cargo.toml index 9f12df3..9b5e957 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "image-api" -version = "0.1.0" +version = "0.2.0" authors = ["Cameron Cordes "] edition = "2021" -- 2.49.1 From 8bc9c5585e928bad766c26b75e831cc1209d7dea Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 5 Dec 2024 20:47:51 -0500 Subject: [PATCH 16/21] log ffmpeg output and cleanup video creation --- src/video.rs | 52 +++++++--------------------------------------------- 1 file changed, 7 insertions(+), 45 deletions(-) diff --git a/src/video.rs b/src/video.rs index bd07f1c..f915ee5 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1,7 +1,7 @@ use crate::is_video; use actix::prelude::*; use futures::TryFutureExt; -use log::{debug, info, trace, warn}; +use log::{debug, error, info, trace, warn}; use std::io::Result; use std::path::{Path, PathBuf}; use std::process::{Child, Command, ExitStatus, Stdio}; @@ -251,60 +251,22 @@ impl Handler for PlaylistGenerator { .arg(playlist_file) .stdout(Stdio::null()) .stderr(Stdio::piped()) - .status() + .output() + .inspect_err(|e| error!("Failed to run ffmpeg on child process: {}", e)) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) .await; // Hang on to the permit until we're done decoding and then explicitly drop drop(permit); + if let Ok(ref res) = ffmpeg_result { + debug!("ffmpeg output: {:?}", res); + } + ffmpeg_result }); Ok("meeee".to_string()) - // .spawn() - // .expect("Failed to spawn ffmpeg process"); - - // .expect("Failed to spawn child process") - // .wait() - // .await - // .inspect_err(|e| error!("Failed to wait on child process: {}", e)); - - /* .map(|exit_status| { - debug!( - "Finished waiting for playlist generate process for file '{}' with code: {}", - video_file, - exit_status - ); - - exit_status.to_string() - }) - */ - - /* if let Some(stderr) = ffmpeg.stderr { - tokio::spawn(async move { - let mut reader = BufReader::new(stderr).lines(); - while let Ok(Some(line)) = reader.next_line().await { - println!("ffmpeg line: {:?}", line); - } - }); - }*/ - - /* ffmpeg.wait().await.map(|exit_status| { - debug!( - "Finished waiting for playlist generate process for file '{}' with code: {}", - video_file, exit_status - ); - - exit_status.to_string() - }) - */ - // ffmpeg - // .wait_with_output() - // .await - // .expect("TODO: panic message") - // - // Ok(video_file) }) } } -- 2.49.1 From 787d1fd5d05df29afcceb10c6b1a4ca8b7ef39c9 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 6 Dec 2024 09:47:21 -0500 Subject: [PATCH 17/21] Fix recursive search at the root, cleanup video generation return --- src/files.rs | 12 +++++++++++- src/video.rs | 14 +++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/files.rs b/src/files.rs index c9cc529..bee4037 100644 --- a/src/files.rs +++ b/src/files.rs @@ -70,7 +70,17 @@ pub async fn list_photos( .map(|tagged_files| { tagged_files .into_iter() - .filter(|f| f.starts_with(&format!("{}/", search_path).to_string())) + .filter(|f| { + // When searching at the root, everything matches recursively + if search_path.trim() == "" { return true; } + + f.starts_with( + &format!( + "{}/", + search_path.strip_suffix('/').unwrap_or_else(|| search_path) + ), + ) + }) .collect::>() }) .inspect(|files| debug!("Found {:?} files", files.len())) diff --git a/src/video.rs b/src/video.rs index f915ee5..d593f90 100644 --- a/src/video.rs +++ b/src/video.rs @@ -156,12 +156,16 @@ impl Handler for VideoPlaylistManager { .await .expect("Failed to send generate playlist message") { - Ok(_) => {} + Ok(_) => { + debug!( + "Successfully generated playlist for file: '{}'", + path_as_str + ); + } Err(e) => { warn!("Failed to generate playlist for path '{:?}'. {:?}", path, e); } } - // .expect("Failed to generate video playlist"); } info!( @@ -180,7 +184,7 @@ pub struct ScanDirectoryMessage { } #[derive(Message)] -#[rtype(result = "Result")] +#[rtype(result = "Result<()>")] struct GeneratePlaylistMessage { video_path: PathBuf, playlist_path: String, @@ -203,7 +207,7 @@ impl Actor for PlaylistGenerator { } impl Handler for PlaylistGenerator { - type Result = ResponseFuture>; + type Result = ResponseFuture>; fn handle(&mut self, msg: GeneratePlaylistMessage, _ctx: &mut Self::Context) -> Self::Result { let video_file = msg.video_path.to_str().unwrap().to_owned(); @@ -266,7 +270,7 @@ impl Handler for PlaylistGenerator { ffmpeg_result }); - Ok("meeee".to_string()) + Ok(()) }) } } -- 2.49.1 From 03f3756ffd93f1645bedb379b6f9c98c318fed50 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 6 Dec 2024 09:54:53 -0500 Subject: [PATCH 18/21] Remove tag count from any tag query --- src/tags.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tags.rs b/src/tags.rs index db28533..fd20a84 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -379,7 +379,7 @@ impl TagDao for SqliteTagDao { .filter(tagged_photo::tag_id.ne_all(exclude_tag_ids)) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) - .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) + // .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) .select(tagged_photo::photo_name) .get_results::(&mut self.connection) .with_context(|| format!("Unable to get Tagged photos with ids: {:?}", tag_ids)) -- 2.49.1 From ff13a57d0eb4ad74aa7cb35a45f8be63d935bb84 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 6 Dec 2024 10:58:40 -0500 Subject: [PATCH 19/21] Try subquery for excluding tags --- src/tags.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tags.rs b/src/tags.rs index fd20a84..2c8ab3c 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -374,9 +374,14 @@ impl TagDao for SqliteTagDao { ) -> anyhow::Result> { use diesel::dsl::*; + let exclude_subquery = tagged_photo::table + .filter(tagged_photo::tag_id.eq_any(exclude_tag_ids.clone())) + .select(tagged_photo::photo_name) + .into_boxed(); + tagged_photo::table .filter(tagged_photo::tag_id.eq_any(tag_ids.clone())) - .filter(tagged_photo::tag_id.ne_all(exclude_tag_ids)) + .filter(tagged_photo::photo_name.ne_all(exclude_subquery)) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) // .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) -- 2.49.1 From 4a91c6344a1b5c4ad3f0fc46478919be60562547 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 6 Dec 2024 11:04:08 -0500 Subject: [PATCH 20/21] Use exclude subquery for recursive all tag search --- src/tags.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tags.rs b/src/tags.rs index 2c8ab3c..1c2d4c0 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -356,12 +356,17 @@ impl TagDao for SqliteTagDao { ) -> anyhow::Result> { use diesel::dsl::*; + let exclude_subquery = tagged_photo::table + .filter(tagged_photo::tag_id.eq_any(exclude_tag_ids.clone())) + .select(tagged_photo::photo_name) + .into_boxed(); + tagged_photo::table .filter(tagged_photo::tag_id.eq_any(tag_ids.clone())) - .filter(tagged_photo::tag_id.ne_all(exclude_tag_ids)) + .filter(tagged_photo::photo_name.ne_all(exclude_subquery)) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) - .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) + .having(count_distinct(tagged_photo::tag_id).ge(tag_ids.len() as i64)) .select(tagged_photo::photo_name) .get_results::(&mut self.connection) .with_context(|| format!("Unable to get Tagged photos with ids: {:?}", tag_ids)) @@ -384,7 +389,6 @@ impl TagDao for SqliteTagDao { .filter(tagged_photo::photo_name.ne_all(exclude_subquery)) .group_by(tagged_photo::photo_name) .select((tagged_photo::photo_name, count(tagged_photo::tag_id))) - // .having(count_distinct(tagged_photo::tag_id).eq(tag_ids.len() as i64)) .select(tagged_photo::photo_name) .get_results::(&mut self.connection) .with_context(|| format!("Unable to get Tagged photos with ids: {:?}", tag_ids)) -- 2.49.1 From 3ce1b84604a9ec8d7d29f92c553d0126413c73ed Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 6 Dec 2024 11:21:42 -0500 Subject: [PATCH 21/21] Sort on recursive search Run clippy --- src/database/mod.rs | 2 +- src/files.rs | 40 ++++++++++++++++++++-------------------- src/tags.rs | 2 +- src/testhelpers.rs | 3 +-- src/video.rs | 2 +- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index 77ac42e..dd8cc1f 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -41,7 +41,7 @@ pub mod test { .run_pending_migrations(DB_MIGRATIONS) .expect("Failure running DB migrations"); - return connection; + connection } } diff --git a/src/files.rs b/src/files.rs index bee4037..22d2e21 100644 --- a/src/files.rs +++ b/src/files.rs @@ -19,6 +19,7 @@ use log::{debug, error, info, trace}; use crate::data::{Claims, FilesRequest, FilterMode, PhotosResponse, SortType}; use crate::{create_thumbnails, AppState}; +use crate::data::SortType::{NameAsc}; use crate::error::IntoHttpError; use crate::tags::TagDao; use crate::video::StreamActor; @@ -54,7 +55,7 @@ pub async fn list_photos( let exclude_tag_ids = req .exclude_tag_ids .clone() - .unwrap_or(String::new()) + .unwrap_or_default() .split(',') .filter_map(|t| t.parse().ok()) .collect::>(); @@ -72,17 +73,18 @@ pub async fn list_photos( .into_iter() .filter(|f| { // When searching at the root, everything matches recursively - if search_path.trim() == "" { return true; } + if search_path.trim() == "" { + return true; + } - f.starts_with( - &format!( - "{}/", - search_path.strip_suffix('/').unwrap_or_else(|| search_path) - ), - ) + f.starts_with(&format!( + "{}/", + search_path.strip_suffix('/').unwrap_or_else(|| search_path) + )) }) .collect::>() }) + .map(|files| sort(files, req.sort.unwrap_or(NameAsc))) .inspect(|files| debug!("Found {:?} files", files.len())) .map(|tagged_files: Vec| { trace!( @@ -130,7 +132,7 @@ pub async fn list_photos( let excluded_tag_ids = &req .exclude_tag_ids .clone() - .unwrap_or(String::new()) + .unwrap_or_default() .split(',') .filter_map(|t| t.parse().ok()) .collect::>(); @@ -178,10 +180,10 @@ fn sort(mut files: Vec, sort_type: SortType) -> Vec { match sort_type { SortType::Shuffle => files.shuffle(&mut thread_rng()), SortType::NameAsc => { - files.sort_by(|l, r| l.cmp(&r)); + files.sort(); } SortType::NameDesc => { - files.sort_by(|l, r| r.cmp(&l)); + files.sort_by(|l, r| r.cmp(l)); } } @@ -393,15 +395,13 @@ mod tests { fn get_files_for_path(&self, path: &str) -> anyhow::Result> { if self.err { Err(anyhow!("Error for test")) + } else if let Some(files) = self.files.get(path) { + Ok(files + .iter() + .map(PathBuf::from) + .collect::>()) } else { - if let Some(files) = self.files.get(path) { - Ok(files - .iter() - .map(|p| PathBuf::from(p)) - .collect::>()) - } else { - Ok(Vec::new()) - } + Ok(Vec::new()) } } @@ -593,7 +593,7 @@ mod tests { ], ); - let request: Query = Query::from_query(&*format!( + let request: Query = Query::from_query(&format!( "path=&tag_ids={},{}&tag_filter_mode=All", tag1.id, tag3.id )) diff --git a/src/tags.rs b/src/tags.rs index 1c2d4c0..212ec7a 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -449,7 +449,7 @@ mod tests { let tag_id = self.tag_count; let tag = Tag { - id: tag_id as i32, + id: tag_id, name: name.to_string(), created_time: Utc::now().timestamp(), }; diff --git a/src/testhelpers.rs b/src/testhelpers.rs index e6097db..e288716 100644 --- a/src/testhelpers.rs +++ b/src/testhelpers.rs @@ -51,8 +51,7 @@ impl UserDao for TestUserDao { self.user_map .borrow() .iter() - .find(|&u| u.username == user) - .is_some() + .any(|u| u.username == user) } } diff --git a/src/video.rs b/src/video.rs index d593f90..b9112da 100644 --- a/src/video.rs +++ b/src/video.rs @@ -132,7 +132,7 @@ impl Handler for VideoPlaylistManager { .into_iter() .filter_map(|e| e.ok()) .filter(|e| e.file_type().is_file()) - .filter(|e| is_video(e)) + .filter(is_video) .collect::>(); let scan_dir_name = msg.directory.clone(); -- 2.49.1