parent
b401a52130
commit
2f939cb104
|
@ -25,7 +25,7 @@ checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
|||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -37,6 +37,50 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
@ -145,9 +189,9 @@ version = "0.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -494,7 +538,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"version_check",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -624,9 +668,9 @@ version = "0.3.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -666,7 +710,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -800,6 +844,12 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "humansize"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.18"
|
||||
|
@ -898,6 +948,7 @@ version = "0.24.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
@ -930,7 +981,7 @@ dependencies = [
|
|||
"base64",
|
||||
"either",
|
||||
"log",
|
||||
"nom",
|
||||
"nom 7.1.1",
|
||||
"ternop",
|
||||
]
|
||||
|
||||
|
@ -963,7 +1014,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"stderrlog",
|
||||
"tempfile",
|
||||
"toml",
|
||||
"toml 0.5.9",
|
||||
"xdg",
|
||||
]
|
||||
|
||||
|
@ -1009,7 +1060,7 @@ dependencies = [
|
|||
"libloading",
|
||||
"native-tls",
|
||||
"nix",
|
||||
"nom",
|
||||
"nom 7.1.1",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"smallvec",
|
||||
|
@ -1089,6 +1140,17 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mpot-archives"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"askama",
|
||||
"mailpot",
|
||||
"percent-encoding",
|
||||
"tokio",
|
||||
"warp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multipart"
|
||||
version = "0.18.0"
|
||||
|
@ -1137,6 +1199,16 @@ 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"
|
||||
|
@ -1289,9 +1361,9 @@ version = "1.0.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1338,10 +1410,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1350,9 +1422,18 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"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 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1361,7 +1442,7 @@ version = "1.0.37"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-xid 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1370,13 +1451,22 @@ 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.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2 1.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1583,9 +1673,9 @@ version = "1.0.137"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1747,9 +1837,20 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
|||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[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 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1758,9 +1859,9 @@ version = "1.0.92"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"unicode-xid 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1816,9 +1917,9 @@ version = "1.0.31"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1881,9 +1982,9 @@ version = "1.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1938,6 +2039,15 @@ 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"
|
||||
|
@ -1972,9 +2082,9 @@ version = "0.1.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2032,7 +2142,7 @@ version = "2.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2062,6 +2172,12 @@ 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 = "unicode-xid"
|
||||
version = "0.2.3"
|
||||
|
@ -2115,6 +2231,12 @@ 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"
|
||||
|
@ -2198,9 +2320,9 @@ dependencies = [
|
|||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -2210,7 +2332,7 @@ version = "0.2.80"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"quote 1.0.18",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
|
@ -2220,9 +2342,9 @@ version = "0.2.80"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.18",
|
||||
"syn 1.0.92",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
|
@ -3,4 +3,5 @@ members = [
|
|||
"core",
|
||||
"cli",
|
||||
"rest-http",
|
||||
"archive-http",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
[package]
|
||||
name = "mpot-archives"
|
||||
version = "0.1.0"
|
||||
authors = ["Manos Pitsidianakis <el13635@mail.ntua.gr>"]
|
||||
edition = "2018"
|
||||
license = "LICENSE"
|
||||
readme = "README.md"
|
||||
description = "mailing list manager"
|
||||
repository = "https://github.com/meli/mailpot"
|
||||
keywords = ["mail", "mailing-lists" ]
|
||||
categories = ["email"]
|
||||
default-run = "mpot-archives"
|
||||
|
||||
[[bin]]
|
||||
name = "mpot-archives"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
mailpot = { version = "0.1.0", path = "../core" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
askama = "0.8"
|
||||
warp = "0.3"
|
||||
percent-encoding = "2.1"
|
|
@ -0,0 +1,5 @@
|
|||
# mailpot REST http server
|
||||
|
||||
```shell
|
||||
cargo run --bin mpot-http
|
||||
```
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* This file is part of mailpot
|
||||
*
|
||||
* Copyright 2020 - Manos Pitsidianakis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern crate mailpot;
|
||||
|
||||
pub use mailpot::config::*;
|
||||
pub use mailpot::db::*;
|
||||
pub use mailpot::errors::*;
|
||||
pub use mailpot::models::*;
|
||||
pub use mailpot::*;
|
||||
|
||||
use askama::Template;
|
||||
use percent_encoding::percent_decode_str;
|
||||
use warp::reject;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "list.html")]
|
||||
struct ListTemplate<'a> {
|
||||
title: &'a str,
|
||||
list: &'a DbVal<MailingList>,
|
||||
posts: Vec<DbVal<Post>>,
|
||||
body: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "post.html")]
|
||||
struct PostTemplate<'a> {
|
||||
title: &'a str,
|
||||
list: &'a DbVal<MailingList>,
|
||||
post: DbVal<Post>,
|
||||
body: &'a str,
|
||||
from: &'a str,
|
||||
to: &'a str,
|
||||
subject: &'a str,
|
||||
in_reply_to: Option<String>,
|
||||
references: Vec<String>,
|
||||
}
|
||||
|
||||
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 list = db.get_list(list_pk).unwrap().unwrap();
|
||||
let posts = db.list_posts(list_pk, None).unwrap();
|
||||
let template = ListTemplate {
|
||||
title: &list.name,
|
||||
list: &list,
|
||||
posts,
|
||||
body: &list.description.clone().unwrap_or_default(),
|
||||
};
|
||||
let res = template.render().unwrap();
|
||||
Ok(warp::reply::html(res))
|
||||
});
|
||||
let post_handler =
|
||||
warp::path!("list" / i64 / String).map(|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 list = db.get_list(list_pk).unwrap().unwrap();
|
||||
let posts = db.list_posts(list_pk, None).unwrap();
|
||||
let post = posts
|
||||
.into_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,
|
||||
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
|
||||
.references()
|
||||
.into_iter()
|
||||
.map(|m| m.to_string())
|
||||
.collect::<Vec<String>>(),
|
||||
};
|
||||
let res = template.render().unwrap();
|
||||
Ok(warp::reply::html(res))
|
||||
});
|
||||
let routes = warp::get().and(list_handler).or(post_handler);
|
||||
|
||||
// Note that composing filters for many routes may increase compile times (because it uses a lot of generics).
|
||||
// If you wish to use dynamic dispatch instead and speed up compile times while
|
||||
// making it slightly slower at runtime, you can use Filter::boxed().
|
||||
|
||||
eprintln!("Running at 127.0.0.1:3030");
|
||||
warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
{% include "css.html" %}
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>{{ title }}</h1>
|
||||
</div>
|
||||
{% include "menu.html" %}
|
||||
<hr />
|
|
@ -0,0 +1,8 @@
|
|||
{% include "header.html" %}
|
||||
<div class="entry">
|
||||
<h1>{{title}}</h1>
|
||||
<div class="body">
|
||||
{{body}}
|
||||
</div>
|
||||
</div>
|
||||
{% include "footer.html" %}
|
|
@ -0,0 +1,14 @@
|
|||
{% include "header.html" %}
|
||||
<div class="entry">
|
||||
<h1>{{title}}</h1>
|
||||
<div class="body">
|
||||
{{body}}
|
||||
<h2>Posts</h2>
|
||||
<ul>
|
||||
{% for post in posts %}
|
||||
<li><a href="/list/{{post.list}}/{{ post.message_id }}">{{ post.address }} {{ post.datetime }} {{ post.message_id }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% include "footer.html" %}
|
|
@ -0,0 +1,10 @@
|
|||
{% include "header.html" %}
|
||||
<div class="entry">
|
||||
<h1>{{subject}}</h1>
|
||||
<div class="body">
|
||||
<pre>
|
||||
{{body}}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
{% include "footer.html" %}
|
|
@ -452,6 +452,9 @@ fn run_app(opt: Opt) -> Result<()> {
|
|||
std::io::stdin().read_to_string(&mut input)?;
|
||||
match Envelope::from_bytes(input.as_bytes(), None) {
|
||||
Ok(env) => {
|
||||
if opt.debug {
|
||||
std::dbg!(&env);
|
||||
}
|
||||
let db = Database::open_or_create_db()?;
|
||||
db.post(&env, input.as_bytes(), dry_run)?;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ chrono = { version = "^0.4", features = ["serde", ] }
|
|||
error-chain = "0.12.4"
|
||||
#melib = { version = "*", default-features = false, features = ["smtp", "unicode_algorithms"], path="../../meli/melib", branch = "master" }
|
||||
melib = { version = "*", default-features = false, features = ["smtp", "unicode_algorithms"], git="https://github.com/meli/meli", branch = "master" }
|
||||
rusqlite = {version = "^0.27" }
|
||||
rusqlite = {version = "^0.27", features = ["bundled"] }
|
||||
serde = { version = "^1", features = ["derive", ]}
|
||||
serde_json = "^1"
|
||||
toml = "^0.5"
|
||||
|
|
117
core/src/db.rs
117
core/src/db.rs
|
@ -142,6 +142,39 @@ impl Database {
|
|||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn list_posts(
|
||||
&self,
|
||||
list_pk: i64,
|
||||
date_range: Option<(String, String)>,
|
||||
) -> Result<Vec<DbVal<Post>>> {
|
||||
let mut stmt = self
|
||||
.connection
|
||||
.prepare("SELECT * FROM post WHERE list = ?;")?;
|
||||
let iter = stmt.query_map(rusqlite::params![&list_pk,], |row| {
|
||||
let pk = row.get("pk")?;
|
||||
Ok(DbVal(
|
||||
Post {
|
||||
pk,
|
||||
list: row.get("list")?,
|
||||
address: row.get("address")?,
|
||||
message_id: row.get("message_id")?,
|
||||
message: row.get("message")?,
|
||||
timestamp: row.get("timestamp")?,
|
||||
datetime: row.get("datetime")?,
|
||||
},
|
||||
pk,
|
||||
))
|
||||
})?;
|
||||
let mut ret = vec![];
|
||||
for post in iter {
|
||||
let post = post?;
|
||||
ret.push(post);
|
||||
}
|
||||
|
||||
trace!("list_posts {:?}.", &ret);
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn update_list(&self, _change_set: MailingListChangeset) -> Result<()> {
|
||||
/*
|
||||
diesel::update(mailing_lists::table)
|
||||
|
@ -416,13 +449,20 @@ impl Database {
|
|||
}
|
||||
|
||||
pub fn insert_post(&self, list_pk: i64, message: &[u8], env: &Envelope) -> Result<i64> {
|
||||
let address = env.from()[0].to_string();
|
||||
let address = env.from()[0].get_email();
|
||||
let message_id = env.message_id_display();
|
||||
let mut stmt = self.connection.prepare(
|
||||
"INSERT INTO post(list, address, message_id, message) VALUES(?, ?, ?, ?) RETURNING pk;",
|
||||
"INSERT INTO post(list, address, message_id, message, datetime, timestamp) VALUES(?, ?, ?, ?, ?, ?) RETURNING pk;",
|
||||
)?;
|
||||
let pk = stmt.query_row(
|
||||
rusqlite::params![&list_pk, &address, &message_id, &message],
|
||||
rusqlite::params![
|
||||
&list_pk,
|
||||
&address,
|
||||
&message_id,
|
||||
&message,
|
||||
&env.date,
|
||||
&env.timestamp
|
||||
],
|
||||
|row| {
|
||||
let pk: i64 = row.get("pk")?;
|
||||
Ok(pk)
|
||||
|
@ -530,51 +570,52 @@ impl Database {
|
|||
trace!("result {:#?}", result);
|
||||
|
||||
let Post { bytes, action, .. } = post;
|
||||
match configuration.send_mail {
|
||||
crate::config::SendMail::Smtp(ref smtp_conf) => {
|
||||
let smtp_conf = smtp_conf.clone();
|
||||
use melib::futures;
|
||||
use melib::smol;
|
||||
use melib::smtp::*;
|
||||
let mut conn = smol::future::block_on(smol::spawn(
|
||||
SmtpConnection::new_connection(smtp_conf.clone()),
|
||||
))?;
|
||||
match action {
|
||||
PostAction::Accept => {
|
||||
let _post_pk = self.insert_post(list_ctx.list.pk, raw, env)?;
|
||||
for job in list_ctx.scheduled_jobs.iter() {
|
||||
if let crate::mail::MailJob::Send { recipients } = job {
|
||||
if !recipients.is_empty() {
|
||||
trace!("recipients: {:?}", &recipients);
|
||||
match action {
|
||||
PostAction::Accept => {
|
||||
let _post_pk = self.insert_post(list_ctx.list.pk, raw, env)?;
|
||||
for job in list_ctx.scheduled_jobs.iter() {
|
||||
if let crate::mail::MailJob::Send { recipients } = job {
|
||||
if !recipients.is_empty() {
|
||||
trace!("recipients: {:?}", &recipients);
|
||||
|
||||
match &configuration.send_mail {
|
||||
crate::config::SendMail::Smtp(ref smtp_conf) => {
|
||||
let smtp_conf = smtp_conf.clone();
|
||||
use melib::futures;
|
||||
use melib::smol;
|
||||
use melib::smtp::*;
|
||||
let mut conn = smol::future::block_on(smol::spawn(
|
||||
SmtpConnection::new_connection(smtp_conf.clone()),
|
||||
))?;
|
||||
futures::executor::block_on(conn.mail_transaction(
|
||||
&String::from_utf8_lossy(&bytes),
|
||||
Some(recipients),
|
||||
))?;
|
||||
} else {
|
||||
trace!("list has no recipients");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
trace!("list has no recipients");
|
||||
}
|
||||
/* - FIXME Save digest metadata in database */
|
||||
}
|
||||
PostAction::Reject { reason } => {
|
||||
/* FIXME - Notify submitter */
|
||||
trace!("PostAction::Reject {{ reason: {} }}", reason);
|
||||
//futures::executor::block_on(conn.mail_transaction(&post.bytes, b)).unwrap();
|
||||
return Err(crate::ErrorKind::PostRejected(reason).into());
|
||||
}
|
||||
PostAction::Defer { reason } => {
|
||||
trace!("PostAction::Defer {{ reason: {} }}", reason);
|
||||
/* - FIXME Notify submitter
|
||||
* - FIXME Save in database */
|
||||
}
|
||||
PostAction::Hold => {
|
||||
trace!("PostAction::Hold");
|
||||
/* FIXME - Save in database */
|
||||
}
|
||||
}
|
||||
/* - FIXME Save digest metadata in database */
|
||||
}
|
||||
PostAction::Reject { reason } => {
|
||||
/* FIXME - Notify submitter */
|
||||
trace!("PostAction::Reject {{ reason: {} }}", reason);
|
||||
//futures::executor::block_on(conn.mail_transaction(&post.bytes, b)).unwrap();
|
||||
return Err(crate::ErrorKind::PostRejected(reason).into());
|
||||
}
|
||||
PostAction::Defer { reason } => {
|
||||
trace!("PostAction::Defer {{ reason: {} }}", reason);
|
||||
/* - FIXME Notify submitter
|
||||
* - FIXME Save in database */
|
||||
}
|
||||
PostAction::Hold => {
|
||||
trace!("PostAction::Hold");
|
||||
/* FIXME - Save in database */
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -240,3 +240,20 @@ pub struct NewListPost<'s> {
|
|||
pub message_id: &'s str,
|
||||
pub message: &'s [u8],
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
pub struct Post {
|
||||
pub pk: i64,
|
||||
pub list: i64,
|
||||
pub address: String,
|
||||
pub message_id: String,
|
||||
pub message: Vec<u8>,
|
||||
pub timestamp: u64,
|
||||
pub datetime: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Post {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(fmt, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ CREATE TABLE IF NOT EXISTS post (
|
|||
address TEXT NOT NULL,
|
||||
message_id TEXT NOT NULL,
|
||||
message BLOB NOT NULL,
|
||||
FOREIGN KEY (list, address) REFERENCES membership(list, address) ON DELETE CASCADE
|
||||
timestamp INTEGER NOT NULL DEFAULT (unixepoch()),
|
||||
datetime TEXT NOT NULL DEFAULT (datetime())
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS post_event (
|
||||
|
|
|
@ -62,7 +62,8 @@ CREATE TABLE IF NOT EXISTS post (
|
|||
address TEXT NOT NULL,
|
||||
message_id TEXT NOT NULL,
|
||||
message BLOB NOT NULL,
|
||||
FOREIGN KEY (list, address) REFERENCES membership(list, address) ON DELETE CASCADE
|
||||
timestamp INTEGER NOT NULL DEFAULT (unixepoch()),
|
||||
datetime TEXT NOT NULL DEFAULT (datetime())
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS post_event (
|
||||
|
|
Loading…
Reference in New Issue