summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-03-12 17:07:11 +0100
committerGitHub <noreply@github.com>2018-03-12 17:07:11 +0100
commit6ec509709dc1d8af444ffbb537a8e5f260e31977 (patch)
tree7b59b3bf70a7ae265b2ff1b3d4ba7c1ae4d0b48c
parentb374f21d7cecd786948092ae89f0f50113d1b422 (diff)
parentcbe30fa9c296b834a4ba371aa5827d9212f25c61 (diff)
downloadimag-6ec509709dc1d8af444ffbb537a8e5f260e31977.zip
imag-6ec509709dc1d8af444ffbb537a8e5f260e31977.tar.gz
Merge pull request #1336 from matthiasbeyer/imag-contact/find-show
imag-contact: Add "find" command
-rw-r--r--bin/domain/imag-contact/src/main.rs77
-rw-r--r--bin/domain/imag-contact/src/ui.rs33
2 files changed, 110 insertions, 0 deletions
diff --git a/bin/domain/imag-contact/src/main.rs b/bin/domain/imag-contact/src/main.rs
index ba50d1b..62196f0 100644
--- a/bin/domain/imag-contact/src/main.rs
+++ b/bin/domain/imag-contact/src/main.rs
@@ -98,6 +98,7 @@ fn main() {
"list" => list(&rt),
"import" => import(&rt),
"show" => show(&rt),
+ "find" => find(&rt),
"create" => create(&rt),
_ => {
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();
}
+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 {
let fmt = scmd
.value_of("format")
diff --git a/bin/domain/imag-contact/src/ui.rs b/bin/domain/imag-contact/src/ui.rs
index e1e3270..79149a9 100644
--- a/bin/domain/imag-contact/src/ui.rs
+++ b/bin/domain/imag-contact/src/ui.rs
@@ -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"))
)
+ .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")
.about("Create a contact file (.vcf) and track it in imag.")
.version("0.1")