Add archive-http crate

Closes  #3
pull/1/head
Manos Pitsidianakis 2022-05-08 02:51:25 +03:00
parent b401a52130
commit 2f939cb104
18 changed files with 462 additions and 91 deletions

222
Cargo.lock generated
View File

@ -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",
]

View File

@ -3,4 +3,5 @@ members = [
"core",
"cli",
"rest-http",
"archive-http",
]

View File

@ -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"

View File

@ -0,0 +1,5 @@
# mailpot REST http server
```shell
cargo run --bin mpot-http
```

View File

@ -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;
}

View File

View File

@ -0,0 +1,3 @@
</body>
</html>

View File

@ -0,0 +1,11 @@
<html>
<head>
<title>{{ title }}</title>
{% include "css.html" %}
</head>
<body>
<div>
<h1>{{ title }}</h1>
</div>
{% include "menu.html" %}
<hr />

View File

@ -0,0 +1,8 @@
{% include "header.html" %}
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
{% include "footer.html" %}

View File

@ -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" %}

View File

View File

@ -0,0 +1,10 @@
{% include "header.html" %}
<div class="entry">
<h1>{{subject}}</h1>
<div class="body">
<pre>
{{body}}
</pre>
</div>
</div>
{% include "footer.html" %}

View File

@ -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)?;
}

View File

@ -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"

View File

@ -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 */
}
_ => {}
}
}

View File

@ -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)
}
}

View File

@ -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 (

View File

@ -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 (