Remove libimagmail
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
49df7f54a9
commit
74045e1800
7 changed files with 0 additions and 353 deletions
|
@ -35,7 +35,6 @@ members = [
|
||||||
"lib/domain/libimagdiary",
|
"lib/domain/libimagdiary",
|
||||||
"lib/domain/libimaghabit",
|
"lib/domain/libimaghabit",
|
||||||
"lib/domain/libimaglog",
|
"lib/domain/libimaglog",
|
||||||
"lib/domain/libimagmail",
|
|
||||||
"lib/domain/libimagnotes",
|
"lib/domain/libimagnotes",
|
||||||
"lib/domain/libimagtimetrack",
|
"lib/domain/libimagtimetrack",
|
||||||
"lib/domain/libimagtodo",
|
"lib/domain/libimagtodo",
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
## libimagmails
|
|
||||||
|
|
||||||
The mail library implements everything that is needed for beeing used to
|
|
||||||
implement a mail reader (MUA).
|
|
||||||
|
|
||||||
It therefor providea reading mailboxes, getting related content or mails, saving
|
|
||||||
attachements to external locations, crafting new mails and responses,...
|
|
||||||
|
|
||||||
It also offers, natively, ways to search for mails (which are represented as
|
|
||||||
imag entries) via tags, categories or even other metadata.
|
|
||||||
|
|
||||||
For more information on the domain of the `imag-mail` command, look at the
|
|
||||||
documentation of the @sec:modules:mails module.
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
[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" }
|
|
|
@ -1 +0,0 @@
|
||||||
../../../doc/src/05100-lib-mails.md
|
|
|
@ -1,55 +0,0 @@
|
||||||
//
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
|
|
|
@ -1,201 +0,0 @@
|
||||||
//
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue