Change template lib to tera
parent
ddb6d225aa
commit
2af8fe1b5e
|
@ -10,7 +10,16 @@ checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"once_cell",
|
"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]]
|
[[package]]
|
||||||
|
@ -28,50 +37,6 @@ version = "1.0.58"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
|
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]]
|
[[package]]
|
||||||
name = "async-channel"
|
name = "async-channel"
|
||||||
version = "1.6.1"
|
version = "1.6.1"
|
||||||
|
@ -180,9 +145,9 @@ version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
|
checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -267,6 +232,15 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bstr"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "buf_redux"
|
name = "buf_redux"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
|
@ -339,6 +313,28 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"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]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.34.0"
|
version = "2.34.0"
|
||||||
|
@ -388,6 +384,15 @@ dependencies = [
|
||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -404,6 +409,12 @@ version = "2.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
|
checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deunicode"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -519,7 +530,7 @@ version = "0.12.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"version_check 0.9.4",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -696,9 +707,9 @@ version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
|
checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -738,7 +749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
|
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
"version_check 0.9.4",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -752,6 +763,30 @@ dependencies = [
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"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]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.13"
|
version = "0.3.13"
|
||||||
|
@ -910,6 +945,24 @@ dependencies = [
|
||||||
"unicode-normalization",
|
"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]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.1"
|
version = "1.9.1"
|
||||||
|
@ -1051,7 +1104,7 @@ dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"either",
|
"either",
|
||||||
"log",
|
"log",
|
||||||
"nom 7.1.1",
|
"nom",
|
||||||
"ternop",
|
"ternop",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1085,7 +1138,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"stderrlog",
|
"stderrlog",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"toml 0.5.9",
|
"toml",
|
||||||
"xdg",
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1131,7 +1184,7 @@ dependencies = [
|
||||||
"libloading",
|
"libloading",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"nix",
|
"nix",
|
||||||
"nom 7.1.1",
|
"nom",
|
||||||
"notify",
|
"notify",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
@ -1239,9 +1292,10 @@ dependencies = [
|
||||||
name = "mpot-archives"
|
name = "mpot-archives"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"askama",
|
"lazy_static",
|
||||||
"mailpot",
|
"mailpot",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
"tera",
|
||||||
"tokio",
|
"tokio",
|
||||||
"warp",
|
"warp",
|
||||||
]
|
]
|
||||||
|
@ -1305,16 +1359,6 @@ dependencies = [
|
||||||
"memoffset",
|
"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]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.1"
|
version = "7.1.1"
|
||||||
|
@ -1405,9 +1449,9 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1458,12 +1502,104 @@ dependencies = [
|
||||||
"windows-sys",
|
"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]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
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]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
|
@ -1479,9 +1615,9 @@ version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74"
|
checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1528,10 +1664,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-error-attr",
|
"proc-macro-error-attr",
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
"version_check 0.9.4",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1540,18 +1676,9 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"version_check 0.9.4",
|
"version_check",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "0.4.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-xid",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1569,22 +1696,13 @@ version = "1.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
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]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1637,6 +1755,23 @@ dependencies = [
|
||||||
"thiserror",
|
"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]]
|
[[package]]
|
||||||
name = "remove_dir_all"
|
name = "remove_dir_all"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
@ -1794,9 +1929,9 @@ version = "1.0.139"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb"
|
checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1846,6 +1981,17 @@ dependencies = [
|
||||||
"digest 0.10.3",
|
"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]]
|
[[package]]
|
||||||
name = "sha1_smol"
|
name = "sha1_smol"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -1871,12 +2017,27 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "0.3.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
|
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slug"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
|
||||||
|
dependencies = [
|
||||||
|
"deunicode",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
@ -1957,20 +2118,9 @@ source = "git+https://github.com/epilys/structopt-derive-manpage#2861b6318cfe9fc
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
|
||||||
|
|
||||||
[[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",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1979,8 +2129,8 @@ version = "1.0.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1998,6 +2148,28 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"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]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -2037,9 +2209,9 @@ version = "1.0.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2104,9 +2276,9 @@ version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2161,15 +2333,6 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.4.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.9"
|
version = "0.5.9"
|
||||||
|
@ -2246,13 +2409,78 @@ version = "1.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
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]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"version_check 0.9.4",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2288,12 +2516,6 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -2341,12 +2563,6 @@ version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
@ -2441,9 +2657,9 @@ dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2453,7 +2669,7 @@ version = "0.2.81"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
|
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2463,9 +2679,9 @@ version = "0.2.81"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
|
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.40",
|
"proc-macro2",
|
||||||
"quote 1.0.20",
|
"quote",
|
||||||
"syn 1.0.98",
|
"syn",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,8 +16,9 @@ name = "mpot-archives"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
askama = "0.8"
|
tera = "1"
|
||||||
mailpot = { version = "0.1.0", path = "../core" }
|
mailpot = { version = "0.1.0", path = "../core" }
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
warp = "0.3"
|
warp = "0.3"
|
||||||
|
lazy_static = "*"
|
||||||
|
|
|
@ -25,9 +25,30 @@ pub use mailpot::errors::*;
|
||||||
pub use mailpot::models::*;
|
pub use mailpot::models::*;
|
||||||
pub use mailpot::*;
|
pub use mailpot::*;
|
||||||
|
|
||||||
use askama::Template;
|
use std::sync::Arc;
|
||||||
use percent_encoding::percent_decode_str;
|
|
||||||
|
|
||||||
|
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)]
|
#[derive(Template)]
|
||||||
#[template(path = "lists.html")]
|
#[template(path = "lists.html")]
|
||||||
struct ListsTemplate<'a> {
|
struct ListsTemplate<'a> {
|
||||||
|
@ -75,72 +96,99 @@ struct PostTemplate<'a> {
|
||||||
_in_reply_to: Option<String>,
|
_in_reply_to: Option<String>,
|
||||||
_references: Vec<String>,
|
_references: Vec<String>,
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
use warp::Filter;
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let list_handler = warp::path!("lists" / i64).map(|list_pk: i64| {
|
let config_path = std::env::args()
|
||||||
let db = Database::open_or_create_db().unwrap();
|
.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 list = db.get_list(list_pk).unwrap().unwrap();
|
||||||
let months = db.months(list_pk).unwrap();
|
let months = db.months(list_pk).unwrap();
|
||||||
let posts = db.list_posts(list_pk, None).unwrap();
|
let posts = db.list_posts(list_pk, None).unwrap();
|
||||||
let template = ListTemplate {
|
let mut context = Context::new();
|
||||||
title: &list.name,
|
context.insert("title", &list.name);
|
||||||
list: &list,
|
context.insert("list", &list);
|
||||||
months,
|
context.insert("months", &months);
|
||||||
posts,
|
context.insert("posts", &posts);
|
||||||
body: &list.description.clone().unwrap_or_default(),
|
context.insert("body", &list.description.clone().unwrap_or_default());
|
||||||
};
|
Ok(warp::reply::html(
|
||||||
let res = template.render().unwrap();
|
TEMPLATES.render("list.html", &context).unwrap(),
|
||||||
Ok(warp::reply::html(res))
|
))
|
||||||
});
|
});
|
||||||
|
let conf2 = conf.clone();
|
||||||
let post_handler =
|
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 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 list = db.get_list(list_pk).unwrap().unwrap();
|
||||||
let posts = db.list_posts(list_pk, None).unwrap();
|
let posts = db.list_posts(list_pk, None).unwrap();
|
||||||
let post = posts
|
let post = posts
|
||||||
.into_iter()
|
.iter()
|
||||||
.find(|p| message_id.contains(&p.message_id))
|
.find(|p| message_id.contains(&p.message_id))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None)
|
let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None)
|
||||||
.expect("Could not parse mail");
|
.expect("Could not parse mail");
|
||||||
let body = envelope.body_bytes(post.message.as_slice());
|
let body = envelope.body_bytes(post.message.as_slice());
|
||||||
let body_text = body.text();
|
let body_text = body.text();
|
||||||
let template = PostTemplate {
|
let mut context = Context::new();
|
||||||
title: &list.name,
|
context.insert("title", &list.name);
|
||||||
_list: &list,
|
context.insert("list", &list);
|
||||||
_post: post,
|
context.insert("post", &post);
|
||||||
body: &body_text,
|
context.insert("posts", &posts);
|
||||||
_from: &envelope.field_from_to_string(),
|
context.insert("body", &body_text);
|
||||||
_to: &envelope.field_to_to_string(),
|
context.insert("from", &envelope.field_from_to_string());
|
||||||
subject: &envelope.subject(),
|
context.insert("date", &envelope.date_as_str());
|
||||||
_in_reply_to: envelope.in_reply_to_display().map(|r| r.to_string()),
|
context.insert("to", &envelope.field_to_to_string());
|
||||||
_references: envelope
|
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()
|
.references()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|m| m.to_string())
|
.map(|m| m.to_string())
|
||||||
.collect::<Vec<String>>(),
|
.collect::<Vec<String>>(),
|
||||||
};
|
);
|
||||||
let res = template.render().unwrap();
|
Ok(warp::reply::html(
|
||||||
Ok(warp::reply::html(res))
|
TEMPLATES.render("post.html", &context).unwrap(),
|
||||||
|
))
|
||||||
});
|
});
|
||||||
let index_handler = warp::path::end().map(|| {
|
let conf3 = conf.clone();
|
||||||
let db = Database::open_or_create_db().unwrap();
|
let index_handler = warp::path::end().map(move || {
|
||||||
|
let db = Database::open_db(&conf3).unwrap();
|
||||||
let lists_values = db.list_lists().unwrap();
|
let lists_values = db.list_lists().unwrap();
|
||||||
|
dbg!(&lists_values);
|
||||||
let lists = lists_values
|
let lists = lists_values
|
||||||
.iter()
|
.iter()
|
||||||
.map(|list| (list, &db).into())
|
.map(|list| {
|
||||||
.collect::<Vec<ListTemplate<'_>>>();
|
let mut context = Context::new();
|
||||||
let template = ListsTemplate {
|
let months = db.months(list.pk).unwrap();
|
||||||
title: "mailing list archive",
|
let posts = db.list_posts(list.pk, None).unwrap();
|
||||||
description: "",
|
context.insert("title", &list.name);
|
||||||
lists_len: lists.len(),
|
context.insert("list", &list);
|
||||||
lists,
|
context.insert("posts", &posts);
|
||||||
};
|
context.insert("months", &months);
|
||||||
let res = template.render().unwrap();
|
context.insert("body", &list.description.as_deref().unwrap_or_default());
|
||||||
Ok(warp::reply::html(res))
|
context.into_json()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
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()
|
let routes = warp::get()
|
||||||
.and(index_handler)
|
.and(index_handler)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{% include "header.html" %}
|
{% include "header.html" %}
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<p>{{lists_len}} lists</p>
|
<p>{{lists|length}} lists</p>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
{% for list in lists %}
|
{% for list in lists %}
|
||||||
{{ list }}
|
{{ list.title }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -0,0 +1,36 @@
|
||||||
|
{% include "header.html" %}
|
||||||
|
<div class="entry">
|
||||||
|
<h1>{{subject}}</h1>
|
||||||
|
<table class="headers">
|
||||||
|
<tr>
|
||||||
|
<th scope="row">List</th>
|
||||||
|
<td>{{ list.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">From</th>
|
||||||
|
<td>{{ from }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Date</th>
|
||||||
|
<td>{{ date }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">To</th>
|
||||||
|
<td>{{ to }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Subject</th>
|
||||||
|
<td>{{ subject }}</td>
|
||||||
|
</tr>
|
||||||
|
{% if in_reply_to %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">In-Reply-To</th>
|
||||||
|
<td>{{ in_reply_to }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
<div class="body">
|
||||||
|
<pre>{{body}}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% include "footer.html" %}
|
|
@ -1,10 +0,0 @@
|
||||||
{% include "header.html" %}
|
|
||||||
<div class="entry">
|
|
||||||
<h1>{{subject}}</h1>
|
|
||||||
<div class="body">
|
|
||||||
<pre>
|
|
||||||
{{body}}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% include "footer.html" %}
|
|
|
@ -48,7 +48,7 @@ struct Opt {
|
||||||
/// Set config file
|
/// Set config file
|
||||||
#[structopt(short, long, parse(from_os_str))]
|
#[structopt(short, long, parse(from_os_str))]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
config: Option<PathBuf>,
|
config: PathBuf,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
cmd: Command,
|
cmd: Command,
|
||||||
/// Silence all output
|
/// Silence all output
|
||||||
|
@ -65,10 +65,6 @@ struct Opt {
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
#[structopt(manpage = "docs/command.mdoc")]
|
#[structopt(manpage = "docs/command.mdoc")]
|
||||||
enum Command {
|
enum Command {
|
||||||
///Prints database filesystem location
|
|
||||||
DbLocation,
|
|
||||||
///Prints default configuration file filesystem location
|
|
||||||
ConfigLocation,
|
|
||||||
///Dumps database data to STDOUT
|
///Dumps database data to STDOUT
|
||||||
DumpDatabase,
|
DumpDatabase,
|
||||||
///Lists all registered mailing lists
|
///Lists all registered mailing lists
|
||||||
|
@ -238,22 +234,11 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
if opt.debug {
|
if opt.debug {
|
||||||
println!("DEBUG: {:?}", &opt);
|
println!("DEBUG: {:?}", &opt);
|
||||||
}
|
}
|
||||||
if let Some(config_path) = opt.config.as_ref() {
|
let config = Configuration::from_file(opt.config.as_path())?;
|
||||||
let config = Configuration::from_file(&config_path)?;
|
|
||||||
config.init_with()?;
|
|
||||||
} else {
|
|
||||||
Configuration::init()?;
|
|
||||||
}
|
|
||||||
use Command::*;
|
use Command::*;
|
||||||
|
let mut db = Database::open_or_create_db(&config)?;
|
||||||
match opt.cmd {
|
match opt.cmd {
|
||||||
DbLocation => {
|
|
||||||
println!("{}", Database::db_path()?.display());
|
|
||||||
}
|
|
||||||
ConfigLocation => {
|
|
||||||
println!("{}", Configuration::default_path()?.display());
|
|
||||||
}
|
|
||||||
DumpDatabase => {
|
DumpDatabase => {
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
let lists = db.list_lists()?;
|
let lists = db.list_lists()?;
|
||||||
let mut stdout = std::io::stdout();
|
let mut stdout = std::io::stdout();
|
||||||
serde_json::to_writer_pretty(&mut stdout, &lists)?;
|
serde_json::to_writer_pretty(&mut stdout, &lists)?;
|
||||||
|
@ -262,7 +247,6 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListLists => {
|
ListLists => {
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
let lists = db.list_lists()?;
|
let lists = db.list_lists()?;
|
||||||
if lists.is_empty() {
|
if lists.is_empty() {
|
||||||
println!("No lists found.");
|
println!("No lists found.");
|
||||||
|
@ -288,7 +272,6 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List { list_id, cmd } => {
|
List { list_id, cmd } => {
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
let list = match db.get_list_by_id(&list_id)? {
|
let list = match db.get_list_by_id(&list_id)? {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
|
@ -531,7 +514,6 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
description,
|
description,
|
||||||
archive_url,
|
archive_url,
|
||||||
} => {
|
} => {
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
let new = db.create_list(MailingList {
|
let new = db.create_list(MailingList {
|
||||||
pk: 0,
|
pk: 0,
|
||||||
name,
|
name,
|
||||||
|
@ -564,12 +546,15 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
if opt.debug {
|
if opt.debug {
|
||||||
std::dbg!(&env);
|
std::dbg!(&env);
|
||||||
}
|
}
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
db.post(&env, input.as_bytes(), dry_run)?;
|
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) => {
|
Err(err) => {
|
||||||
eprintln!("Could not parse message: {}", 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());
|
eprintln!("Message saved at {}", p.display());
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
}
|
}
|
||||||
|
@ -577,7 +562,6 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
}
|
}
|
||||||
ErrorQueue { cmd } => match cmd {
|
ErrorQueue { cmd } => match cmd {
|
||||||
ErrorQueueCommand::List => {
|
ErrorQueueCommand::List => {
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
let errors = db.error_queue()?;
|
let errors = db.error_queue()?;
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
println!("Error queue is empty.");
|
println!("Error queue is empty.");
|
||||||
|
@ -595,7 +579,6 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ErrorQueueCommand::Print { index, json } => {
|
ErrorQueueCommand::Print { index, json } => {
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
let mut errors = db.error_queue()?;
|
let mut errors = db.error_queue()?;
|
||||||
if !index.is_empty() {
|
if !index.is_empty() {
|
||||||
errors.retain(|el| index.contains(&el.pk()));
|
errors.retain(|el| index.contains(&el.pk()));
|
||||||
|
@ -613,7 +596,6 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ErrorQueueCommand::Delete { index, quiet } => {
|
ErrorQueueCommand::Delete { index, quiet } => {
|
||||||
let mut db = Database::open_or_create_db()?;
|
|
||||||
let mut errors = db.error_queue()?;
|
let mut errors = db.error_queue()?;
|
||||||
if !index.is_empty() {
|
if !index.is_empty() {
|
||||||
errors.retain(|el| index.contains(&el.pk()));
|
errors.retain(|el| index.contains(&el.pk()));
|
||||||
|
@ -639,7 +621,6 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
list_id,
|
list_id,
|
||||||
mut maildir_path,
|
mut maildir_path,
|
||||||
} => {
|
} => {
|
||||||
let db = Database::open_or_create_db()?;
|
|
||||||
let list = match db.get_list_by_id(&list_id)? {
|
let list = match db.get_list_by_id(&list_id)? {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -24,9 +24,6 @@ use std::io::{Read, Write};
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
thread_local!(pub static CONFIG: RefCell<Configuration> = RefCell::new(Configuration::new()));
|
|
||||||
thread_local!(static CONFIG_INIT: Cell<bool> = Cell::new(false));
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[serde(tag = "type", content = "value")]
|
#[serde(tag = "type", content = "value")]
|
||||||
pub enum SendMail {
|
pub enum SendMail {
|
||||||
|
@ -40,33 +37,24 @@ pub struct Configuration {
|
||||||
#[serde(default = "default_storage_fn")]
|
#[serde(default = "default_storage_fn")]
|
||||||
pub storage: String,
|
pub storage: String,
|
||||||
pub db_path: PathBuf,
|
pub db_path: PathBuf,
|
||||||
}
|
pub data_path: PathBuf,
|
||||||
|
|
||||||
impl Default for Configuration {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Configuration {
|
impl Configuration {
|
||||||
pub(crate) fn new() -> Self {
|
/*
|
||||||
|
pub fn new(db_path: impl Into<PathBuf>) -> Self {
|
||||||
|
let db_path = db_path.into();
|
||||||
Configuration {
|
Configuration {
|
||||||
send_mail: SendMail::ShellCommand("/usr/bin/false".to_string()),
|
send_mail: SendMail::ShellCommand("/usr/bin/false".to_string()),
|
||||||
storage: "sqlite3".into(),
|
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<P: AsRef<Path>>(path: P) -> Result<Self> {
|
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
@ -81,27 +69,12 @@ impl Configuration {
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() -> Result<()> {
|
pub fn data_directory(&self) -> &Path {
|
||||||
if CONFIG_INIT.with(|f| f.get()) {
|
self.data_path.as_path()
|
||||||
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() -> Result<PathBuf> {
|
pub fn db_path(&self) -> &Path {
|
||||||
Ok(xdg::BaseDirectories::with_prefix("mailpot")?
|
self.db_path.as_path()
|
||||||
.get_data_home()
|
|
||||||
.canonicalize()?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_path() -> Result<PathBuf> {
|
pub fn default_path() -> Result<PathBuf> {
|
||||||
|
@ -114,10 +87,13 @@ impl Configuration {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_message_to_path(msg: &str, mut path: PathBuf) -> Result<PathBuf> {
|
pub fn save_message_to_path(&self, msg: &str, mut path: PathBuf) -> Result<PathBuf> {
|
||||||
let now = Local::now().timestamp();
|
if path.is_dir() {
|
||||||
path.push(format!("{}-failed.eml", now));
|
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 mut file = std::fs::File::create(&path)?;
|
||||||
let metadata = file.metadata()?;
|
let metadata = file.metadata()?;
|
||||||
let mut permissions = metadata.permissions();
|
let mut permissions = metadata.permissions();
|
||||||
|
@ -129,23 +105,8 @@ impl Configuration {
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_message(msg: String) -> Result<PathBuf> {
|
pub fn save_message(&self, msg: String) -> Result<PathBuf> {
|
||||||
match Configuration::data_directory()
|
self.save_message_to_path(&msg, self.data_directory().to_path_buf())
|
||||||
.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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use super::Configuration;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ErrorKind::*;
|
use crate::ErrorKind::*;
|
||||||
use melib::Envelope;
|
use melib::Envelope;
|
||||||
|
@ -25,13 +26,14 @@ use rusqlite::Connection as DbConnection;
|
||||||
use rusqlite::OptionalExtension;
|
use rusqlite::OptionalExtension;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
const DB_NAME: &str = "current.db";
|
const DB_NAME: &str = "current.db";
|
||||||
|
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
pub connection: DbConnection,
|
pub connection: DbConnection,
|
||||||
|
conf: Configuration,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod error_queue;
|
mod error_queue;
|
||||||
|
@ -42,22 +44,18 @@ mod members;
|
||||||
pub use members::*;
|
pub use members::*;
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
pub fn db_path() -> Result<PathBuf> {
|
pub fn open_db(conf: &Configuration) -> Result<Self> {
|
||||||
Ok(crate::config::CONFIG.with(|c| c.borrow().db_path.clone()))
|
if !conf.db_path.exists() {
|
||||||
}
|
|
||||||
|
|
||||||
pub fn open_db(db_path: PathBuf) -> Result<Self> {
|
|
||||||
if !db_path.exists() {
|
|
||||||
return Err("Database doesn't exist".into());
|
return Err("Database doesn't exist".into());
|
||||||
}
|
}
|
||||||
Ok(Database {
|
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<Self> {
|
pub fn open_or_create_db(conf: &Configuration) -> Result<Self> {
|
||||||
crate::config::Configuration::init()?;
|
let mut db_path = conf.db_path.to_path_buf();
|
||||||
let mut db_path = Self::db_path()?;
|
|
||||||
if db_path.is_dir() {
|
if db_path.is_dir() {
|
||||||
db_path.push(DB_NAME);
|
db_path.push(DB_NAME);
|
||||||
}
|
}
|
||||||
|
@ -100,11 +98,14 @@ impl Database {
|
||||||
|
|
||||||
let conn = DbConnection::open(&db_path.to_str().unwrap())?;
|
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> {
|
pub fn load_archives(&mut self, conf: &Configuration) -> Result<&mut Self> {
|
||||||
let archives_path = crate::config::CONFIG.with(|c| c.borrow().db_path.clone());
|
let archives_path = conf.data_path.clone();
|
||||||
let mut stmt = self.connection.prepare("ATTACH ? AS ?;")?;
|
let mut stmt = self.connection.prepare("ATTACH ? AS ?;")?;
|
||||||
for archive in std::fs::read_dir(&archives_path)? {
|
for archive in std::fs::read_dir(&archives_path)? {
|
||||||
let archive = archive?;
|
let archive = archive?;
|
||||||
|
@ -232,7 +233,7 @@ impl Database {
|
||||||
pub fn remove_list_policy(&self, list_pk: i64, policy_pk: i64) -> Result<()> {
|
pub fn remove_list_policy(&self, list_pk: i64, policy_pk: i64) -> Result<()> {
|
||||||
let mut stmt = self
|
let mut stmt = self
|
||||||
.connection
|
.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,])?;
|
stmt.execute(rusqlite::params![&policy_pk, &list_pk,])?;
|
||||||
|
|
||||||
trace!("remove_list_policy {} {}.", list_pk, policy_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<DbVal<PostPolicy>> {
|
pub fn set_list_policy(&self, list_pk: i64, policy: PostPolicy) -> Result<DbVal<PostPolicy>> {
|
||||||
|
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 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(
|
let ret = stmt.query_row(
|
||||||
rusqlite::params![
|
rusqlite::params![
|
||||||
|
|
|
@ -119,11 +119,7 @@ impl Database {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut configuration = crate::config::Configuration::new();
|
trace!("Configuration is {:#?}", &self.conf);
|
||||||
crate::config::CONFIG.with(|f| {
|
|
||||||
configuration = f.borrow().clone();
|
|
||||||
});
|
|
||||||
trace!("Configuration is {:#?}", &configuration);
|
|
||||||
use crate::mail::{ListContext, Post, PostAction};
|
use crate::mail::{ListContext, Post, PostAction};
|
||||||
for mut list in lists {
|
for mut list in lists {
|
||||||
trace!("Examining list {}", list.list_id());
|
trace!("Examining list {}", list.list_id());
|
||||||
|
@ -161,7 +157,7 @@ impl Database {
|
||||||
trace!("recipients: {:?}", &recipients);
|
trace!("recipients: {:?}", &recipients);
|
||||||
|
|
||||||
if let crate::config::SendMail::Smtp(ref smtp_conf) =
|
if let crate::config::SendMail::Smtp(ref smtp_conf) =
|
||||||
&configuration.send_mail
|
&self.conf.send_mail
|
||||||
{
|
{
|
||||||
let smtp_conf = smtp_conf.clone();
|
let smtp_conf = smtp_conf.clone();
|
||||||
use melib::futures;
|
use melib::futures;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use mailpot::{models::*, Configuration, Database};
|
use mailpot::{models::*, Configuration, Database, SendMail};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -6,13 +6,17 @@ fn test_init_empty() {
|
||||||
let tmp_dir = TempDir::new().unwrap();
|
let tmp_dir = TempDir::new().unwrap();
|
||||||
|
|
||||||
let db_path = tmp_dir.path().join("mpot.db");
|
let db_path = tmp_dir.path().join("mpot.db");
|
||||||
let mut config = Configuration::default();
|
let config = Configuration {
|
||||||
config.db_path = db_path.clone();
|
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();
|
config.init_with().unwrap();
|
||||||
|
|
||||||
assert_eq!(Database::db_path().unwrap(), db_path);
|
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());
|
assert!(db.list_lists().unwrap().is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,13 +25,17 @@ fn test_list_creation() {
|
||||||
let tmp_dir = TempDir::new().unwrap();
|
let tmp_dir = TempDir::new().unwrap();
|
||||||
|
|
||||||
let db_path = tmp_dir.path().join("mpot.db");
|
let db_path = tmp_dir.path().join("mpot.db");
|
||||||
let mut config = Configuration::default();
|
let config = Configuration {
|
||||||
config.db_path = db_path.clone();
|
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();
|
config.init_with().unwrap();
|
||||||
|
|
||||||
assert_eq!(Database::db_path().unwrap(), db_path);
|
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());
|
assert!(db.list_lists().unwrap().is_empty());
|
||||||
let foo_chat = db
|
let foo_chat = db
|
||||||
.create_list(MailingList {
|
.create_list(MailingList {
|
||||||
|
|
|
@ -25,14 +25,17 @@ fn test_error_queue() {
|
||||||
let tmp_dir = TempDir::new().unwrap();
|
let tmp_dir = TempDir::new().unwrap();
|
||||||
|
|
||||||
let db_path = tmp_dir.path().join("mpot.db");
|
let db_path = tmp_dir.path().join("mpot.db");
|
||||||
let mut config = Configuration::default();
|
let config = Configuration {
|
||||||
config.send_mail = SendMail::Smtp(get_smtp_conf());
|
send_mail: SendMail::Smtp(get_smtp_conf()),
|
||||||
config.db_path = db_path.clone();
|
db_path: db_path.clone(),
|
||||||
|
storage: "sqlite3".to_string(),
|
||||||
|
data_path: tmp_dir.path().to_path_buf(),
|
||||||
|
};
|
||||||
config.init_with().unwrap();
|
config.init_with().unwrap();
|
||||||
|
|
||||||
assert_eq!(Database::db_path().unwrap(), db_path);
|
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());
|
assert!(db.list_lists().unwrap().is_empty());
|
||||||
let foo_chat = db
|
let foo_chat = db
|
||||||
.create_list(MailingList {
|
.create_list(MailingList {
|
||||||
|
|
|
@ -192,14 +192,17 @@ fn test_smtp() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let db_path = tmp_dir.path().join("mpot.db");
|
let db_path = tmp_dir.path().join("mpot.db");
|
||||||
let mut config = Configuration::default();
|
let config = Configuration {
|
||||||
config.send_mail = SendMail::Smtp(get_smtp_conf());
|
send_mail: SendMail::Smtp(get_smtp_conf()),
|
||||||
config.db_path = db_path.clone();
|
db_path: db_path.clone(),
|
||||||
config.init_with().unwrap();
|
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);
|
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());
|
assert!(db.list_lists().unwrap().is_empty());
|
||||||
let foo_chat = db
|
let foo_chat = db
|
||||||
.create_list(MailingList {
|
.create_list(MailingList {
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
|
|
||||||
.Bl -tag -width Ds -compact -offset indent
|
.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
|
.It Ic dump-database
|
||||||
Dumps database data to STDOUT.
|
Dumps database data to STDOUT.
|
||||||
.It Ic list-lists
|
.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.
|
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
|
.It Ic dump-database
|
||||||
Dumps database data to STDOUT.
|
Dumps database data to STDOUT.
|
||||||
.It Ic list-lists
|
.It Ic list-lists
|
||||||
|
|
|
@ -31,10 +31,6 @@ This command-line tool allows you to control databases of the mailing list manag
|
||||||
.Sh COMMANDS
|
.Sh COMMANDS
|
||||||
|
|
||||||
.Bl -tag -width Ds -compact -offset indent
|
.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
|
.It Ic dump-database
|
||||||
Dumps database data to STDOUT.
|
Dumps database data to STDOUT.
|
||||||
.It Ic list-lists
|
.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.
|
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
|
.It Ic dump-database
|
||||||
Dumps database data to STDOUT.
|
Dumps database data to STDOUT.
|
||||||
.It Ic list-lists
|
.It Ic list-lists
|
||||||
|
|
|
@ -37,9 +37,15 @@ fn json_body() -> impl Filter<Extract = (String,), Error = warp::Rejection> + Cl
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn 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
|
// GET /lists/:i64/policy
|
||||||
let policy = warp::path!("lists" / i64 / "policy").map(|list_pk| {
|
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)
|
db.get_list_policy(list_pk)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|l| warp::reply::json(&l.unwrap()))
|
.map(|l| warp::reply::json(&l.unwrap()))
|
||||||
|
@ -48,21 +54,21 @@ async fn main() {
|
||||||
|
|
||||||
//get("/lists")]
|
//get("/lists")]
|
||||||
let lists = warp::path!("lists").map(|| {
|
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();
|
let lists = db.list_lists().unwrap();
|
||||||
warp::reply::json(&lists)
|
warp::reply::json(&lists)
|
||||||
});
|
});
|
||||||
|
|
||||||
//get("/lists/<num>")]
|
//get("/lists/<num>")]
|
||||||
let lists_num = warp::path!("lists" / i64).map(|list_pk| {
|
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();
|
let list = db.get_list(list_pk).unwrap();
|
||||||
warp::reply::json(&list)
|
warp::reply::json(&list)
|
||||||
});
|
});
|
||||||
|
|
||||||
//get("/lists/<num>/members")]
|
//get("/lists/<num>/members")]
|
||||||
let lists_members = warp::path!("lists" / i64 / "members").map(|list_pk| {
|
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)
|
db.list_members(list_pk)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|l| warp::reply::json(&l))
|
.map(|l| warp::reply::json(&l))
|
||||||
|
@ -71,7 +77,7 @@ async fn main() {
|
||||||
|
|
||||||
//get("/lists/<num>/owners")]
|
//get("/lists/<num>/owners")]
|
||||||
let lists_owners = warp::path!("lists" / i64 / "owners").map(|list_pk| {
|
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)
|
db.get_list_owners(list_pk)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|l| warp::reply::json(&l))
|
.map(|l| warp::reply::json(&l))
|
||||||
|
|
Loading…
Reference in New Issue