Enhance listing functionality with handlebars templating
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
8dbb2f1590
commit
14dc03f40f
5 changed files with 114 additions and 33 deletions
|
@ -25,6 +25,7 @@ log = "0.4"
|
|||
failure = "0.1"
|
||||
walkdir = "2.2.8"
|
||||
vobject = "0.7"
|
||||
handlebars = "2"
|
||||
|
||||
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
|
||||
libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" }
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
extern crate clap;
|
||||
extern crate toml_query;
|
||||
extern crate walkdir;
|
||||
extern crate handlebars;
|
||||
|
||||
#[macro_use] extern crate libimagrt;
|
||||
extern crate libimagcalendar;
|
||||
|
@ -164,6 +165,9 @@ fn list(rt: &Runtime) {
|
|||
use util::*;
|
||||
|
||||
let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe by clap
|
||||
let list_format = get_event_print_format("calendar.list_format", rt, &scmd)
|
||||
.map_err_trace_exit_unwrap();
|
||||
|
||||
let ref_config = rt.config()
|
||||
.ok_or_else(|| format_err!("No configuration, cannot continue!"))
|
||||
.map_err_trace_exit_unwrap()
|
||||
|
@ -173,8 +177,14 @@ fn list(rt: &Runtime) {
|
|||
.ok_or_else(|| format_err!("Configuration missing: {}", libimagentryref::reference::Config::LOCATION))
|
||||
.map_err_trace_exit_unwrap();
|
||||
|
||||
|
||||
debug!("List format: {:?}", list_format);
|
||||
debug!("Ref config : {:?}", ref_config);
|
||||
|
||||
let event_filter = |pefle: &ParsedEventFLE| true; // TODO: impl filtering
|
||||
|
||||
let mut listed_events = 0;
|
||||
|
||||
rt.store()
|
||||
.all_events()
|
||||
.map_err_trace_exit_unwrap()
|
||||
|
@ -186,37 +196,25 @@ fn list(rt: &Runtime) {
|
|||
.map(|ev| ParsedEventFLE::parse(ev, &ref_config))
|
||||
.trace_unwrap_exit()
|
||||
.filter(|e| event_filter(e))
|
||||
.for_each(|parsed_event| {
|
||||
for event in parsed_event.get_data().events().filter_map(RResult::ok) {
|
||||
macro_rules! get_data {
|
||||
($t:expr, $text:expr) => {
|
||||
($t).map(|obj| obj.into_raw()).unwrap_or_else(|| String::from($text))
|
||||
}
|
||||
}
|
||||
.for_each(|parsed_entry| {
|
||||
parsed_entry
|
||||
.get_data()
|
||||
.events()
|
||||
.filter_map(RResult::ok)
|
||||
.filter(event_filter)
|
||||
.for_each(|event| {
|
||||
listed_events = listed_events + 1;
|
||||
let data = build_data_object_for_handlebars(listed_events, &event);
|
||||
|
||||
let summary = get_data!(event.summary(), "<no summary>");
|
||||
let uid = get_data!(event.uid(), "<no uid>");
|
||||
let description = get_data!(event.description(), "<no description>");
|
||||
let dtstart = get_data!(event.dtstart(), "<no start date>");
|
||||
let dtend = get_data!(event.dtend(), "<no end date>");
|
||||
let location = get_data!(event.location(), "<no location>");
|
||||
let rendered = list_format
|
||||
.render("format", &data)
|
||||
.map_err(Error::from)
|
||||
.map_err_trace_exit_unwrap();
|
||||
|
||||
let summary_underline = std::iter::repeat('-').take(summary.len()).collect::<String>();
|
||||
writeln!(rt.stdout(), "{}", rendered).to_exit_code().unwrap_or_exit()
|
||||
});
|
||||
|
||||
writeln!(rt.stdout(),
|
||||
"{summary}\n{summary_underline}\n\n{uid}\n{description}\n{dtstart}\n{dtend}\n{location}\n\n",
|
||||
summary = summary,
|
||||
summary_underline = summary_underline,
|
||||
uid = uid,
|
||||
description = description,
|
||||
dtstart = dtstart,
|
||||
dtend = dtend,
|
||||
location = location)
|
||||
.to_exit_code()
|
||||
.unwrap_or_exit();
|
||||
}
|
||||
|
||||
rt.report_touched(parsed_event.get_entry().get_location()).unwrap_or_exit();
|
||||
rt.report_touched(parsed_entry.get_entry().get_location()).unwrap_or_exit();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -225,3 +223,4 @@ fn is_not_hidden(entry: &DirEntry) -> bool {
|
|||
!entry.file_name().to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,13 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
|
|||
.subcommand(SubCommand::with_name("list")
|
||||
.about("List calendar entries")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("format")
|
||||
.long("format")
|
||||
.short("F")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
.multiple(false)
|
||||
.help("Override the format used to list one event"))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,18 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
//
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use clap::ArgMatches;
|
||||
use vobject::icalendar::ICalendar;
|
||||
use vobject::icalendar::Event;
|
||||
use handlebars::Handlebars;
|
||||
use failure::Fallible as Result;
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
use toml_query::read::TomlValueReadTypeExt;
|
||||
|
||||
use libimagrt::runtime::Runtime;
|
||||
use libimagstore::store::FileLockEntry;
|
||||
use libimagentryref::reference::fassade::RefFassade;
|
||||
use libimagentryref::reference::Ref;
|
||||
|
@ -58,3 +66,54 @@ impl<'a> ParsedEventFLE<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_event_print_format(config_value_path: &'static str, rt: &Runtime, scmd: &ArgMatches)
|
||||
-> Result<Handlebars>
|
||||
{
|
||||
scmd.value_of("format")
|
||||
.map(String::from)
|
||||
.map(Ok)
|
||||
.unwrap_or_else(|| {
|
||||
rt.config()
|
||||
.ok_or_else(|| err_msg("No configuration file"))?
|
||||
.read_string(config_value_path)?
|
||||
.ok_or_else(|| err_msg("Configuration 'contact.list_format' does not exist"))
|
||||
})
|
||||
.and_then(|fmt| {
|
||||
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<'a>(i: usize, event: &Event<'a>)
|
||||
-> BTreeMap<&'static str, String>
|
||||
{
|
||||
macro_rules! process_opt {
|
||||
($t:expr, $text:expr) => {
|
||||
($t).map(|obj| obj.into_raw()).unwrap_or_else(|| String::from($text))
|
||||
}
|
||||
}
|
||||
|
||||
let mut data = BTreeMap::new();
|
||||
|
||||
data.insert("i" , format!("{}", i));
|
||||
data.insert("dtend" , process_opt!(event.dtend() , "<no dtend>"));
|
||||
data.insert("dtstart" , process_opt!(event.dtstart() , "<no dtstart>"));
|
||||
data.insert("dtstamp" , process_opt!(event.dtstamp() , "<no dtstamp>"));
|
||||
data.insert("uid" , process_opt!(event.uid() , "<no uid>"));
|
||||
data.insert("description" , process_opt!(event.description() , "<no description>"));
|
||||
data.insert("summary" , process_opt!(event.summary() , "<no summary>"));
|
||||
data.insert("url" , process_opt!(event.url() , "<no url>"));
|
||||
data.insert("location" , process_opt!(event.location() , "<no location>"));
|
||||
data.insert("class" , process_opt!(event.class() , "<no class>"));
|
||||
data.insert("categories" , process_opt!(event.categories() , "<no categories>"));
|
||||
data.insert("transp" , process_opt!(event.transp() , "<no transp>"));
|
||||
data.insert("rrule" , process_opt!(event.rrule() , "<no rrule>"));
|
||||
|
||||
data
|
||||
}
|
||||
|
|
15
imagrc.toml
15
imagrc.toml
|
@ -334,6 +334,21 @@ Email : {{EMAIL}}
|
|||
Address : {{ADR}}
|
||||
"""
|
||||
|
||||
[calendar]
|
||||
list_format = "{{lpad 5 i}} | {{abbrev 5 uid}} | {{summary}} | {{location}}"
|
||||
show_format = """
|
||||
{{i}} - {{uid}}
|
||||
|
||||
Summary : {{summary}}
|
||||
Start : {{dtstart}}
|
||||
End : {{dtend}}
|
||||
Url : {{url}}
|
||||
Location : {{location}}
|
||||
|
||||
{{description}}
|
||||
|
||||
"""
|
||||
|
||||
[log]
|
||||
logs = ["default"]
|
||||
default = "default"
|
||||
|
|
Loading…
Reference in a new issue