diff --git a/Cargo.lock b/Cargo.lock index 8be00a9..449f98e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,16 @@ checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ "getrandom", "once_cell", - "version_check 0.9.4", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +dependencies = [ + "memchr", ] [[package]] @@ -28,50 +37,6 @@ version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" -[[package]] -name = "askama" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc2a4b6d7f812d2b13d251ae792caecebd635d6401761162d4b71d5ebe1a010" -dependencies = [ - "askama_derive", - "askama_escape", - "askama_shared", -] - -[[package]] -name = "askama_derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ee2fff0f22ad5d215cace1227cd036c28e81e26206763bb837b6d0e766c87d" -dependencies = [ - "askama_shared", - "nom 4.2.3", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - -[[package]] -name = "askama_escape" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0de942230b5beedaa9e1d64df5b76fa1c97002e4c7982897be899cccf40621d" - -[[package]] -name = "askama_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6dfa6b6d254fd066a8bbed9a8f913123e3f701db89216ad4f0aff04ad87718c" -dependencies = [ - "askama_escape", - "humansize", - "num-traits", - "serde", - "serde_derive", - "toml 0.4.10", -] - [[package]] name = "async-channel" version = "1.6.1" @@ -180,9 +145,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -267,6 +232,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + [[package]] name = "buf_redux" version = "0.8.4" @@ -339,6 +313,28 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "chrono-tz" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + [[package]] name = "clap" version = "2.34.0" @@ -388,6 +384,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -404,6 +409,12 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +[[package]] +name = "deunicode" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" + [[package]] name = "digest" version = "0.9.0" @@ -519,7 +530,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" dependencies = [ - "version_check 0.9.4", + "version_check", ] [[package]] @@ -696,9 +707,9 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -738,7 +749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", - "version_check 0.9.4", + "version_check", ] [[package]] @@ -752,6 +763,30 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "globset" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags", + "ignore", + "walkdir", +] + [[package]] name = "h2" version = "0.3.13" @@ -910,6 +945,24 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" version = "1.9.1" @@ -1051,7 +1104,7 @@ dependencies = [ "base64", "either", "log", - "nom 7.1.1", + "nom", "ternop", ] @@ -1085,7 +1138,7 @@ dependencies = [ "serde_json", "stderrlog", "tempfile", - "toml 0.5.9", + "toml", "xdg", ] @@ -1131,7 +1184,7 @@ dependencies = [ "libloading", "native-tls", "nix", - "nom 7.1.1", + "nom", "notify", "serde", "serde_derive", @@ -1239,9 +1292,10 @@ dependencies = [ name = "mpot-archives" version = "0.1.0" dependencies = [ - "askama", + "lazy_static", "mailpot", "percent-encoding", + "tera", "tokio", "warp", ] @@ -1305,16 +1359,6 @@ dependencies = [ "memoffset", ] -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -dependencies = [ - "memchr", - "version_check 0.1.5", -] - [[package]] name = "nom" version = "7.1.1" @@ -1405,9 +1449,9 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1458,12 +1502,104 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pest" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d" +dependencies = [ + "once_cell", + "pest", + "sha1", +] + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", + "uncased", +] + [[package]] name = "pin-project" version = "1.0.11" @@ -1479,9 +1615,9 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1528,10 +1664,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", - "version_check 0.9.4", + "proc-macro2", + "quote", + "syn", + "version_check", ] [[package]] @@ -1540,18 +1676,9 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "version_check 0.9.4", -] - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid", + "proc-macro2", + "quote", + "version_check", ] [[package]] @@ -1569,22 +1696,13 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", -] - [[package]] name = "quote" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ - "proc-macro2 1.0.40", + "proc-macro2", ] [[package]] @@ -1637,6 +1755,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -1794,9 +1929,9 @@ version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1846,6 +1981,17 @@ dependencies = [ "digest 0.10.3", ] +[[package]] +name = "sha1" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.3", +] + [[package]] name = "sha1_smol" version = "1.0.0" @@ -1871,12 +2017,27 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + [[package]] name = "slab" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +[[package]] +name = "slug" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" +dependencies = [ + "deunicode", +] + [[package]] name = "smallvec" version = "1.9.0" @@ -1957,20 +2118,9 @@ source = "git+https://github.com/epilys/structopt-derive-manpage#2861b6318cfe9fc dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", -] - -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1979,8 +2129,8 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", + "proc-macro2", + "quote", "unicode-ident", ] @@ -1998,6 +2148,28 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "tera" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9783d6ff395ae80cf17ed9a25360e7ba37742a79fa8fddabb073c5c7c8856d" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + [[package]] name = "termcolor" version = "1.1.3" @@ -2037,9 +2209,9 @@ version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2104,9 +2276,9 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -2161,15 +2333,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" -dependencies = [ - "serde", -] - [[package]] name = "toml" version = "0.5.9" @@ -2246,13 +2409,78 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "uncased" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" +dependencies = [ + "version_check", +] + +[[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.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.9.4", + "version_check", ] [[package]] @@ -2288,12 +2516,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - [[package]] name = "untrusted" version = "0.7.1" @@ -2341,12 +2563,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.4" @@ -2441,9 +2657,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-shared", ] @@ -2453,7 +2669,7 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" dependencies = [ - "quote 1.0.20", + "quote", "wasm-bindgen-macro-support", ] @@ -2463,9 +2679,9 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ - "proc-macro2 1.0.40", - "quote 1.0.20", - "syn 1.0.98", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/archive-http/Cargo.toml b/archive-http/Cargo.toml index f6fdff9..ce81d91 100644 --- a/archive-http/Cargo.toml +++ b/archive-http/Cargo.toml @@ -16,8 +16,9 @@ name = "mpot-archives" path = "src/main.rs" [dependencies] -askama = "0.8" +tera = "1" mailpot = { version = "0.1.0", path = "../core" } percent-encoding = "2.1" tokio = { version = "1", features = ["full"] } warp = "0.3" +lazy_static = "*" diff --git a/archive-http/src/main.rs b/archive-http/src/main.rs index 5d28609..09010a6 100644 --- a/archive-http/src/main.rs +++ b/archive-http/src/main.rs @@ -25,9 +25,30 @@ pub use mailpot::errors::*; pub use mailpot::models::*; pub use mailpot::*; -use askama::Template; -use percent_encoding::percent_decode_str; +use std::sync::Arc; +use percent_encoding::percent_decode_str; +use tera::{Context, Tera}; +use warp::Filter; + +lazy_static::lazy_static! { + pub static ref TEMPLATES: Tera = { + let mut tera = match Tera::new("src/templates/*") { + Ok(t) => t, + Err(e) => { + println!("Parsing error(s): {}", e); + ::std::process::exit(1); + } + }; + let names: Vec<_> = tera.get_template_names().collect(); + println!("names: {:?}", names); + assert!(!names.is_empty()); + tera.autoescape_on(vec![".html", ".sql"]); + tera + }; +} + +/* #[derive(Template)] #[template(path = "lists.html")] struct ListsTemplate<'a> { @@ -75,72 +96,99 @@ struct PostTemplate<'a> { _in_reply_to: Option, _references: Vec, } +*/ -use warp::Filter; #[tokio::main] async fn main() { - let list_handler = warp::path!("lists" / i64).map(|list_pk: i64| { - let db = Database::open_or_create_db().unwrap(); + let config_path = std::env::args() + .skip(1) + .next() + .expect("Expected configuration file path as first argument."); + let conf = Arc::new(Configuration::from_file(config_path).unwrap()); + + let conf1 = conf.clone(); + let list_handler = warp::path!("lists" / i64).map(move |list_pk: i64| { + let db = Database::open_db(&conf1).unwrap(); let list = db.get_list(list_pk).unwrap().unwrap(); let months = db.months(list_pk).unwrap(); let posts = db.list_posts(list_pk, None).unwrap(); - let template = ListTemplate { - title: &list.name, - list: &list, - months, - posts, - body: &list.description.clone().unwrap_or_default(), - }; - let res = template.render().unwrap(); - Ok(warp::reply::html(res)) + let mut context = Context::new(); + context.insert("title", &list.name); + context.insert("list", &list); + context.insert("months", &months); + context.insert("posts", &posts); + context.insert("body", &list.description.clone().unwrap_or_default()); + Ok(warp::reply::html( + TEMPLATES.render("list.html", &context).unwrap(), + )) }); + let conf2 = conf.clone(); let post_handler = - warp::path!("list" / i64 / String).map(|list_pk: i64, message_id: String| { + warp::path!("list" / i64 / String).map(move |list_pk: i64, message_id: String| { let message_id = percent_decode_str(&message_id).decode_utf8().unwrap(); - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_db(&conf2).unwrap(); let list = db.get_list(list_pk).unwrap().unwrap(); let posts = db.list_posts(list_pk, None).unwrap(); let post = posts - .into_iter() + .iter() .find(|p| message_id.contains(&p.message_id)) .unwrap(); let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None) .expect("Could not parse mail"); let body = envelope.body_bytes(post.message.as_slice()); let body_text = body.text(); - let template = PostTemplate { - title: &list.name, - _list: &list, - _post: post, - body: &body_text, - _from: &envelope.field_from_to_string(), - _to: &envelope.field_to_to_string(), - subject: &envelope.subject(), - _in_reply_to: envelope.in_reply_to_display().map(|r| r.to_string()), - _references: envelope + let mut context = Context::new(); + context.insert("title", &list.name); + context.insert("list", &list); + context.insert("post", &post); + context.insert("posts", &posts); + context.insert("body", &body_text); + context.insert("from", &envelope.field_from_to_string()); + context.insert("date", &envelope.date_as_str()); + context.insert("to", &envelope.field_to_to_string()); + context.insert("subject", &envelope.subject()); + context.insert( + "in_reply_to", + &envelope.in_reply_to_display().map(|r| r.to_string()), + ); + context.insert( + "references", + &envelope .references() .into_iter() .map(|m| m.to_string()) .collect::>(), - }; - let res = template.render().unwrap(); - Ok(warp::reply::html(res)) + ); + Ok(warp::reply::html( + TEMPLATES.render("post.html", &context).unwrap(), + )) }); - let index_handler = warp::path::end().map(|| { - let db = Database::open_or_create_db().unwrap(); + let conf3 = conf.clone(); + let index_handler = warp::path::end().map(move || { + let db = Database::open_db(&conf3).unwrap(); let lists_values = db.list_lists().unwrap(); + dbg!(&lists_values); let lists = lists_values .iter() - .map(|list| (list, &db).into()) - .collect::>>(); - let template = ListsTemplate { - title: "mailing list archive", - description: "", - lists_len: lists.len(), - lists, - }; - let res = template.render().unwrap(); - Ok(warp::reply::html(res)) + .map(|list| { + let mut context = Context::new(); + let months = db.months(list.pk).unwrap(); + let posts = db.list_posts(list.pk, None).unwrap(); + context.insert("title", &list.name); + context.insert("list", &list); + context.insert("posts", &posts); + context.insert("months", &months); + context.insert("body", &list.description.as_deref().unwrap_or_default()); + context.into_json() + }) + .collect::>(); + let mut context = Context::new(); + context.insert("title", "mailing list archive"); + context.insert("description", ""); + context.insert("lists", &lists); + Ok(warp::reply::html( + TEMPLATES.render("lists.html", &context).unwrap(), + )) }); let routes = warp::get() .and(index_handler) diff --git a/archive-http/templates/css.html b/archive-http/src/templates/css.html similarity index 100% rename from archive-http/templates/css.html rename to archive-http/src/templates/css.html diff --git a/archive-http/templates/footer.html b/archive-http/src/templates/footer.html similarity index 100% rename from archive-http/templates/footer.html rename to archive-http/src/templates/footer.html diff --git a/archive-http/templates/header.html b/archive-http/src/templates/header.html similarity index 100% rename from archive-http/templates/header.html rename to archive-http/src/templates/header.html diff --git a/archive-http/templates/index.html b/archive-http/src/templates/index.html similarity index 100% rename from archive-http/templates/index.html rename to archive-http/src/templates/index.html diff --git a/archive-http/templates/list.html b/archive-http/src/templates/list.html similarity index 100% rename from archive-http/templates/list.html rename to archive-http/src/templates/list.html diff --git a/archive-http/templates/lists.html b/archive-http/src/templates/lists.html similarity index 74% rename from archive-http/templates/lists.html rename to archive-http/src/templates/lists.html index caca741..067ed53 100644 --- a/archive-http/templates/lists.html +++ b/archive-http/src/templates/lists.html @@ -1,9 +1,9 @@ {% include "header.html" %}
-

{{lists_len}} lists

+

{{lists|length}} lists

{% for list in lists %} - {{ list }} + {{ list.title }} {% endfor %}
diff --git a/archive-http/templates/menu.html b/archive-http/src/templates/menu.html similarity index 100% rename from archive-http/templates/menu.html rename to archive-http/src/templates/menu.html diff --git a/archive-http/src/templates/post.html b/archive-http/src/templates/post.html new file mode 100644 index 0000000..a1b9165 --- /dev/null +++ b/archive-http/src/templates/post.html @@ -0,0 +1,36 @@ +{% include "header.html" %} +
+

{{subject}}

+ + + + + + + + + + + + + + + + + + + + + + {% if in_reply_to %} + + + + + {% endif %} +
List{{ list.id }}
From{{ from }}
Date{{ date }}
To{{ to }}
Subject{{ subject }}
In-Reply-To{{ in_reply_to }}
+
+
{{body}}
+
+
+{% include "footer.html" %} diff --git a/archive-http/templates/post.html b/archive-http/templates/post.html deleted file mode 100644 index 3902aa2..0000000 --- a/archive-http/templates/post.html +++ /dev/null @@ -1,10 +0,0 @@ -{% include "header.html" %} -
-

{{subject}}

-
-
-        {{body}}
-      
-
-
-{% include "footer.html" %} diff --git a/cli/src/main.rs b/cli/src/main.rs index 4c89e3b..6d48975 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -48,7 +48,7 @@ struct Opt { /// Set config file #[structopt(short, long, parse(from_os_str))] #[allow(dead_code)] - config: Option, + config: PathBuf, #[structopt(flatten)] cmd: Command, /// Silence all output @@ -65,10 +65,6 @@ struct Opt { #[derive(Debug, StructOpt)] #[structopt(manpage = "docs/command.mdoc")] enum Command { - ///Prints database filesystem location - DbLocation, - ///Prints default configuration file filesystem location - ConfigLocation, ///Dumps database data to STDOUT DumpDatabase, ///Lists all registered mailing lists @@ -238,22 +234,11 @@ fn run_app(opt: Opt) -> Result<()> { if opt.debug { println!("DEBUG: {:?}", &opt); } - if let Some(config_path) = opt.config.as_ref() { - let config = Configuration::from_file(&config_path)?; - config.init_with()?; - } else { - Configuration::init()?; - } + let config = Configuration::from_file(opt.config.as_path())?; use Command::*; + let mut db = Database::open_or_create_db(&config)?; match opt.cmd { - DbLocation => { - println!("{}", Database::db_path()?.display()); - } - ConfigLocation => { - println!("{}", Configuration::default_path()?.display()); - } DumpDatabase => { - let db = Database::open_or_create_db()?; let lists = db.list_lists()?; let mut stdout = std::io::stdout(); serde_json::to_writer_pretty(&mut stdout, &lists)?; @@ -262,7 +247,6 @@ fn run_app(opt: Opt) -> Result<()> { } } ListLists => { - let db = Database::open_or_create_db()?; let lists = db.list_lists()?; if lists.is_empty() { println!("No lists found."); @@ -288,7 +272,6 @@ fn run_app(opt: Opt) -> Result<()> { } } List { list_id, cmd } => { - let db = Database::open_or_create_db()?; let list = match db.get_list_by_id(&list_id)? { Some(v) => v, None => { @@ -531,7 +514,6 @@ fn run_app(opt: Opt) -> Result<()> { description, archive_url, } => { - let db = Database::open_or_create_db()?; let new = db.create_list(MailingList { pk: 0, name, @@ -564,12 +546,15 @@ fn run_app(opt: Opt) -> Result<()> { if opt.debug { std::dbg!(&env); } - let db = Database::open_or_create_db()?; db.post(&env, input.as_bytes(), dry_run)?; } + Err(err) if input.trim().is_empty() => { + eprintln!("Empty input, abort."); + return Err(err.into()); + } Err(err) => { eprintln!("Could not parse message: {}", err); - let p = Configuration::save_message(input)?; + let p = config.save_message(input)?; eprintln!("Message saved at {}", p.display()); return Err(err.into()); } @@ -577,7 +562,6 @@ fn run_app(opt: Opt) -> Result<()> { } ErrorQueue { cmd } => match cmd { ErrorQueueCommand::List => { - let db = Database::open_or_create_db()?; let errors = db.error_queue()?; if errors.is_empty() { println!("Error queue is empty."); @@ -595,7 +579,6 @@ fn run_app(opt: Opt) -> Result<()> { } } ErrorQueueCommand::Print { index, json } => { - let db = Database::open_or_create_db()?; let mut errors = db.error_queue()?; if !index.is_empty() { errors.retain(|el| index.contains(&el.pk())); @@ -613,7 +596,6 @@ fn run_app(opt: Opt) -> Result<()> { } } ErrorQueueCommand::Delete { index, quiet } => { - let mut db = Database::open_or_create_db()?; let mut errors = db.error_queue()?; if !index.is_empty() { errors.retain(|el| index.contains(&el.pk())); @@ -639,7 +621,6 @@ fn run_app(opt: Opt) -> Result<()> { list_id, mut maildir_path, } => { - let db = Database::open_or_create_db()?; let list = match db.get_list_by_id(&list_id)? { Some(v) => v, None => { diff --git a/core/src/config.rs b/core/src/config.rs index 7722ba7..dbb6e3f 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -24,9 +24,6 @@ use std::io::{Read, Write}; use std::os::unix::fs::PermissionsExt; use std::path::{Path, PathBuf}; -thread_local!(pub static CONFIG: RefCell = RefCell::new(Configuration::new())); -thread_local!(static CONFIG_INIT: Cell = Cell::new(false)); - #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(tag = "type", content = "value")] pub enum SendMail { @@ -40,33 +37,24 @@ pub struct Configuration { #[serde(default = "default_storage_fn")] pub storage: String, pub db_path: PathBuf, -} - -impl Default for Configuration { - fn default() -> Self { - Self::new() - } + pub data_path: PathBuf, } impl Configuration { - pub(crate) fn new() -> Self { + /* + pub fn new(db_path: impl Into) -> Self { + let db_path = db_path.into(); Configuration { send_mail: SendMail::ShellCommand("/usr/bin/false".to_string()), storage: "sqlite3".into(), - db_path: ".".into(), + data_path: db_path + .parent() + .map(Path::to_path_buf) + .unwrap_or_else(|| db_path.clone()), + db_path, } } - - pub fn init_with(self) -> Result<()> { - CONFIG.with(|f| { - *f.borrow_mut() = self; - }); - CONFIG_INIT.with(|f| { - f.set(true); - }); - - Ok(()) - } + */ pub fn from_file>(path: P) -> Result { let path = path.as_ref(); @@ -81,27 +69,12 @@ impl Configuration { Ok(config) } - pub fn init() -> Result<()> { - if CONFIG_INIT.with(|f| f.get()) { - return Ok(()); - } - let mut path = - xdg::BaseDirectories::with_prefix("mailpot")?.place_config_file("config.toml")?; - if !path.exists() { - return Err(format!("Configuration file {} doesn't exist", path.display()).into()); - } - if path.starts_with("~") { - path = Path::new(&std::env::var("HOME").context("No $HOME set.")?) - .join(path.strip_prefix("~").context("Internal error while getting default database path: path starts with ~ but rust couldn't strip_refix(\"~\"")?); - } - let config: Configuration = Self::from_file(&path)?; - config.init_with() + pub fn data_directory(&self) -> &Path { + self.data_path.as_path() } - pub fn data_directory() -> Result { - Ok(xdg::BaseDirectories::with_prefix("mailpot")? - .get_data_home() - .canonicalize()?) + pub fn db_path(&self) -> &Path { + self.db_path.as_path() } pub fn default_path() -> Result { @@ -114,10 +87,13 @@ impl Configuration { Ok(result) } - pub fn save_message_to_path(msg: &str, mut path: PathBuf) -> Result { - let now = Local::now().timestamp(); - path.push(format!("{}-failed.eml", now)); + pub fn save_message_to_path(&self, msg: &str, mut path: PathBuf) -> Result { + if path.is_dir() { + let now = Local::now().timestamp(); + path.push(format!("{}-failed.eml", now)); + } + debug_assert!(path != self.db_path()); let mut file = std::fs::File::create(&path)?; let metadata = file.metadata()?; let mut permissions = metadata.permissions(); @@ -129,23 +105,8 @@ impl Configuration { Ok(path) } - pub fn save_message(msg: String) -> Result { - match Configuration::data_directory() - .and_then(|path| Self::save_message_to_path(&msg, path)) - { - Ok(p) => return Ok(p), - Err(err) => { - eprintln!("{}", err); - } - }; - match Self::save_message_to_path(&msg, PathBuf::from(".")) { - Ok(p) => return Ok(p), - Err(err) => { - eprintln!("{}", err); - } - } - let temp_path = std::env::temp_dir(); - Self::save_message_to_path(&msg, temp_path) + pub fn save_message(&self, msg: String) -> Result { + self.save_message_to_path(&msg, self.data_directory().to_path_buf()) } } diff --git a/core/src/db.rs b/core/src/db.rs index 4569687..302e0a9 100644 --- a/core/src/db.rs +++ b/core/src/db.rs @@ -17,6 +17,7 @@ * along with this program. If not, see . */ +use super::Configuration; use super::*; use crate::ErrorKind::*; use melib::Envelope; @@ -25,13 +26,14 @@ use rusqlite::Connection as DbConnection; use rusqlite::OptionalExtension; use std::convert::TryFrom; use std::io::Write; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; const DB_NAME: &str = "current.db"; pub struct Database { pub connection: DbConnection, + conf: Configuration, } mod error_queue; @@ -42,22 +44,18 @@ mod members; pub use members::*; impl Database { - pub fn db_path() -> Result { - Ok(crate::config::CONFIG.with(|c| c.borrow().db_path.clone())) - } - - pub fn open_db(db_path: PathBuf) -> Result { - if !db_path.exists() { + pub fn open_db(conf: &Configuration) -> Result { + if !conf.db_path.exists() { return Err("Database doesn't exist".into()); } Ok(Database { - connection: DbConnection::open(&db_path.to_str().unwrap())?, + conf: conf.clone(), + connection: DbConnection::open(&conf.db_path.to_str().unwrap())?, }) } - pub fn open_or_create_db() -> Result { - crate::config::Configuration::init()?; - let mut db_path = Self::db_path()?; + pub fn open_or_create_db(conf: &Configuration) -> Result { + let mut db_path = conf.db_path.to_path_buf(); if db_path.is_dir() { db_path.push(DB_NAME); } @@ -100,11 +98,14 @@ impl Database { let conn = DbConnection::open(&db_path.to_str().unwrap())?; - Ok(Database { connection: conn }) + Ok(Database { + conf: conf.clone(), + connection: conn, + }) } - pub fn load_archives(&mut self) -> Result<&mut Self> { - let archives_path = crate::config::CONFIG.with(|c| c.borrow().db_path.clone()); + pub fn load_archives(&mut self, conf: &Configuration) -> Result<&mut Self> { + let archives_path = conf.data_path.clone(); let mut stmt = self.connection.prepare("ATTACH ? AS ?;")?; for archive in std::fs::read_dir(&archives_path)? { let archive = archive?; @@ -232,7 +233,7 @@ impl Database { pub fn remove_list_policy(&self, list_pk: i64, policy_pk: i64) -> Result<()> { let mut stmt = self .connection - .prepare("DELETE FROM post_policy WHERE pk = ? AND list_pk = ?;")?; + .prepare("DELETE FROM post_policy WHERE pk = ? AND list = ?;")?; stmt.execute(rusqlite::params![&policy_pk, &list_pk,])?; trace!("remove_list_policy {} {}.", list_pk, policy_pk); @@ -240,6 +241,13 @@ impl Database { } pub fn set_list_policy(&self, list_pk: i64, policy: PostPolicy) -> Result> { + if !(policy.announce_only || policy.subscriber_only || policy.approval_needed) { + return Err( + "Cannot add empty policy. Having no policies is probably what you want to do." + .into(), + ); + } + let mut stmt = self.connection.prepare("INSERT OR REPLACE INTO post_policy(list, announce_only, subscriber_only, approval_needed) VALUES (?, ?, ?, ?) RETURNING *;")?; let ret = stmt.query_row( rusqlite::params![ diff --git a/core/src/db/posts.rs b/core/src/db/posts.rs index 48f5842..da6fcb5 100644 --- a/core/src/db/posts.rs +++ b/core/src/db/posts.rs @@ -119,11 +119,7 @@ impl Database { return Ok(()); } - let mut configuration = crate::config::Configuration::new(); - crate::config::CONFIG.with(|f| { - configuration = f.borrow().clone(); - }); - trace!("Configuration is {:#?}", &configuration); + trace!("Configuration is {:#?}", &self.conf); use crate::mail::{ListContext, Post, PostAction}; for mut list in lists { trace!("Examining list {}", list.list_id()); @@ -161,7 +157,7 @@ impl Database { trace!("recipients: {:?}", &recipients); if let crate::config::SendMail::Smtp(ref smtp_conf) = - &configuration.send_mail + &self.conf.send_mail { let smtp_conf = smtp_conf.clone(); use melib::futures; diff --git a/core/tests/creation.rs b/core/tests/creation.rs index e24ed41..359e03f 100644 --- a/core/tests/creation.rs +++ b/core/tests/creation.rs @@ -1,4 +1,4 @@ -use mailpot::{models::*, Configuration, Database}; +use mailpot::{models::*, Configuration, Database, SendMail}; use tempfile::TempDir; #[test] @@ -6,13 +6,17 @@ fn test_init_empty() { let tmp_dir = TempDir::new().unwrap(); let db_path = tmp_dir.path().join("mpot.db"); - let mut config = Configuration::default(); - config.db_path = db_path.clone(); + let config = Configuration { + send_mail: SendMail::ShellCommand("/usr/bin/false".to_string()), + db_path: db_path.clone(), + storage: "sqlite3".to_string(), + data_path: tmp_dir.path().to_path_buf(), + }; config.init_with().unwrap(); assert_eq!(Database::db_path().unwrap(), db_path); - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&db_path).unwrap(); assert!(db.list_lists().unwrap().is_empty()); } @@ -21,13 +25,17 @@ fn test_list_creation() { let tmp_dir = TempDir::new().unwrap(); let db_path = tmp_dir.path().join("mpot.db"); - let mut config = Configuration::default(); - config.db_path = db_path.clone(); + let config = Configuration { + send_mail: SendMail::ShellCommand("/usr/bin/false".to_string()), + db_path: db_path.clone(), + storage: "sqlite3".to_string(), + data_path: tmp_dir.path().to_path_buf(), + }; config.init_with().unwrap(); assert_eq!(Database::db_path().unwrap(), db_path); - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&db_path).unwrap(); assert!(db.list_lists().unwrap().is_empty()); let foo_chat = db .create_list(MailingList { diff --git a/core/tests/error_queue.rs b/core/tests/error_queue.rs index a0643a0..611114c 100644 --- a/core/tests/error_queue.rs +++ b/core/tests/error_queue.rs @@ -25,14 +25,17 @@ fn test_error_queue() { let tmp_dir = TempDir::new().unwrap(); let db_path = tmp_dir.path().join("mpot.db"); - let mut config = Configuration::default(); - config.send_mail = SendMail::Smtp(get_smtp_conf()); - config.db_path = db_path.clone(); + let config = Configuration { + send_mail: SendMail::Smtp(get_smtp_conf()), + db_path: db_path.clone(), + storage: "sqlite3".to_string(), + data_path: tmp_dir.path().to_path_buf(), + }; config.init_with().unwrap(); assert_eq!(Database::db_path().unwrap(), db_path); - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&db_path).unwrap(); assert!(db.list_lists().unwrap().is_empty()); let foo_chat = db .create_list(MailingList { diff --git a/core/tests/smtp.rs b/core/tests/smtp.rs index d840882..fe4b349 100644 --- a/core/tests/smtp.rs +++ b/core/tests/smtp.rs @@ -192,14 +192,17 @@ fn test_smtp() { }); let db_path = tmp_dir.path().join("mpot.db"); - let mut config = Configuration::default(); - config.send_mail = SendMail::Smtp(get_smtp_conf()); - config.db_path = db_path.clone(); - config.init_with().unwrap(); + let config = Configuration { + send_mail: SendMail::Smtp(get_smtp_conf()), + db_path: db_path.clone(), + storage: "sqlite3".to_string(), + data_path: tmp_dir.path().to_path_buf(), + }; + config.clone().init_with().unwrap(); assert_eq!(Database::db_path().unwrap(), db_path); - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&config.db_path).unwrap(); assert!(db.list_lists().unwrap().is_empty()); let foo_chat = db .create_list(MailingList { diff --git a/docs/command.mdoc b/docs/command.mdoc index bbefdad..7dd119c 100644 --- a/docs/command.mdoc +++ b/docs/command.mdoc @@ -1,9 +1,5 @@ .Bl -tag -width Ds -compact -offset indent -.It Ic db-location -Prints database filesystem location. -.It Ic config-location -Prints default configuration file filesystem location. .It Ic dump-database Dumps database data to STDOUT. .It Ic list-lists @@ -39,10 +35,6 @@ Mail that has not been handled properly end up in the error queue. . Import a maildir folder into an existing list. -.It Ic db-location -Prints database filesystem location. -.It Ic config-location -Prints default configuration file filesystem location. .It Ic dump-database Dumps database data to STDOUT. .It Ic list-lists diff --git a/docs/mailpot.1 b/docs/mailpot.1 index e481ebb..4e2babe 100644 --- a/docs/mailpot.1 +++ b/docs/mailpot.1 @@ -31,10 +31,6 @@ This command-line tool allows you to control databases of the mailing list manag .Sh COMMANDS .Bl -tag -width Ds -compact -offset indent -.It Ic db-location -Prints database filesystem location. -.It Ic config-location -Prints default configuration file filesystem location. .It Ic dump-database Dumps database data to STDOUT. .It Ic list-lists @@ -70,10 +66,6 @@ Mail that has not been handled properly end up in the error queue. . Import a maildir folder into an existing list. -.It Ic db-location -Prints database filesystem location. -.It Ic config-location -Prints default configuration file filesystem location. .It Ic dump-database Dumps database data to STDOUT. .It Ic list-lists diff --git a/rest-http/src/main.rs b/rest-http/src/main.rs index 471f0ed..54c8684 100644 --- a/rest-http/src/main.rs +++ b/rest-http/src/main.rs @@ -37,9 +37,15 @@ fn json_body() -> impl Filter + Cl #[tokio::main] async fn main() { + let config_path = std::env::args() + .skip(1) + .next() + .expect("Expected configuration file path as first argument."); + Configuration::init(config_path).unwrap(); + // GET /lists/:i64/policy let policy = warp::path!("lists" / i64 / "policy").map(|list_pk| { - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&Configuration::db_path().unwrap()).unwrap(); db.get_list_policy(list_pk) .ok() .map(|l| warp::reply::json(&l.unwrap())) @@ -48,21 +54,21 @@ async fn main() { //get("/lists")] let lists = warp::path!("lists").map(|| { - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&Configuration::db_path().unwrap()).unwrap(); let lists = db.list_lists().unwrap(); warp::reply::json(&lists) }); //get("/lists/")] let lists_num = warp::path!("lists" / i64).map(|list_pk| { - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&Configuration::db_path().unwrap()).unwrap(); let list = db.get_list(list_pk).unwrap(); warp::reply::json(&list) }); //get("/lists//members")] let lists_members = warp::path!("lists" / i64 / "members").map(|list_pk| { - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&Configuration::db_path().unwrap()).unwrap(); db.list_members(list_pk) .ok() .map(|l| warp::reply::json(&l)) @@ -71,7 +77,7 @@ async fn main() { //get("/lists//owners")] let lists_owners = warp::path!("lists" / i64 / "owners").map(|list_pk| { - let db = Database::open_or_create_db().unwrap(); + let db = Database::open_or_create_db(&Configuration::db_path().unwrap()).unwrap(); db.get_list_owners(list_pk) .ok() .map(|l| warp::reply::json(&l))