From 03ae71497046f915125806ce4fb9dd687c3836ac Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 18:14:11 +0200 Subject: [PATCH] Add MailHasher --- libimagmail/src/error.rs | 1 + libimagmail/src/hasher.rs | 64 +++++++++++++++++++++++++++++++++++++++ libimagmail/src/lib.rs | 3 +- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 libimagmail/src/hasher.rs diff --git a/libimagmail/src/error.rs b/libimagmail/src/error.rs index cac14af1..59664b66 100644 --- a/libimagmail/src/error.rs +++ b/libimagmail/src/error.rs @@ -1,6 +1,7 @@ generate_error_module!( generate_error_types!(MailError, MailErrorKind, RefCreationError => "Error creating a reference to a file/directory", + MailParsingError => "Error while parsing mail", IOError => "IO Error" ); ); diff --git a/libimagmail/src/hasher.rs b/libimagmail/src/hasher.rs new file mode 100644 index 00000000..f0ced139 --- /dev/null +++ b/libimagmail/src/hasher.rs @@ -0,0 +1,64 @@ +use std::io::Read; +use std::path::PathBuf; + +use mailparse::{MailHeader, parse_mail}; + +use libimagref::hasher::Hasher; +use libimagref::hasher::DefaultHasher; +use libimagref::error::RefErrorKind as REK; +use libimagref::error::MapErrInto; +use libimagref::result::Result as RResult; +use libimagerror::into::IntoError; + +use error::MailErrorKind as MEK; + +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; + + let mut s = String::new(); + try!(c.read_to_string(&mut s).map_err_into(REK::UTF8Error).map_err_into(REK::IOError)); + + parse_mail(&s.as_bytes()) + .map_err(Box::new) + .map_err(|e| MEK::MailParsingError.into_error_with_cause(e)) + .map_err_into(REK::RefHashingError) + .and_then(|mail| { + let has_key = |hdr: &MailHeader, exp: &str| + hdr.get_key().map(|s| s == exp).unwrap_or(false); + + let subject_filter = |hdr: &MailHeader| has_key(hdr, "Subject"); + let from_filter = |hdr: &MailHeader| has_key(hdr, "From"); + let to_filter = |hdr: &MailHeader| has_key(hdr, "To"); + + let filter = subject_filter.or(from_filter).or(to_filter); + + let s : String = mail.headers + .iter() + .filter(|item| filter.filter(item)) + .filter_map(|hdr| hdr.get_value().ok()) // TODO: Do not hide error here + .collect::>() + .join(""); + + self.defaulthasher.create_hash(pb, &mut s.as_bytes()) + }) + } + +} diff --git a/libimagmail/src/lib.rs b/libimagmail/src/lib.rs index d21252eb..14105f3c 100644 --- a/libimagmail/src/lib.rs +++ b/libimagmail/src/lib.rs @@ -7,7 +7,8 @@ extern crate filters; #[macro_use] extern crate libimagerror; extern crate libimagstore; -pub mod mail; pub mod error; +pub mod hasher; +pub mod mail; pub mod result;