diff --git a/Cargo.lock b/Cargo.lock index 6b99edb..8f181bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -124,7 +124,7 @@ dependencies = [ "slab", "socket2", "waker-fn", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -155,13 +155,13 @@ checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" dependencies = [ "async-io", "blocking", - "cfg-if", + "cfg-if 1.0.0", "event-listener", "futures-lite", "libc", "once_cell", "signal-hook", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -205,7 +205,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -313,6 +313,12 @@ version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -330,7 +336,7 @@ dependencies = [ "num-traits", "serde", "time", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -434,7 +440,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -543,6 +549,18 @@ dependencies = [ "instant", ] +[[package]] +name = "filetime" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "windows-sys", +] + [[package]] name = "fnv" version = "1.0.7" @@ -574,6 +592,41 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fsevent" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +dependencies = [ + "libc", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "futures" version = "0.3.21" @@ -694,7 +747,7 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] @@ -868,13 +921,42 @@ dependencies = [ "serde", ] +[[package]] +name = "inotify" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "instant" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", ] [[package]] @@ -892,12 +974,28 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.126" @@ -910,8 +1008,8 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ - "cfg-if", - "winapi", + "cfg-if 1.0.0", + "winapi 0.3.9", ] [[package]] @@ -941,7 +1039,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1019,7 +1117,6 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "melib" version = "0.7.2" -source = "git+https://github.com/meli/meli?branch=master#ce269c64e16db344f0e65461e56dbced2f1a4d64" dependencies = [ "async-stream", "base64", @@ -1034,6 +1131,7 @@ dependencies = [ "native-tls", "nix", "nom 7.1.1", + "notify", "serde", "serde_derive", "smallvec", @@ -1081,6 +1179,25 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + [[package]] name = "mio" version = "0.8.4" @@ -1093,6 +1210,30 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio 0.6.23", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + [[package]] name = "mpot-archives" version = "0.1.0" @@ -1140,6 +1281,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + [[package]] name = "nix" version = "0.24.1" @@ -1147,7 +1299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 1.0.0", "libc", "memoffset", ] @@ -1172,6 +1324,24 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "notify" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +dependencies = [ + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio 0.6.23", + "mio-extras", + "walkdir", + "winapi 0.3.9", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -1220,7 +1390,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 1.0.0", "foreign-types", "libc", "once_cell", @@ -1280,7 +1450,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", @@ -1337,11 +1507,11 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "log", "wepoll-ffi", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1472,7 +1642,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1487,7 +1657,7 @@ dependencies = [ "spin", "untrusted", "web-sys", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1538,6 +1708,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.20" @@ -1649,7 +1828,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest 0.9.0", "opaque-debug", @@ -1661,7 +1840,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest 0.10.3", ] @@ -1731,7 +1910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1810,12 +1989,12 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "libc", "redox_syscall", "remove_dir_all", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1879,7 +2058,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1907,7 +2086,7 @@ dependencies = [ "bytes", "libc", "memchr", - "mio", + "mio 0.8.4", "num_cpus", "once_cell", "parking_lot", @@ -1915,7 +2094,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2011,7 +2190,7 @@ version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "log", "pin-project-lite", "tracing-core", @@ -2179,6 +2358,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + [[package]] name = "want" version = "0.3.0" @@ -2237,7 +2427,7 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -2314,6 +2504,12 @@ dependencies = [ "cc", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -2324,6 +2520,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -2336,7 +2538,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2388,6 +2590,16 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "xdg" version = "2.4.1" diff --git a/archive-http/README.md b/archive-http/README.md index 63a4750..ab7dbac 100644 --- a/archive-http/README.md +++ b/archive-http/README.md @@ -1,5 +1,5 @@ # mailpot REST http server ```shell -cargo run --bin mpot-http +cargo run --bin mpot-archives ``` diff --git a/archive-http/src/main.rs b/archive-http/src/main.rs index 181856d..1b4cad8 100644 --- a/archive-http/src/main.rs +++ b/archive-http/src/main.rs @@ -28,15 +28,44 @@ pub use mailpot::*; use askama::Template; use percent_encoding::percent_decode_str; +#[derive(Template)] +#[template(path = "lists.html")] +struct ListsTemplate<'a> { + title: &'a str, + description: &'a str, + lists_len: usize, + lists: Vec>, +} + #[derive(Template)] #[template(path = "list.html")] struct ListTemplate<'a> { title: &'a str, - _list: &'a DbVal, + list: &'a DbVal, posts: Vec>, + months: Vec, body: &'a str, } +impl<'a> Into> for (&'a DbVal, &'a Database) { + fn into(self: (&'a DbVal, &'a Database)) -> ListTemplate<'a> { + let (list, db) = self; + let months = db.months(list.pk).unwrap(); + let posts = db.list_posts(list.pk, None).unwrap(); + ListTemplate { + title: &list.name, + list: &list, + posts, + months, + body: &list + .description + .as_ref() + .map(|s| s.as_str()) + .unwrap_or_default(), + } + } +} + #[derive(Template)] #[template(path = "post.html")] struct PostTemplate<'a> { @@ -57,10 +86,12 @@ 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 months = db.months(list_pk).unwrap(); let posts = db.list_posts(list_pk, None).unwrap(); let template = ListTemplate { title: &list.name, - _list: &list, + list: &list, + months, posts, body: &list.description.clone().unwrap_or_default(), }; @@ -99,12 +130,31 @@ async fn main() { let res = template.render().unwrap(); Ok(warp::reply::html(res)) }); - let routes = warp::get().and(list_handler).or(post_handler); + let index_handler = warp::path::end().map(|| { + let db = Database::open_or_create_db().unwrap(); + let lists_values = db.list_lists().unwrap(); + let lists = lists_values + .iter() + .map(|list| (list, &db).into()) + .collect::>>(); + let template = ListsTemplate { + title: "mailing list archive", + description: "", + lists_len: lists.len(), + lists: lists, + }; + let res = template.render().unwrap(); + Ok(warp::reply::html(res)) + }); + let routes = warp::get() + .and(index_handler) + .or(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"); + eprintln!("Running at http://127.0.0.1:3030"); warp::serve(routes).run(([127, 0, 0, 1], 3030)).await; } diff --git a/archive-http/templates/list.html b/archive-http/templates/list.html index 3a431ef..f56bf9e 100644 --- a/archive-http/templates/list.html +++ b/archive-http/templates/list.html @@ -3,6 +3,12 @@

{{title}}

{{body}} +

Months

+
    + {% for month in months %} +
  • {{ month }}
  • +{% endfor %} +

Posts

    {% for post in posts %} diff --git a/archive-http/templates/lists.html b/archive-http/templates/lists.html new file mode 100644 index 0000000..caca741 --- /dev/null +++ b/archive-http/templates/lists.html @@ -0,0 +1,10 @@ +{% include "header.html" %} +
    +

    {{lists_len}} lists

    +
    + {% for list in lists %} + {{ list }} + {% endfor %} +
    +
    +{% include "footer.html" %} diff --git a/cli/src/main.rs b/cli/src/main.rs index e636624..558d7a6 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -108,6 +108,13 @@ enum Command { #[structopt(subcommand)] cmd: ErrorQueueCommand, }, + /// Import a maildir folder into an existing list. + ImportMaildir { + ///Selects mailing list to operate on + list_id: String, + #[structopt(long, parse(from_os_str))] + maildir_path: PathBuf, + }, } #[derive(Debug, StructOpt)] @@ -628,6 +635,53 @@ fn run_app(opt: Opt) -> Result<()> { } } }, + ImportMaildir { + list_id, + mut maildir_path, + } => { + let db = Database::open_or_create_db()?; + let list = match db.get_list_by_id(&list_id)? { + Some(v) => v, + None => { + return Err(format!("No list with id {} was found", list_id).into()); + } + }; + use melib::backends::maildir::MaildirPathTrait; + use melib::{Envelope, EnvelopeHash}; + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; + use std::io::Read; + + if !maildir_path.is_absolute() { + maildir_path = std::env::current_dir() + .expect("could not detect current directory") + .join(&maildir_path); + } + + fn get_file_hash(file: &std::path::Path) -> EnvelopeHash { + let mut hasher = DefaultHasher::default(); + file.hash(&mut hasher); + hasher.finish() + } + let mut buf = Vec::with_capacity(4096); + let files = melib::backends::maildir::MaildirType::list_mail_in_maildir_fs( + maildir_path.clone(), + true, + )?; + let mut ctr = 0; + for file in files { + let hash = get_file_hash(&file); + let mut reader = std::io::BufReader::new(std::fs::File::open(&file)?); + buf.clear(); + reader.read_to_end(&mut buf)?; + if let Ok(mut env) = Envelope::from_bytes(buf.as_slice(), Some(file.flags())) { + env.set_hash(hash); + db.insert_post(list.pk, &buf, &env)?; + ctr += 1; + } + } + println!("Inserted {} posts to {}.", ctr, list_id); + } } Ok(()) diff --git a/core/src/db.rs b/core/src/db.rs index a860d64..ba50a89 100644 --- a/core/src/db.rs +++ b/core/src/db.rs @@ -56,6 +56,7 @@ impl Database { } pub fn open_or_create_db() -> Result { + crate::config::Configuration::init()?; let mut db_path = Self::db_path()?; db_path = db_path .canonicalize() diff --git a/core/src/db/posts.rs b/core/src/db/posts.rs index 09d16a6..6c7dd40 100644 --- a/core/src/db/posts.rs +++ b/core/src/db/posts.rs @@ -21,10 +21,24 @@ use super::*; impl Database { pub fn insert_post(&self, list_pk: i64, message: &[u8], env: &Envelope) -> Result { - let address = env.from()[0].get_email(); + let from_ = env.from(); + let address = if from_.is_empty() { + String::new() + } else { + from_[0].get_email() + }; + let mut datetime: std::borrow::Cow<'_, str> = env.date.as_str().into(); + if env.timestamp != 0 { + datetime = melib::datetime::timestamp_to_string( + env.timestamp, + Some(melib::datetime::RFC3339_FMT_WITH_TIME), + true, + ) + .into(); + } let message_id = env.message_id_display(); let mut stmt = self.connection.prepare( - "INSERT INTO post(list, address, message_id, message, datetime, timestamp) VALUES(?, ?, ?, ?, ?, ?) RETURNING pk;", + "INSERT OR REPLACE INTO post(list, address, message_id, message, datetime, timestamp) VALUES(?, ?, ?, ?, ?, ?) RETURNING pk;", )?; let pk = stmt.query_row( rusqlite::params![ @@ -32,7 +46,7 @@ impl Database { &address, &message_id, &message, - &env.date, + &datetime, &env.timestamp ], |row| { @@ -296,4 +310,21 @@ impl Database { } Ok(()) } + + pub fn months(&self, list_pk: i64) -> Result> { + let mut stmt = self.connection.prepare( + "SELECT DISTINCT strftime('%Y-%m', CAST(timestamp AS INTEGER), 'unixepoch') FROM post WHERE list = ?;", + )?; + let months_iter = stmt.query_map([list_pk], |row| { + let val: String = row.get(0)?; + Ok(val) + })?; + + let mut ret = vec![]; + for month in months_iter { + let month = month?; + ret.push(month); + } + Ok(ret) + } } diff --git a/docs/command.mdoc b/docs/command.mdoc index dc69c93..bbefdad 100644 --- a/docs/command.mdoc +++ b/docs/command.mdoc @@ -34,6 +34,11 @@ Create new list. Post message from STDIN to list. .It Ic error-queue Mail that has not been handled properly end up in the error queue. +.It Ic import-maildir +.Fl -maildir-path Ar maildir-path +. + +Import a maildir folder into an existing list. .It Ic db-location Prints database filesystem location. .It Ic config-location @@ -50,5 +55,7 @@ Create new list. Post message from STDIN to list. .It Ic error-queue Mail that has not been handled properly end up in the error queue. +.It Ic import-maildir +Import a maildir folder into an existing list. .El .Pp diff --git a/docs/mailpot.1 b/docs/mailpot.1 index f07db9f..e481ebb 100644 --- a/docs/mailpot.1 +++ b/docs/mailpot.1 @@ -65,6 +65,11 @@ Create new list. Post message from STDIN to list. .It Ic error-queue Mail that has not been handled properly end up in the error queue. +.It Ic import-maildir +.Fl -maildir-path Ar maildir-path +. + +Import a maildir folder into an existing list. .It Ic db-location Prints database filesystem location. .It Ic config-location @@ -81,6 +86,8 @@ Create new list. Post message from STDIN to list. .It Ic error-queue Mail that has not been handled properly end up in the error queue. +.It Ic import-maildir +Import a maildir folder into an existing list. .El .Pp