summaryrefslogtreecommitdiffstats
path: root/lib/domain
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-02-17 11:49:27 +0100
committerMatthias Beyer <mail@beyermatthias.de>2019-02-20 16:22:52 +0100
commitf84cc8169fffee3904cd44c14baec0bac7a05478 (patch)
tree92a60c35a47e0bb175299d07a42cf90946e6f105 /lib/domain
parent27c0a30494b7b827b48e62bfc90ec96da35e8e00 (diff)
Revert "Remove libimagmail"
This reverts commit 74045e18007152d2fff63e83170e3406efcc73ac. Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'lib/domain')
-rw-r--r--lib/domain/libimagmail/Cargo.toml30
l---------lib/domain/libimagmail/README.md1
-rw-r--r--lib/domain/libimagmail/src/iter.rs55
-rw-r--r--lib/domain/libimagmail/src/lib.rs51
-rw-r--r--lib/domain/libimagmail/src/mail.rs201
5 files changed, 338 insertions, 0 deletions
diff --git a/lib/domain/libimagmail/Cargo.toml b/lib/domain/libimagmail/Cargo.toml
new file mode 100644
index 00000000..294040f3
--- /dev/null
+++ b/lib/domain/libimagmail/Cargo.toml
@@ -0,0 +1,30 @@
+[package]
+name = "libimagmail"
+version = "0.10.0"
+authors = ["Matthias Beyer <mail@beyermatthias.de>"]
+
+description = "Library for the imag core distribution"
+
+keywords = ["imag", "PIM", "personal", "information", "management"]
+readme = "../../../README.md"
+license = "LGPL-2.1"
+
+documentation = "https://imag-pim.org/doc/"
+repository = "https://github.com/matthiasbeyer/imag"
+homepage = "http://imag-pim.org"
+
+[badges]
+travis-ci = { repository = "matthiasbeyer/imag" }
+is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
+is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
+maintenance = { status = "actively-developed" }
+
+[dependencies]
+log = "0.4.0"
+email = "0.0.20"
+filters = "0.3"
+failure = "0.1"
+
+libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" }
+libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
+libimagentryref = { version = "0.10.0", path = "../../../lib/entry/libimagentryref" }
diff --git a/lib/domain/libimagmail/README.md b/lib/domain/libimagmail/README.md
new file mode 120000
index 00000000..9aeb65d2
--- /dev/null
+++ b/lib/domain/libimagmail/README.md
@@ -0,0 +1 @@
+../../../doc/src/05100-lib-mails.md \ No newline at end of file
diff --git a/lib/domain/libimagmail/src/iter.rs b/lib/domain/libimagmail/src/iter.rs
new file mode 100644
index 00000000..e4d375cd
--- /dev/null
+++ b/lib/domain/libimagmail/src/iter.rs
@@ -0,0 +1,55 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+//! Module for the MailIter
+//!
+//! MailIter is a iterator which takes an Iterator that yields `Ref` and yields itself
+//! `Result<Mail>`, where `Err(_)` is returned if the Ref is not a Mail or parsing of the
+//! referenced mail file failed.
+//!
+
+use mail::Mail;
+use failure::Fallible as Result;
+
+use libimagstore::store::FileLockEntry;
+
+use std::marker::PhantomData;
+
+pub struct MailIter<'a, I: Iterator<Item = FileLockEntry<'a>>> {
+ _marker: PhantomData<I>,
+ i: I,
+}
+
+impl<'a, I: Iterator<Item = FileLockEntry<'a>>> MailIter<'a, I> {
+
+ pub fn new(i: I) -> MailIter<'a, I> {
+ MailIter { _marker: PhantomData, i: i }
+ }
+
+}
+
+impl<'a, I: Iterator<Item = FileLockEntry<'a>>> Iterator for MailIter<'a, I> {
+ type Item = Result<Mail<'a>>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.i.next().map(Mail::from_fle)
+ }
+
+}
+
diff --git a/lib/domain/libimagmail/src/lib.rs b/lib/domain/libimagmail/src/lib.rs
new file mode 100644
index 00000000..3ba7397f
--- /dev/null
+++ b/lib/domain/libimagmail/src/lib.rs
@@ -0,0 +1,51 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#![forbid(unsafe_code)]
+
+#![recursion_limit="256"]
+
+#![deny(
+ dead_code,
+ non_camel_case_types,
+ non_snake_case,
+ path_statements,
+ trivial_numeric_casts,
+ unstable_features,
+ unused_allocation,
+ unused_import_braces,
+ unused_imports,
+ unused_must_use,
+ unused_mut,
+ unused_qualifications,
+ while_true,
+)]
+
+#[macro_use] extern crate log;
+extern crate email;
+extern crate filters;
+extern crate failure;
+
+extern crate libimagerror;
+extern crate libimagstore;
+extern crate libimagentryref;
+
+pub mod iter;
+pub mod mail;
+
diff --git a/lib/domain/libimagmail/src/mail.rs b/lib/domain/libimagmail/src/mail.rs
new file mode 100644
index 00000000..ab59a694
--- /dev/null
+++ b/lib/domain/libimagmail/src/mail.rs
@@ -0,0 +1,201 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+use std::path::Path;
+use std::fs::File;
+use std::io::Read;
+use std::fs::OpenOptions;
+
+use libimagstore::store::Store;
+use libimagstore::storeid::StoreId;
+use libimagstore::store::FileLockEntry;
+use libimagentryref::reference::Ref;
+use libimagentryref::refstore::RefStore;
+use libimagentryref::refstore::UniqueRefPathGenerator;
+use libimagerror::errors::ErrorMsg as EM;
+
+use email::MimeMessage;
+use email::results::ParsingResult as EmailParsingResult;
+
+use failure::Fallible as Result;
+use failure::ResultExt;
+use failure::Error;
+use failure::err_msg;
+
+struct UniqueMailRefGenerator;
+impl UniqueRefPathGenerator for UniqueMailRefGenerator {
+ /// The collection the `StoreId` should be created for
+ fn collection() -> &'static str {
+ "mail"
+ }
+
+ /// A function which should generate a unique string for a Path
+ fn unique_hash<A: AsRef<Path>>(path: A) -> Result<String> {
+ use filters::filter::Filter;
+ use email::Header;
+
+ let mut s = String::new();
+ let _ = OpenOptions::new()
+ .read(true)
+ .write(false)
+ .create(false)
+ .open(path)?
+ .read_to_string(&mut s)?;
+
+ MimeMessage::parse(&s)
+ .context(err_msg("Error creating ref"))
+ .map_err(Error::from)
+ .and_then(|mail| {
+ let has_key = |hdr: &Header, exp: &str| hdr.name == exp;
+
+ let subject_filter = |hdr: &Header| has_key(hdr, "Subject");
+ let from_filter = |hdr: &Header| has_key(hdr, "From");
+ let to_filter = |hdr: &Header| has_key(hdr, "To");
+
+ let filter = subject_filter.or(from_filter).or(to_filter);
+
+ let mut v : Vec<String> = vec![];
+ for hdr in mail.headers.iter().filter(|item| filter.filter(item)) {
+ let s = hdr
+ .get_value()
+ .context(err_msg("Ref creation error"))?;
+
+ v.push(s);
+ }
+ let s : String = v.join("");
+ Ok(s)
+ })
+ }
+
+ /// Postprocess the generated `StoreId` object
+ fn postprocess_storeid(sid: StoreId) -> Result<StoreId> {
+ Ok(sid)
+ }
+}
+
+struct Buffer(String);
+
+impl Buffer {
+ pub fn parsed(&self) -> EmailParsingResult<MimeMessage> {
+ MimeMessage::parse(&self.0)
+ }
+}
+
+impl From<String> for Buffer {
+ fn from(data: String) -> Buffer {
+ Buffer(data)
+ }
+}
+
+pub struct Mail<'a>(FileLockEntry<'a>, Buffer);
+
+impl<'a> Mail<'a> {
+
+ /// Imports a mail from the Path passed
+ pub fn import_from_path<P: AsRef<Path>>(store: &Store, p: P) -> Result<Mail> {
+ debug!("Importing Mail from path");
+ store.retrieve_ref::<UniqueMailRefGenerator, P>(p)
+ .and_then(|reference| {
+ debug!("Build reference file: {:?}", reference);
+ reference.get_path()
+ .context(err_msg("Ref handling error"))
+ .map_err(Error::from)
+ .and_then(|path| File::open(path).context(EM::IO).map_err(Error::from))
+ .and_then(|mut file| {
+ let mut s = String::new();
+ file.read_to_string(&mut s)
+ .map(|_| s)
+ .context(EM::IO)
+ .map_err(Error::from)
+ })
+ .map(Buffer::from)
+ .map(|buffer| Mail(reference, buffer))
+ })
+ }
+
+ /// Opens a mail by the passed hash
+ pub fn open<S: AsRef<str>>(store: &Store, hash: S) -> Result<Option<Mail>> {
+ debug!("Opening Mail by Hash");
+ store.get_ref::<UniqueMailRefGenerator, S>(hash)
+ .context(err_msg("Fetch by hash error"))
+ .context(err_msg("Fetch error"))
+ .map_err(Error::from)
+ .and_then(|o| match o {
+ Some(r) => Mail::from_fle(r).map(Some),
+ None => Ok(None),
+ })
+ }
+
+ /// Implement me as TryFrom as soon as it is stable
+ pub fn from_fle(fle: FileLockEntry<'a>) -> Result<Mail<'a>> {
+ fle.get_path()
+ .context(err_msg("Ref handling error"))
+ .map_err(Error::from)
+ .and_then(|path| File::open(path).context(EM::IO).map_err(Error::from))
+ .and_then(|mut file| {
+ let mut s = String::new();
+ file.read_to_string(&mut s)
+ .map(|_| s)
+ .context(EM::IO)
+ .map_err(Error::from)
+ })
+ .map(Buffer::from)
+ .map(|buffer| Mail(fle, buffer))
+ }
+
+ pub fn get_field(&self, field: &str) -> Result<Option<String>> {
+ debug!("Getting field in mail: {:?}", field);
+ self.1
+ .parsed()
+ .context(err_msg("Mail parsing error"))
+ .map_err(Error::from)
+ .map(|parsed| {
+ parsed.headers
+ .iter()
+ .filter(|hdr| hdr.name == field)
+ .nth(0)
+ .and_then(|field| field.get_value().ok())
+ })
+ }
+
+ pub fn get_from(&self) -> Result<Option<String>> {
+ self.get_field("From")
+ }
+
+ pub fn get_to(&self) -> Result<Option<String>> {
+ self.get_field("To")
+ }
+
+ pub fn get_subject(&self) -> Result<Option<String>> {
+ self.get_field("Subject")
+ }
+
+ pub fn get_message_id(&self) -> Result<Option<String>> {
+ self.get_field("Message-ID")
+ }
+
+ pub fn get_in_reply_to(&self) -> Result<Option<String>> {
+ self.get_field("In-Reply-To")
+ }
+
+ pub fn fle(&self) -> &FileLockEntry<'a> {
+ &self.0
+ }
+
+}