diff --git a/.gitignore b/.gitignore index 2f7896d..b63ff1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ target/ +app.toml +/buckets diff --git a/Cargo.lock b/Cargo.lock index f624075..439b555 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,29 +146,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "axum-extra" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45bf463831f5131b7d3c756525b305d40f1185b688565648a92e1392ca35713d" -dependencies = [ - "axum", - "axum-core", - "bytes", - "cookie", - "futures-util", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "serde", - "tower", - "tower-layer", - "tower-service", -] - [[package]] name = "axum-macros" version = "0.5.0" @@ -257,13 +234,31 @@ dependencies = [ ] [[package]] -name = "bstr" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +name = "buckets" +version = "1.0.0" dependencies = [ - "memchr", + "axum", + "buckets-core", + "dotenv", + "pathbufd", + "tetratto-core", + "tokio", + "tower-http", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "buckets-core" +version = "1.0.1" +dependencies = [ + "oiseau", + "pathbufd", "serde", + "serde_json", + "tetratto-core", + "tetratto-shared", + "toml", ] [[package]] @@ -325,28 +320,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "chrono-tz" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" -dependencies = [ - "chrono", - "chrono-tz-build", - "phf 0.11.3", -] - -[[package]] -name = "chrono-tz-build" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" -dependencies = [ - "parse-zoneinfo", - "phf 0.11.3", - "phf_codegen", -] - [[package]] name = "combine" version = "4.6.7" @@ -367,17 +340,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -412,31 +374,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - [[package]] name = "crypto-common" version = "0.1.6" @@ -476,21 +413,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" -[[package]] -name = "deranged" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "deunicode" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" - [[package]] name = "digest" version = "0.10.7" @@ -534,12 +456,6 @@ dependencies = [ "dtoa", ] -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - [[package]] name = "emojis" version = "0.7.2" @@ -571,7 +487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -760,41 +676,11 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "globset" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "globwalk" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" -dependencies = [ - "bitflags 2.9.2", - "ignore", - "walkdir", -] - [[package]] name = "h2" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -893,15 +779,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humansize" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" -dependencies = [ - "libm", -] - [[package]] name = "hyper" version = "1.6.0" @@ -1112,22 +989,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "ignore" -version = "0.4.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata 0.4.9", - "same-file", - "walkdir", - "winapi-util", -] - [[package]] name = "image" version = "0.25.6" @@ -1148,7 +1009,6 @@ checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", - "serde", ] [[package]] @@ -1178,15 +1038,6 @@ dependencies = [ "serde", ] -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.15" @@ -1215,12 +1066,6 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" -[[package]] -name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -1268,31 +1113,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -[[package]] -name = "malachite" -version = "1.0.0" -dependencies = [ - "axum", - "axum-extra", - "dotenv", - "glob", - "nanoneo", - "oiseau", - "pathbufd", - "regex", - "serde", - "serde_json", - "serde_valid", - "tera", - "tetratto-core", - "tetratto-shared", - "tokio", - "toml 0.9.5", - "tower-http", - "tracing", - "tracing-subscriber", -] - [[package]] name = "maplit" version = "1.0.2" @@ -1389,12 +1209,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "nanoneo" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1495d19c5bed5372c613d7b4a38e8093b357f4405ce38ba1de2d6586e5c892" - [[package]] name = "native-tls" version = "0.2.14" @@ -1438,12 +1252,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-integer" version = "0.1.46" @@ -1562,15 +1370,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "parse-zoneinfo" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" -dependencies = [ - "regex", -] - [[package]] name = "paste" version = "1.0.15" @@ -1592,50 +1391,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pest" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" -dependencies = [ - "memchr", - "thiserror 2.0.12", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" -dependencies = [ - "pest", - "sha2", -] - [[package]] name = "phf" version = "0.11.3" @@ -1775,12 +1530,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1796,27 +1545,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", -] - [[package]] name = "proc-macro2" version = "1.0.95" @@ -1883,8 +1611,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", - "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -1894,20 +1620,10 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ - "rand_chacha 0.9.0", + "rand_chacha", "rand_core 0.9.3", ] -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_chacha" version = "0.9.0" @@ -1923,9 +1639,6 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] [[package]] name = "rand_core" @@ -2083,14 +1796,14 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.23.29" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2491382039b29b9b11ff08b76ff6c97cf287671dbb74f0be44bda389fffe9bd1" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "once_cell", "rustls-pki-types", @@ -2131,15 +1844,6 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "schannel" version = "0.1.27" @@ -2226,15 +1930,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - [[package]] name = "serde_spanned" version = "1.0.0" @@ -2256,52 +1951,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_valid" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b615bed66931a7a9809b273937adc8a402d038b1e509d027fcaf62f084d33d1" -dependencies = [ - "indexmap", - "itertools", - "num-traits", - "once_cell", - "paste", - "regex", - "serde", - "serde_json", - "serde_valid_derive", - "serde_valid_literal", - "thiserror 1.0.69", - "toml 0.8.23", - "unicode-segmentation", -] - -[[package]] -name = "serde_valid_derive" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fa1a5a21ea5aab06d2e6a6b59837d450fb2be9695be97735a711edfbe79ea07" -dependencies = [ - "itertools", - "paste", - "proc-macro-error2", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "serde_valid_literal" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd07331596ea967dccf9a35bde71ecd757490e09827b938a5c6226c648e3a25e" -dependencies = [ - "paste", - "regex", -] - [[package]] name = "sha1" version = "0.10.6" @@ -2363,16 +2012,6 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" -[[package]] -name = "slug" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" -dependencies = [ - "deunicode", - "wasm-bindgen", -] - [[package]] name = "smallvec" version = "1.15.1" @@ -2450,12 +2089,6 @@ dependencies = [ "unicode-properties", ] -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "subtle" version = "2.6.1" @@ -2516,15 +2149,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2538,33 +2171,11 @@ dependencies = [ "utf-8", ] -[[package]] -name = "tera" -version = "1.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee" -dependencies = [ - "chrono", - "chrono-tz", - "globwalk", - "humansize", - "lazy_static", - "percent-encoding", - "pest", - "pest_derive", - "rand 0.8.5", - "regex", - "serde", - "serde_json", - "slug", - "unic-segment", -] - [[package]] name = "tetratto-core" -version = "15.0.1" +version = "15.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7aeb9dcc5631ec6188bb9438dc97015c6662b6f59e650e5afa865775f170c9c" +checksum = "605c03fac71468f57f9c47d9246300640f3f65ec9f19fb86799e10f632d3ea68" dependencies = [ "async-recursion", "base16ct", @@ -2582,7 +2193,7 @@ dependencies = [ "tetratto-l10n", "tetratto-shared", "tokio", - "toml 0.9.5", + "toml", "totp-rs", ] @@ -2594,7 +2205,7 @@ checksum = "d96f5e41633c757e3519efb47c9b85d00d14322c1961360e126d0ecc0ea79b86" dependencies = [ "pathbufd", "serde", - "toml 0.9.5", + "toml", ] [[package]] @@ -2615,33 +2226,13 @@ dependencies = [ "uuid", ] -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - [[package]] name = "thiserror" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.12", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "thiserror-impl", ] [[package]] @@ -2664,37 +2255,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "time" -version = "0.3.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" - -[[package]] -name = "time-macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" -dependencies = [ - "num-conv", - "time-core", -] - [[package]] name = "tinystr" version = "0.8.1" @@ -2821,18 +2381,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit", -] - [[package]] name = "toml" version = "0.9.5" @@ -2841,22 +2389,13 @@ checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ "indexmap", "serde", - "serde_spanned 1.0.0", - "toml_datetime 0.7.0", + "serde_spanned", + "toml_datetime", "toml_parser", "toml_writer", "winnow", ] -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - [[package]] name = "toml_datetime" version = "0.7.0" @@ -2866,20 +2405,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", - "winnow", -] - [[package]] name = "toml_parser" version = "1.0.2" @@ -2889,12 +2414,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" version = "1.0.2" @@ -3055,7 +2574,7 @@ dependencies = [ "log", "rand 0.9.1", "sha1", - "thiserror 2.0.12", + "thiserror", "utf-8", ] @@ -3065,62 +2584,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" -[[package]] -name = "ucd-trie" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" - -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" -dependencies = [ - "unic-ucd-segment", -] - -[[package]] -name = "unic-ucd-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicase" version = "2.8.1" @@ -3154,12 +2617,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-width" version = "0.2.1" @@ -3230,16 +2687,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" version = "0.3.1" @@ -3390,15 +2837,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -3628,9 +3066,6 @@ name = "winnow" version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" -dependencies = [ - "memchr", -] [[package]] name = "wit-bindgen-rt" diff --git a/Cargo.toml b/Cargo.toml index 1f204ef..bfba647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,34 +1,19 @@ -[package] -name = "malachite" -version = "1.0.0" -edition = "2024" -authors = ["trisuaso"] -repository = "https://trisua.com/t/malachite" -license = "AGPL-3.0-or-later" -homepage = "https://trisua.com" +[workspace] +resolver = "2" +members = ["crates/buckets", "crates/buckets-core"] +package.authors = ["trisuaso"] +package.repository = "https://trisua.com/t/buckets" +package.license = "AGPL-3.0-or-later" +package.homepage = "https://tetratto.com" -[dependencies] -tetratto-core = "15.0.1" -tetratto-shared = "12.0.6" -tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] } -pathbufd = "0.1.4" -serde = { version = "1.0.219", features = ["derive"] } -tera = "1.20.0" -tracing = "0.1.41" -tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } -tower-http = { version = "0.6.6", features = [ - "trace", - "fs", - "catch-panic", - "set-header", -] } -axum = { version = "0.8.4", features = ["macros", "ws"] } -axum-extra = { version = "0.10.1", features = ["cookie"] } -nanoneo = "0.2.0" -dotenv = "0.15.0" -glob = "0.3.2" -serde_json = "1.0.142" -toml = "0.9.4" -serde_valid = { version = "1.0.5", features = ["toml"] } -regex = "1.11.1" -oiseau = { version = "0.1.2", default-features = false, features = ["postgres", "redis",] } +[profile.dev] +incremental = true + +[profile.release] +opt-level = 3 +lto = true +codegen-units = 2 +# panic = "abort" +panic = "unwind" +strip = true +incremental = true diff --git a/README.md b/README.md index 59180a5..69ac887 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ -# 🪨 malachite +# 🪣 buckets -simple template for building backends with a structure similar to how the [tetratto](https://trisua.com/t/tetratto) repository is organized +object-like storage http server + +it's basically like regular file storage, but it connects to your database to store file metadata, buckets, ids, etc. (meaning files are stored in a jumbled mess on the file system, but are controlled by entries in the database!) diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 53bfc0b..0000000 --- a/app/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -docs/**/* -!docs/example.md -icons/ -templates_build/ -public/favicon.svg -.env -app.toml diff --git a/app/docs/example.md b/app/docs/example.md deleted file mode 100644 index 11a5345..0000000 --- a/app/docs/example.md +++ /dev/null @@ -1 +0,0 @@ -# hi :) diff --git a/app/public/app.js b/app/public/app.js deleted file mode 100644 index b74d6b2..0000000 --- a/app/public/app.js +++ /dev/null @@ -1,208 +0,0 @@ -// theme preference -function media_theme_pref() { - document.documentElement.removeAttribute("class"); - - if ( - window.matchMedia("(prefers-color-scheme: dark)").matches && - (!window.localStorage.getItem("malachite.app:theme") || - window.localStorage.getItem("malachite.app:theme") === "Auto") - ) { - document.documentElement.classList.add("dark"); - - document.getElementById("switch_light").classList.add("hidden"); - document.getElementById("switch_dark").classList.remove("hidden"); - } else if ( - window.matchMedia("(prefers-color-scheme: light)").matches && - (!window.localStorage.getItem("malachite.app:theme") || - window.localStorage.getItem("malachite.app:theme") === "Auto") - ) { - document.documentElement.classList.remove("dark"); - - document.getElementById("switch_light").classList.remove("hidden"); - document.getElementById("switch_dark").classList.add("hidden"); - } else if (window.localStorage.getItem("malachite.app:theme")) { - /* restore theme */ - const current = window.localStorage.getItem("malachite.app:theme"); - document.documentElement.className = current.toLowerCase(); - - if (current === "Light") { - document.getElementById("switch_light").classList.remove("hidden"); - document.getElementById("switch_dark").classList.add("hidden"); - } else { - document.getElementById("switch_light").classList.add("hidden"); - document.getElementById("switch_dark").classList.remove("hidden"); - } - } -} - -globalThis.temporary_set_theme = (theme) => { - document.documentElement.className = theme.toLowerCase(); - - if (theme === "Light") { - document.getElementById("switch_light").classList.remove("hidden"); - document.getElementById("switch_dark").classList.add("hidden"); - } else { - document.getElementById("switch_light").classList.add("hidden"); - document.getElementById("switch_dark").classList.remove("hidden"); - } -}; - -globalThis.set_theme = (theme) => { - window.localStorage.setItem("malachite.app:theme", theme); - document.documentElement.className = theme; - media_theme_pref(); -}; - -media_theme_pref(); - -// messages -function get_cookie(key) { - return (document.cookie.split(`${key}=`)[1] || "").split(";")[0]; -} - -function check_message() { - const element = document.getElementById("messages"); - - const message = get_cookie("App-Message"); - const message_good = get_cookie("App-Message-Good") === "true"; - - if (message) { - element.style.marginBottom = "1rem"; - element.style.paddingLeft = "1rem"; - element.innerHTML = `
`; - } - - // clear cookies - for (cookie of document.cookie.split(";")) { - // biome-ignore lint/suspicious/noDocumentCookie: cookie store is barely supported - document.cookie = `${cookie.split("=")[0]}=; expires=${new Date(0).toUTCString()}; path=/`; - } -} - -globalThis.show_message = (message, message_good = true) => { - const element = document.getElementById("messages"); - element.style.marginBottom = "1rem"; - element.style.paddingLeft = "1rem"; - element.innerHTML = ` `; -}; - -check_message(); - -// components -function close_dropdowns() { - for (const dropdown of Array.from( - document.querySelectorAll(".inner.open"), - )) { - dropdown.classList.remove("open"); - } -} - -globalThis.open_dropdown = (event) => { - event.stopImmediatePropagation(); - let target = event.target; - - while (!target.matches(".dropdown")) { - target = target.parentElement; - } - - // close all others - close_dropdowns(); - - // open - setTimeout(() => { - for (const dropdown of Array.from(target.querySelectorAll(".inner"))) { - // check y - const box = target.getBoundingClientRect(); - - let parent = dropdown.parentElement; - - while (!parent.matches("html, .window")) { - parent = parent.parentElement; - } - - let parent_height = parent.getBoundingClientRect().y; - - if (parent.nodeName === "HTML") { - parent_height = window.screen.height; - } - - const scroll = window.scrollY; - const height = parent_height; - const y = box.y + scroll; - - if (y > height - scroll - 375) { - dropdown.classList.add("top"); - } else { - dropdown.classList.remove("top"); - } - - // open - dropdown.classList.add("open"); - - if (dropdown.classList.contains("open")) { - dropdown.removeAttribute("aria-hidden"); - } else { - dropdown.setAttribute("aria-hidden", "true"); - } - } - }, 5); -}; - -globalThis.init_dropdowns = (bind_to) => { - for (const dropdown of Array.from(document.querySelectorAll(".inner"))) { - dropdown.setAttribute("aria-hidden", "true"); - } - - bind_to.addEventListener("click", (event) => { - if ( - event.target.matches(".dropdown") || - event.target.matches("[exclude=dropdown]") - ) { - return; - } - - for (const dropdown of Array.from( - document.querySelectorAll(".inner.open"), - )) { - dropdown.classList.remove("open"); - } - }); -}; - -globalThis.hash_check = (hash) => { - if (hash.startsWith("#/")) { - for (const x of Array.from(document.querySelectorAll(".subpage"))) { - x.classList.add("hidden"); - } - - document.getElementById(hash).classList.remove("hidden"); - } -}; - -window.addEventListener("hashchange", (_) => hash_check(window.location.hash)); - -setTimeout(() => { - // run initial hash check - hash_check(window.location.hash); -}, 150); - -globalThis.submitter_load = (submitter) => { - return { - load() { - submitter.querySelector("[ui_ident=text]").classList.add("hidden"); - submitter - .querySelector("[ui_ident=loader]") - .classList.remove("hidden"); - submitter.setAttribute("disabled", "true"); - }, - failed() { - submitter - .querySelector("[ui_ident=text]") - .classList.remove("hidden"); - submitter - .querySelector("[ui_ident=loader]") - .classList.add("hidden"); - submitter.removeAttribute("disabled"); - }, - }; -}; diff --git a/app/public/reference b/app/public/reference deleted file mode 120000 index bb0525b..0000000 --- a/app/public/reference +++ /dev/null @@ -1 +0,0 @@ -../../target/doc \ No newline at end of file diff --git a/app/public/style.css b/app/public/style.css deleted file mode 100644 index 2f2b3b4..0000000 --- a/app/public/style.css +++ /dev/null @@ -1,705 +0,0 @@ -:root { - color-scheme: light dark; - - --color-super-lowered: oklch(87.1% 0.006 286.286); - --color-lowered: oklch(96.7% 0.001 286.375); - --color-surface: oklch(92.9% 0.013 255.508); - --color-raised: oklch(98.4% 0.003 247.858); - --color-super-raised: oklch(96.8% 0.007 247.896); - --color-text: hsl(0, 0%, 5%); - - --color-link: #2949b2; - --color-shadow: rgba(0, 0, 0, 0.08); - --color-red: hsl(0, 84%, 40%); - --color-green: hsl(100, 84%, 20%); - --color-yellow: oklch(47% 0.157 37.304); - --color-purple: hsl(284, 84%, 20%); - --color-green-lowered: hsl(100, 84%, 15%); - --color-red-lowered: hsl(0, 84%, 35%); - - --shadow-x-offset: 0; - --shadow-y-offset: 0.125rem; - --shadow-size: var(--pad-1); - - --pad-1: 0.2rem; - --pad-2: 0.35rem; - --pad-3: 0.5rem; - --pad-4: 1rem; - - --radius: 0.2rem; - --nav-height: 36px; -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; - font-size: 16px; -} - -.dark, -.dark * { - --color-super-lowered: var(--color-super-raised); - --color-lowered: var(--color-raised); - --color-surface: oklch(21% 0.006 285.885); - --color-raised: oklch(27.4% 0.006 286.033); - --color-super-raised: oklch(37% 0.013 285.805); - --color-text: hsl(0, 0%, 95%); - - --color-link: #93c5fd; - --color-red: hsl(0, 94%, 82%); - --color-green: hsl(100, 94%, 82%); - --color-yellow: oklch(90.1% 0.076 70.697); - --color-purple: hsl(284, 94%, 82%); -} - -html, -body { - line-height: 1.5; - letter-spacing: 0.15px; - font-family: - "Inter", - "Poppins", - "Roboto", - ui-sans-serif, - -apple-system, - BlinkMacSystemFont, - system-ui, - sans-serif, - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol", - "Noto Color Emoji"; - color: var(--color-text); - background: var(--color-surface); - overflow: auto auto; - height: 100dvh; - scroll-behavior: smooth; - overflow-x: hidden; -} - -main { - width: 80ch; - margin: var(--pad-4) auto; - padding: var(--pad-3) var(--pad-4); -} - -article { - margin: var(--pad-2) 0; - height: calc(100dvh - var(--pad-4) - var(--nav-height) * 2); -} - -.tab { - flex: 1 0 auto; - overflow: auto; -} - -.tabs .tab { - height: 100%; -} - -.fadein { - animation: fadein ease-in-out 1 0.5s forwards running; -} - -nav { - height: var(--nav-height); -} - -nav.sticky { - background: var(--color-raised); - position: sticky; - z-index: 2; - top: 0; -} - -@media screen and (max-width: 900px) { - main, - article, - nav, - header, - footer { - width: 100%; - } - - article { - margin-top: 0; - } - - main { - padding: 0; - } - - .flex_collapse_rev { - flex-direction: column-reverse !important; - } -} - -.container { - margin: 10px auto 0; - width: 100%; -} - -.content_container { - margin: 0 auto var(--pad-2); - width: 100%; -} - -@media screen and (min-width: 500px) { - .content_container { - max-width: 540px; - } -} - -@media (min-width: 768px) { - .content_container { - max-width: 720px; - } -} - -@media (min-width: 900px) { - .content_container { - max-width: 960px; - } - - @media (min-width: 1200px) { - article { - padding: 0; - } - - .content_container { - max-width: 1100px; - } - } -} - -video { - max-width: 100%; - border-radius: var(--radius); -} - -/* card */ -.card { - padding: var(--pad-4); - background: var(--color-raised); - color: var(--color-text); -} - -.card_nest .card:nth-child(1) { - background: var(--color-super-raised); - padding: var(--pad-2) var(--pad-4); -} - -/* button */ -.button { - --h: 36px; - display: flex; - justify-content: center; - align-items: center; - gap: var(--pad-2); - padding: var(--pad-2) calc(var(--pad-3) * 1.5); - cursor: pointer; - background: var(--color-raised); - color: var(--color-text); - outline: none; - border: none; - width: max-content; - height: var(--h); - line-height: var(--h); - transition: background 0.15s; - text-decoration: none !important; - user-select: none; - appearance: none; -} - -.button:disabled { - opacity: 50%; - cursor: not-allowed; -} - -.button.small { - --h: 28px; -} - -.button:not(:has(.button:hover)):not(.camo):hover { - background: var(--color-super-raised); -} - -.button.camo { - background: transparent; - color: inherit; -} - -.bar .button:not(.simple).camo:hover { - color: var(--color-link); -} - -.button.simple { - --size: 18px; - font-weight: 600; - padding: var(--pad-2) !important; - border-radius: var(--radius); - width: var(--size); - height: var(--size); - aspect-ratio: 1 / 1; - font-size: 12px; -} - -.button.surface { - background: var(--color-surface); -} - -.button.surface.simple:is(.camo *) { - background: var(--color-super-raised); -} - -.button.green:not(.dark *) { - background: var(--color-green); - color: white !important; - - &:hover { - background: var(--color-green-lowered) !important; - } -} - -.button.red:not(.dark *) { - background: var(--color-red); - color: white !important; - - &:hover { - background: var(--color-red-lowered) !important; - } -} - -/* dropdown */ -.dropdown { - position: relative; -} - -.dropdown .inner { - display: none; - flex-direction: column; - box-shadow: var(--shadow-x-offset) var(--shadow-y-offset) var(--shadow-size) - var(--color-shadow); - background: var(--color-raised); - color: inherit; - position: absolute; - z-index: 2; - top: 100%; - right: 0; - width: max-content; - max-width: 15rem; -} - -.dropdown .inner.left { - right: unset; - left: 0; -} - -.dropdown .inner.open { - display: flex; -} - -.dropdown .inner .button, -.dropdown .inner .title { - padding: var(--pad-3) var(--pad-4); - justify-content: flex-start; - width: 100%; -} - -.dropdown .inner .title { - font-weight: 600; - font-size: 14px; -} - -.dropdown:has(.inner.open) .button:nth-child(1):not(.inner *) { - background: var(--color-raised); -} - -.dropdown .inner.top { - top: unset; - bottom: 100%; -} - -.dropdown .inner.left { - left: 0; - right: unset; -} - -/* input */ -input { - --h: 36px; - padding: var(--pad-2) calc(var(--pad-3) * 1.5); - background: var(--color-raised); - color: var(--color-text); - outline: none; - border: none; - width: max-content; - transition: - background 0.15s, - border 0.15s; - height: var(--h); - line-height: var(--h); - border-left: solid 0px transparent; -} - -input:not([type="checkbox"]):focus { - outline: solid 2px var(--color-primary); - box-shadow: 0 0 0 4px oklch(87% 0.065 274.039 / 25%); - background: var(--color-super-raised); -} - -input:user-invalid, -input[data-invalid] { - border-left: inset 5px var(--color-red); -} - -input.surface { - background: var(--color-surface); -} - -input[type="checkbox"] { - height: max-content; -} - -/* typo */ -p, -ul, -ol { - margin-bottom: var(--pad-4) !important; - - &:last-child { - margin-bottom: 0 !important; - } -} - -.post_right:not(.repost) { - max-width: calc(100% - 52px); -} - -.rhs { - width: 100% !important; -} - -.name { - max-width: 250px; - overflow: hidden; - /* overflow-wrap: break-word; */ - overflow-wrap: anywhere; - text-overflow: ellipsis; -} - -@media screen and (min-width: 901px) { - .name.shorter { - max-width: 200px; - } - - .name.lg\:long { - max-width: unset; - } - - .rhs { - width: calc(100% - 23rem) !important; - } -} - -ul, -ol { - margin: var(--pad-2) 0 var(--pad-2) var(--pad-4); -} - -pre { - padding: var(--pad-2) var(--pad-4); - border-left: solid 5px var(--color-primary); - background: var(--color-surface); - border-radius: var(--radius); - margin-bottom: var(--pad-4); -} - -code { - padding: 0; -} - -pre, -code { - font-family: "Jetbrains Mono", "Fire Code", monospace; - width: 100%; - max-width: 100%; - overflow: auto; - border-radius: var(--radius); - font-size: 0.8rem !important; - color: inherit; -} - -code * { - font-size: 0.8rem !important; -} - -code:not(pre *) { - padding: var(--pad-1) var(--pad-2); - background: oklch(98% 0.016 73.684 / 25%); - color: oklch(90.1% 0.076 70.697); - border-radius: var(--radius); - white-space: break-spaces; -} - -code:not(pre *):not(.dark *) { - background: oklch(83.7% 0.128 66.29 / 25%); - color: oklch(47% 0.157 37.304); -} - -svg.icon { - stroke: currentColor; - fill: currentColor; - width: 18px; - height: 1em; -} - -svg.icon.filled { - fill: currentColor; -} - -.no_fill svg.icon { - fill: transparent; -} - -button svg { - pointer-events: none; -} - -hr { - border-top: solid 1px var(--color-super-lowered) !important; - border-left: 0; - border-bottom: 0; - border-right: 0; -} - -hr.margin, -.container hr { - margin: var(--pad-4) 0; -} - -span.img_sizer { - display: inline-block; -} - -p, -li, -span, -code { - max-width: 100%; - overflow-wrap: normal; - text-wrap: stable; - word-wrap: break-word; -} - -h1 { - font-size: 2rem; -} - -h2 { - font-size: 1.75rem; -} - -h3 { - font-size: 1.5rem; -} - -h4 { - font-size: 1.25rem; -} - -h5 { - font-size: var(--pad-4); -} - -h6 { - font-size: var(--pad-3); -} - -h1, -h2, -h3, -h4, -h5, -h6 { - margin: var(--pad-4) 0; - font-weight: 700; - width: -moz-max-content; - position: relative; - max-width: 100%; -} - -h1 { - text-align: center; - margin: 2rem 0; - width: 100%; -} - -a { - text-decoration: none; - color: var(--color-link); -} - -.color_block a { - color: inherit; -} - -a.flush { - color: inherit; -} - -a:hover { - text-decoration: underline; -} - -img { - display: inline; - max-width: 100%; - vertical-align: middle; -} - -.img_sizer img { - width: 100%; - height: 100%; -} - -.avatar { - --size: 18px; - width: var(--size); - height: var(--size); - aspect-ratio: 1 / 1; -} - -blockquote { - padding-left: 1rem; - border-left: solid 5px var(--color-green); - color: var(--color-green); - opacity: 75%; -} - -p, -span { - font-size: inherit; -} - -/* extra */ -@keyframes fadein { - from { - opacity: 0%; - } - - to { - opacity: 100%; - } -} - -.loader { - animation: spin linear infinite 2s forwards running; - display: flex; - justify-content: center; - align-items: center; -} - -@keyframes spin { - from { - transform: rotateZ(0deg); - } - - to { - transform: rotateZ(360deg); - } -} - -.items-end { - align-items: flex-end; -} - -/* table */ -table { - width: 100%; - table-layout: auto; - margin: var(--pad-4) 0; - border-collapse: separate; - border-spacing: 0; - border: solid 1px var(--color-super-raised); -} - -table td, -table th { - padding: var(--pad-2) var(--pad-4); -} - -table tr:not(thead *):nth-child(odd) { - background: var(--color-super-raised); -} - -table thead th { - text-align: left; -} - -/* details */ -details { - width: 100%; - margin: var(--pad-4) 0; -} - -details summary { - background: var(--color-super-raised); - padding: var(--pad-2) var(--pad-4); - cursor: pointer; -} - -details .content { - padding: var(--pad-4); - background: var(--color-surface); -} - -/* dialog */ -dialog { - background: var(--color-surface); - color: var(--color-text); - box-shadow: var(--shadow-x-offset) var(--shadow-y-offset) var(--shadow-size) - var(--color-shadow); - animation: fadein ease-in-out 1 0.25s forwards running; - max-width: 95%; - width: 30rem; - margin: auto; - padding: var(--pad-4); - border: 0; -} - -dialog.inner { - display: flex; - flex-direction: column; - gap: var(--pad-2); -} - -dialog::backdrop { - background: hsla(0, 0%, 0%, 25%); - backdrop-filter: blur(2px); -} - -dialog:is(.dark *)::backdrop { - background: hsla(0, 0%, 100%, 15%); -} - -/* menus */ -menu { - display: flex; -} - -menu .button { - justify-content: flex-start; - width: 100%; -} - -menu .button.active { - background: var(--color-super-raised); -} - -menu.col { - flex-direction: column; - width: 25rem; - max-width: 100%; -} diff --git a/app/templates_src/error.lisp b/app/templates_src/error.lisp deleted file mode 100644 index 23b614a..0000000 --- a/app/templates_src/error.lisp +++ /dev/null @@ -1,9 +0,0 @@ -(text "{% extends \"root.lisp\" %} {% block head %}") -(title - (text "Error - {{ name }}")) -(link ("rel" "icon") ("href" "/public/favicon.svg")) -(text "{% endblock %} {% block body %}") -(div - ("class" "card") - (p (text "{{ error }}"))) -(text "{% endblock %}") diff --git a/app/templates_src/index.lisp b/app/templates_src/index.lisp deleted file mode 100644 index 8a45f31..0000000 --- a/app/templates_src/index.lisp +++ /dev/null @@ -1,12 +0,0 @@ -(text "{% extends \"root.lisp\" %} {% block head %}") -(title - (text "{{ name }}")) - -(meta ("property" "og:title") ("content" "{{ name }}")) -(meta ("property" "twitter:title") ("content" "{{ name }}")) -(link ("rel" "icon") ("href" "/public/favicon.svg")) -(text "{% endblock %} {% block body %}") -(div - ("class" "card") - (h1 (text "{{ name }}"))) -(text "{% endblock %}") diff --git a/app/templates_src/root.lisp b/app/templates_src/root.lisp deleted file mode 100644 index 830ca5e..0000000 --- a/app/templates_src/root.lisp +++ /dev/null @@ -1,75 +0,0 @@ -(text "") -(html - ("lang" "en") - (head - (meta ("charset" "UTF-8")) - (meta ("name" "viewport") ("content" "width=device-width, initial-scale=1.0")) - (meta ("http-equiv" "X-UA-Compatible") ("content" "ie=edge")) - - (link ("rel" "stylesheet") ("href" "https://repodelivery.trisua.com/tetratto/crates/app/src/public/css/utility.css")) - (link ("rel" "stylesheet") ("href" "/public/style.css?v={{ build_code }}")) - - (style (text ":root { --color-primary: {{ theme_color }}; }")) - - (meta ("name" "theme-color") ("content" "{{ theme_color }}")) - (meta ("property" "og:type") ("content" "website")) - (meta ("property" "og:site_name") ("content" "{{ name }}")) - - (script ("src" "/public/app.js?v={{ build_code }}") ("defer")) - - (text "{% block head %}{% endblock %}")) - - (body - ; nav - (nav - ("class" "flex w_full justify_between gap_2 sticky") - (div - ("class" "flex side") - (div - ("class" "dropdown") - (button - ("onclick" "open_dropdown(event)") - ("exclude" "dropdown") - ("class" "button camo fade") - (text "{{ icon \"menu\" }}")) - (div - ("class" "inner left") - (a - ("class" "button") - ("href" "/") - (text "home")) - (a - ("class" "button") - ("href" "https://trisua.com/t/malachite") - (text "source")) - (text "{% block dropdown %}{% endblock %}"))) - (a ("class" "button camo") ("href" "/") (b (text "{{ name }}")))) - - (div - ("class" "side flex") - (text "{% block nav_extras %}{% endblock %}") - - ; theme switches - (button - ("class" "button camo fade") - ("id" "switch_light") - ("title" "Switch theme") - ("onclick" "set_theme('Dark')") - (text "{{ icon \"sun\" }}")) - - (button - ("class" "button camo fade hidden") - ("id" "switch_dark") - ("title" "Switch theme") - ("onclick" "set_theme('Light')") - (text "{{ icon \"moon\" }}")))) - - ; page - (article - ("class" "content_container flex flex_col") - ("id" "page") - (ul ("id" "messages")) - (text "{% block body %}{% endblock %}") - (div ("style" "min-height: 32px"))) - - (script (text "setTimeout(() => init_dropdowns(document.body), 150);")))) diff --git a/crates/buckets-core/Cargo.toml b/crates/buckets-core/Cargo.toml new file mode 100644 index 0000000..0b7b7d3 --- /dev/null +++ b/crates/buckets-core/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "buckets-core" +description = "Buckets media upload types" +version = "1.0.1" +edition = "2024" +readme = "../../README.md" +authors.workspace = true +repository.workspace = true +license.workspace = true +homepage.workspace = true + +[dependencies] +tetratto-core = "15.0.2" +tetratto-shared = "12.0.6" +pathbufd = "0.1.4" +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.142" +toml = "0.9.4" +oiseau = { version = "0.1.2", default-features = false, features = ["postgres", "redis",] } diff --git a/src/config.rs b/crates/buckets-core/src/config.rs similarity index 65% rename from src/config.rs rename to crates/buckets-core/src/config.rs index 3866212..382259a 100644 --- a/src/config.rs +++ b/crates/buckets-core/src/config.rs @@ -4,30 +4,16 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Config { - /// The name of the site. Shown in the UI. - #[serde(default = "default_name")] - pub name: String, - /// The (CSS) theme color of the site. Shown in the UI. - #[serde(default = "default_theme_color")] - pub theme_color: String, - /// Real IP header (for reverse proxy). - #[serde(default = "default_real_ip_header")] - pub real_ip_header: String, + /// The directory files are stored in (relative to cwd). + #[serde(default = "default_directory")] + pub directory: String, /// Database configuration. #[serde(default = "default_database")] pub database: DatabaseConfig, } -fn default_name() -> String { - "App".to_string() -} - -fn default_theme_color() -> String { - "#6ee7b7".to_string() -} - -fn default_real_ip_header() -> String { - "CF-Connecting-IP".to_string() +fn default_directory() -> String { + "buckets".to_string() } fn default_database() -> DatabaseConfig { @@ -43,9 +29,7 @@ impl Configuration for Config { impl Default for Config { fn default() -> Self { Self { - name: default_name(), - theme_color: default_theme_color(), - real_ip_header: default_real_ip_header(), + directory: default_directory(), database: default_database(), } } diff --git a/src/database/mod.rs b/crates/buckets-core/src/database/mod.rs similarity index 85% rename from src/database/mod.rs rename to crates/buckets-core/src/database/mod.rs index 71ffaad..3395d92 100644 --- a/src/database/mod.rs +++ b/crates/buckets-core/src/database/mod.rs @@ -1,11 +1,10 @@ mod sql; +mod uploads; use crate::config::Config; use oiseau::{execute, postgres::DataManager as OiseauManager, postgres::Result as PgResult}; use tetratto_core::model::{Error, Result}; -pub const NAME_REGEX: &str = r"[^\w_\-\.,!]+"; - #[derive(Clone)] pub struct DataManager(pub OiseauManager