Add "find" command
This patch adds a "find" command to imag-contact which can either list or show the found contacts (defaults to "list").
This commit is contained in:
parent
252046583a
commit
cbe30fa9c2
2 changed files with 110 additions and 0 deletions
|
@ -98,6 +98,7 @@ fn main() {
|
||||||
"list" => list(&rt),
|
"list" => list(&rt),
|
||||||
"import" => import(&rt),
|
"import" => import(&rt),
|
||||||
"show" => show(&rt),
|
"show" => show(&rt),
|
||||||
|
"find" => find(&rt),
|
||||||
"create" => create(&rt),
|
"create" => create(&rt),
|
||||||
_ => {
|
_ => {
|
||||||
error!("Unknown command"); // More error handling
|
error!("Unknown command"); // More error handling
|
||||||
|
@ -214,6 +215,82 @@ fn show(rt: &Runtime) {
|
||||||
let _ = writeln!(::std::io::stdout(), "{}", s).to_exit_code().unwrap_or_exit();
|
let _ = writeln!(::std::io::stdout(), "{}", s).to_exit_code().unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find(rt: &Runtime) {
|
||||||
|
let scmd = rt.cli().subcommand_matches("find").unwrap();
|
||||||
|
let grepstring = scmd
|
||||||
|
.values_of("string")
|
||||||
|
.unwrap() // safed by clap
|
||||||
|
.map(String::from)
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
|
// We don't know yet which we need, but we pay that price for simplicity of the codebase
|
||||||
|
let show_format = get_contact_print_format("contact.show_format", rt, &scmd);
|
||||||
|
let list_format = get_contact_print_format("contact.list_format", rt, &scmd);
|
||||||
|
|
||||||
|
rt.store()
|
||||||
|
.all_contacts()
|
||||||
|
.map_err_trace_exit_unwrap(1)
|
||||||
|
.into_get_iter(rt.store())
|
||||||
|
.map(|el| {
|
||||||
|
el.map_err_trace_exit_unwrap(1)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
error!("Could not get StoreId from Store::all_contacts(). This is a BUG!");
|
||||||
|
::std::process::exit(1)
|
||||||
|
})
|
||||||
|
.unwrap() // safed above
|
||||||
|
})
|
||||||
|
.filter_map(|cont| {
|
||||||
|
let comp = cont
|
||||||
|
.get_contact_data()
|
||||||
|
.map_err_trace_exit_unwrap(1)
|
||||||
|
.into_inner();
|
||||||
|
|
||||||
|
let card = Vcard::from_component(comp)
|
||||||
|
.map_err(|_| {
|
||||||
|
error!("Could not build Vcard from {:?}", cont.get_location());
|
||||||
|
::std::process::exit(1)
|
||||||
|
})
|
||||||
|
.unwrap(); // safed above
|
||||||
|
|
||||||
|
let str_contains_any = |s: &String, v: &Vec<String>| {
|
||||||
|
v.iter().any(|i| s.contains(i))
|
||||||
|
};
|
||||||
|
|
||||||
|
let take = card.adr().iter().any(|a| str_contains_any(a.raw(), &grepstring))
|
||||||
|
|| card.email().iter().any(|a| str_contains_any(a.raw(), &grepstring))
|
||||||
|
|| card.fullname().iter().any(|a| str_contains_any(a.raw(), &grepstring));
|
||||||
|
|
||||||
|
if take {
|
||||||
|
// optimization so we don't have to parse again in the next step
|
||||||
|
Some((cont, card))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(i, (fle, card))| {
|
||||||
|
let fmt = if scmd.is_present("find-show") {
|
||||||
|
&show_format
|
||||||
|
} else if scmd.is_present("find-list") {
|
||||||
|
&list_format
|
||||||
|
} else { // default: find-list
|
||||||
|
&list_format
|
||||||
|
};
|
||||||
|
|
||||||
|
let hash = fle.get_hash().map(String::from).map_err_trace_exit_unwrap(1);
|
||||||
|
let data = build_data_object_for_handlebars(i, hash, &card);
|
||||||
|
let s = fmt
|
||||||
|
.render("format", &data)
|
||||||
|
.err_from_str()
|
||||||
|
.map_err(CE::from)
|
||||||
|
.map_err_trace_exit_unwrap(1);
|
||||||
|
|
||||||
|
let _ = writeln!(rt.stdout(), "{}", s)
|
||||||
|
.to_exit_code()
|
||||||
|
.unwrap_or_exit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd: &ArgMatches) -> Handlebars {
|
fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd: &ArgMatches) -> Handlebars {
|
||||||
let fmt = scmd
|
let fmt = scmd
|
||||||
.value_of("format")
|
.value_of("format")
|
||||||
|
|
|
@ -71,6 +71,39 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
|
||||||
.help("Format to format the contact when printing it"))
|
.help("Format to format the contact when printing it"))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
.subcommand(SubCommand::with_name("find")
|
||||||
|
.about("Find contact by grepping for a string (no regex yet)")
|
||||||
|
.version("0.1")
|
||||||
|
.arg(Arg::with_name("string")
|
||||||
|
.index(1)
|
||||||
|
.takes_value(true)
|
||||||
|
.required(true)
|
||||||
|
.multiple(true)
|
||||||
|
.value_name("grepstring")
|
||||||
|
.help("Find the contact by grepping for this string"))
|
||||||
|
|
||||||
|
.arg(Arg::with_name("find-show")
|
||||||
|
.long("show")
|
||||||
|
.short("s")
|
||||||
|
.takes_value(false)
|
||||||
|
.required(false)
|
||||||
|
.multiple(false)
|
||||||
|
.help("Show the result")
|
||||||
|
.conflicts_with("find-list")
|
||||||
|
)
|
||||||
|
|
||||||
|
.arg(Arg::with_name("find-list")
|
||||||
|
.long("list")
|
||||||
|
.short("l")
|
||||||
|
.takes_value(false)
|
||||||
|
.required(false)
|
||||||
|
.multiple(false)
|
||||||
|
.help("List the result")
|
||||||
|
.conflicts_with("find-show")
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("create")
|
.subcommand(SubCommand::with_name("create")
|
||||||
.about("Create a contact file (.vcf) and track it in imag.")
|
.about("Create a contact file (.vcf) and track it in imag.")
|
||||||
.version("0.1")
|
.version("0.1")
|
||||||
|
|
Loading…
Reference in a new issue