From 30ad7d89b18d783c6f15afe1aaa19d56c6384b79 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 13 Feb 2018 23:49:55 +0100 Subject: [PATCH] Reimplement libimagmail for new libimagentryref interface --- lib/domain/libimagmail/src/error.rs | 4 ++ lib/domain/libimagmail/src/hasher.rs | 81 ---------------------------- lib/domain/libimagmail/src/lib.rs | 1 - lib/domain/libimagmail/src/mail.rs | 75 +++++++++++++++++++++----- 4 files changed, 65 insertions(+), 96 deletions(-) delete mode 100644 lib/domain/libimagmail/src/hasher.rs diff --git a/lib/domain/libimagmail/src/error.rs b/lib/domain/libimagmail/src/error.rs index 870954fa..519eb729 100644 --- a/lib/domain/libimagmail/src/error.rs +++ b/lib/domain/libimagmail/src/error.rs @@ -26,6 +26,10 @@ error_chain! { RefError(::libimagentryref::error::RefError, ::libimagentryref::error::RefErrorKind); } + foreign_links { + IoError(::std::io::Error); + } + errors { RefCreationError { diff --git a/lib/domain/libimagmail/src/hasher.rs b/lib/domain/libimagmail/src/hasher.rs deleted file mode 100644 index 6c68c82b..00000000 --- a/lib/domain/libimagmail/src/hasher.rs +++ /dev/null @@ -1,81 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer 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::io::Read; -use std::path::PathBuf; - -use email::MimeMessage; - -use libimagentryref::hasher::Hasher; -use libimagentryref::hasher::DefaultHasher; -use libimagentryref::error::RefErrorKind as REK; -use libimagentryref::error::ResultExt; -use libimagentryref::error::Result as RResult; - -pub struct MailHasher { - defaulthasher: DefaultHasher, -} - -impl MailHasher { - - pub fn new() -> MailHasher { - MailHasher { defaulthasher: DefaultHasher::new() } - } - -} - -impl Hasher for MailHasher { - - fn hash_name(&self) -> &'static str { - "default_mail_hasher" - } - - fn create_hash(&mut self, pb: &PathBuf, c: &mut R) -> RResult { - use filters::filter::Filter; - use email::Header; - - let mut s = String::new(); - c.read_to_string(&mut s)?; - - MimeMessage::parse(&s) - .chain_err(|| REK::RefHashingError) - .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 = vec![]; - for hdr in mail.headers.iter().filter(|item| filter.filter(item)) { - let s = hdr - .get_value() - .chain_err(|| REK::RefHashingError)?; - - v.push(s); - } - let s : String = v.join(""); - - self.defaulthasher.create_hash(pb, &mut s.as_bytes()) - }) - } - -} diff --git a/lib/domain/libimagmail/src/lib.rs b/lib/domain/libimagmail/src/lib.rs index da0460ed..1439f9b7 100644 --- a/lib/domain/libimagmail/src/lib.rs +++ b/lib/domain/libimagmail/src/lib.rs @@ -45,7 +45,6 @@ extern crate libimagstore; extern crate libimagentryref; pub mod error; -pub mod hasher; pub mod iter; pub mod mail; diff --git a/lib/domain/libimagmail/src/mail.rs b/lib/domain/libimagmail/src/mail.rs index 7536b11e..bf16c4a6 100644 --- a/lib/domain/libimagmail/src/mail.rs +++ b/lib/domain/libimagmail/src/mail.rs @@ -18,22 +18,75 @@ // use std::path::Path; -use std::path::PathBuf; use std::fs::File; use std::io::Read; +use std::fs::OpenOptions; +use std::result::Result as RResult; use libimagstore::store::Store; +use libimagstore::storeid::StoreId; use libimagstore::store::FileLockEntry; use libimagentryref::reference::Ref; -use libimagentryref::flags::RefFlags; use libimagentryref::refstore::RefStore; +use libimagentryref::refstore::UniqueRefPathGenerator; use email::MimeMessage; use email::results::ParsingResult as EmailParsingResult; -use hasher::MailHasher; use error::Result; -use error::{ResultExt, MailErrorKind as MEK}; +use error::{ResultExt, MailError as ME, MailErrorKind as MEK}; + +struct UniqueMailRefGenerator; +impl UniqueRefPathGenerator for UniqueMailRefGenerator { + type Error = ME; + + /// 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>(path: A) -> RResult { + 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) + .chain_err(|| MEK::RefCreationError) + .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 = vec![]; + for hdr in mail.headers.iter().filter(|item| filter.filter(item)) { + let s = hdr + .get_value() + .chain_err(|| MEK::RefCreationError)?; + + v.push(s); + } + let s : String = v.join(""); + Ok(s) + }) + } + + /// Postprocess the generated `StoreId` object + fn postprocess_storeid(sid: StoreId) -> RResult { + Ok(sid) + } +} struct Buffer(String); @@ -56,15 +109,10 @@ impl<'a> Mail<'a> { /// Imports a mail from the Path passed pub fn import_from_path>(store: &Store, p: P) -> Result { debug!("Importing Mail from path"); - let h = MailHasher::new(); - let f = RefFlags::default().with_content_hashing(true).with_permission_tracking(false); - let p = PathBuf::from(p.as_ref()); - - store.create_with_hasher(p, f, h) - .chain_err(|| MEK::RefCreationError) + store.retrieve_ref::(p) .and_then(|reference| { debug!("Build reference file: {:?}", reference); - reference.fs_file() + reference.get_path() .chain_err(|| MEK::RefHandlingError) .and_then(|path| File::open(path).chain_err(|| MEK::IOError)) .and_then(|mut file| { @@ -81,19 +129,18 @@ impl<'a> Mail<'a> { /// Opens a mail by the passed hash pub fn open>(store: &Store, hash: S) -> Result> { debug!("Opening Mail by Hash"); - store.get_by_hash(String::from(hash.as_ref())) + store.get_ref::(hash) .chain_err(|| MEK::FetchByHashError) .chain_err(|| MEK::FetchError) .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> { - fle.fs_file() + fle.get_path() .chain_err(|| MEK::RefHandlingError) .and_then(|path| File::open(path).chain_err(|| MEK::IOError)) .and_then(|mut file| {