~matthiasbeyer/imag

0ad852f6c1f1386ebdc5d59076279abade1c539d — Matthias Beyer 1 year, 10 months ago d80ef3b
Add support for format in configuration for imag-mail-list

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
M bin/domain/imag-mail/Cargo.toml => bin/domain/imag-mail/Cargo.toml +2 -1
@@ 22,8 22,8 @@ maintenance                       = { status     = "actively-developed" }
[dependencies]
log = "0.4.6"
failure = "0.1.5"
indoc = "0.3.3"
resiter = "0.4"
handlebars = "2"

libimagrt       = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
libimagstore    = { version = "0.10.0", path = "../../../lib/core/libimagstore" }


@@ 31,6 31,7 @@ libimagerror    = { version = "0.10.0", path = "../../../lib/core/libimagerror" 
libimagmail     = { version = "0.10.0", path = "../../../lib/domain/libimagmail" }
libimagutil     = { version = "0.10.0", path = "../../../lib/etc/libimagutil" }
libimagentryref = { version = "0.10.0", path = "../../../lib/entry/libimagentryref" }
libimaginteraction = { version = "0.10.0", path = "../../../lib/etc/libimaginteraction" }

[dependencies.clap]
version = "2.33.0"

M bin/domain/imag-mail/src/lib.rs => bin/domain/imag-mail/src/lib.rs +15 -48
@@ 38,8 38,8 @@ extern crate clap;
#[macro_use] extern crate log;
#[macro_use] extern crate failure;
extern crate toml_query;
#[macro_use] extern crate indoc;
extern crate resiter;
extern crate handlebars;

extern crate libimagrt;
extern crate libimagmail;


@@ 47,6 47,7 @@ extern crate libimagerror;
extern crate libimagstore;
extern crate libimagutil;
extern crate libimagentryref;
extern crate libimaginteraction;

use std::io::Write;
use std::path::PathBuf;


@@ 59,19 60,16 @@ use clap::App;
use resiter::AndThen;
use resiter::IterInnerOkOrElse;

use libimagmail::mail::Mail;
use libimagmail::store::MailStore;
use libimagmail::util;
use libimagentryref::reference::{Ref, RefFassade};
use libimagentryref::util::get_ref_config;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagutil::info_result::*;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::iter::get::StoreIdGetIteratorExtension;

mod ui;
mod util;

/// Marker enum for implementing ImagApplication on
///


@@ 141,48 139,10 @@ fn import_mail(rt: &Runtime) -> Result<()> {
}

fn list(rt: &Runtime) -> Result<()> {
    let refconfig       = get_ref_config(rt, "imag-mail")?;
    let scmd            = rt.cli().subcommand_matches("list").unwrap(); // safe via clap

    // TODO: Implement lister type in libimagmail for this
    //
    // Optimization: Pass refconfig here instead of call get_ref_config() in lister function. This
    // way we do not call get_ref_config() multiple times.
    fn list_mail<'a>(rt: &Runtime,
                     refconfig: &::libimagentryref::reference::Config,
                     m: &FileLockEntry<'a>) -> Result<()> {

        let id = match m.get_message_id(&refconfig)? {
            Some(f) => f.into(),
            None => "<no id>".to_owned(),
        };

        let from = match m.get_from(&refconfig)? {
            Some(f) => f,
            None => "<no from>".to_owned(),
        };

        let to = match m.get_to(&refconfig)? {
            Some(f) => f,
            None => "<no to>".to_owned(),
        };

        let subject = match m.get_subject(&refconfig)? {
            Some(f) => f,
            None => "<no subject>".to_owned(),
        };

        writeln!(rt.stdout(),
                 "Mail: {id}\nFrom: {from}\nTo: {to}\n{subj}\n",
                 from = from,
                 id   = id,
                 subj = subject,
                 to   = to
        )?;

        rt.report_touched(m.get_location())?;
        Ok(())
    }
    let refconfig   = get_ref_config(rt, "imag-mail")?;
    let scmd        = rt.cli().subcommand_matches("list").unwrap(); // safe via clap
    let list_format = util::get_mail_print_format("mail.list_format", rt, &scmd)?;
    let mut i = 0;

    if rt.ids_from_stdin() {
        let iter = rt


@@ 200,7 160,14 @@ fn list(rt: &Runtime) -> Result<()> {
    .inspect(|id| debug!("Found: {:?}", id))
    .into_get_iter(rt.store())
    .map_inner_ok_or_else(|| err_msg("Did not find one entry"))
    .and_then_ok(|m| list_mail(&rt, &refconfig, &m))
    .and_then_ok(|m| {
        let data = util::build_data_object_for_handlebars(i, &m, &refconfig)?;
        let s = list_format.render("format", &data)?;
        writeln!(rt.stdout(), "{}", s)?;
        rt.report_touched(m.get_location())?;
        i += 1;
        Ok(())
    })
    .collect::<Result<Vec<_>>>()
    .map(|_| ())
}

M bin/domain/imag-mail/src/ui.rs => bin/domain/imag-mail/src/ui.rs +6 -0
@@ 58,6 58,12 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
                         .multiple(true)
                         .help("The ids of the mails to list information for"))

                    .arg(Arg::with_name("format")
                         .long("format")
                         .takes_value(true)
                         .required(false)
                         .multiple(false)
                         .help("The format to list the mails with"))
                    )

        .subcommand(SubCommand::with_name("mail-store")

A bin/domain/imag-mail/src/util.rs => bin/domain/imag-mail/src/util.rs +87 -0
@@ 0,0 1,87 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2020 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::collections::BTreeMap;

use clap::ArgMatches;
use failure::Error;
use failure::Fallible as Result;
use failure::err_msg;
use handlebars::Handlebars;
use toml_query::read::TomlValueReadTypeExt;

use libimagmail::mail::Mail;
use libimagrt::runtime::Runtime;
use libimagstore::store::FileLockEntry;
use libimagentryref::reference::Config as RefConfig;

pub fn get_mail_print_format(config_value_path: &'static str, rt: &Runtime, scmd: &ArgMatches) -> Result<Handlebars> {
    let fmt = match scmd.value_of("format").map(String::from) {
        Some(s) => Ok(s),
        None => {
            rt.config()
                .ok_or_else(|| err_msg("No configuration file"))?
                .read_string(config_value_path)
                .map_err(Error::from)?
                .ok_or_else(|| format_err!("Configuration '{}' does not exist", config_value_path))
        }
    }?;

    let mut hb = Handlebars::new();
    hb.register_template_string("format", fmt)?;

    hb.register_escape_fn(::handlebars::no_escape);
    ::libimaginteraction::format::register_all_color_helpers(&mut hb);
    ::libimaginteraction::format::register_all_format_helpers(&mut hb);
    Ok(hb)
}

pub fn build_data_object_for_handlebars(i: usize, m: &FileLockEntry, refconfig: &RefConfig) -> Result<BTreeMap<&'static str, String>> {
    let mut data = BTreeMap::new();

    data.insert("i", format!("{}", i));

    let id = match m.get_message_id(refconfig)? {
        Some(f) => f.into(),
        None => "<no id>".to_owned(),
    };

    let from = match m.get_from(refconfig)? {
        Some(f) => f,
        None => "<no from>".to_owned(),
    };

    let to = match m.get_to(refconfig)? {
        Some(f) => f,
        None => "<no to>".to_owned(),
    };

    let subject = match m.get_subject(refconfig)? {
        Some(f) => f,
        None => "<no subject>".to_owned(),
    };

    data.insert("id"      , id);
    data.insert("from"    , from);
    data.insert("to"      , to);
    data.insert("subject" , subject);

    Ok(data)
}


M imagrc.toml => imagrc.toml +1 -0
@@ 374,6 374,7 @@ calendars = "/home/user/calendars"
[mail]
# The name of the mail reference collection
ref_collection_name = "mail"
list_format = "{{i}} - {{id}} - {{from}} -> {{to}}\t: {{subject}}"

[todo]
show_format = """