2015-12-30 10:34:24 +00:00
|
|
|
use std::fmt::{Debug, Formatter};
|
|
|
|
use std::fmt::Result as FMTResult;
|
2015-12-30 10:33:08 +00:00
|
|
|
use std::rc::Rc;
|
|
|
|
use std::cell::RefCell;
|
2016-01-02 17:49:55 +00:00
|
|
|
use std::ops::Deref;
|
2015-12-30 10:34:24 +00:00
|
|
|
|
2015-12-30 10:05:00 +00:00
|
|
|
use clap::ArgMatches;
|
2015-12-30 10:33:08 +00:00
|
|
|
use regex::Regex;
|
2015-12-30 10:05:00 +00:00
|
|
|
|
2015-12-30 10:34:24 +00:00
|
|
|
mod header;
|
|
|
|
|
|
|
|
use module::Module;
|
|
|
|
use runtime::Runtime;
|
2015-12-30 10:33:08 +00:00
|
|
|
use storage::file::File;
|
2015-12-30 10:05:00 +00:00
|
|
|
use storage::parser::Parser;
|
|
|
|
use storage::json::parser::JsonHeaderParser;
|
2015-12-30 10:33:08 +00:00
|
|
|
use module::helpers::cli::create_tag_filter;
|
|
|
|
use module::helpers::cli::create_hash_filter;
|
|
|
|
use module::helpers::cli::create_text_header_field_grep_filter;
|
|
|
|
use module::helpers::cli::create_content_grep_filter;
|
|
|
|
use module::helpers::cli::CliFileFilter;
|
2015-12-30 10:34:24 +00:00
|
|
|
|
|
|
|
pub struct Notes<'a> {
|
|
|
|
rt: &'a Runtime<'a>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Notes<'a> {
|
|
|
|
|
|
|
|
pub fn new(rt: &'a Runtime<'a>) -> Notes<'a> {
|
|
|
|
Notes {
|
|
|
|
rt: rt,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn command_add(&self, matches: &ArgMatches) -> bool {
|
2015-12-30 10:05:00 +00:00
|
|
|
use std::process::exit;
|
|
|
|
use self::header::build_header;
|
|
|
|
|
|
|
|
let parser = Parser::new(JsonHeaderParser::new(None));
|
|
|
|
let name = matches.value_of("name")
|
|
|
|
.map(String::from)
|
|
|
|
.unwrap_or(String::from(""));
|
|
|
|
let tags = matches.value_of("tags")
|
|
|
|
.and_then(|s| Some(s.split(",").map(String::from).collect()))
|
|
|
|
.unwrap_or(vec![]);
|
|
|
|
|
|
|
|
debug!("Building header with");
|
|
|
|
debug!(" name = '{:?}'", name);
|
|
|
|
debug!(" tags = '{:?}'", tags);
|
|
|
|
let header = build_header(name, tags);
|
|
|
|
|
|
|
|
let fileid = self.rt.store().new_file_with_header(self, header);
|
|
|
|
self.rt
|
|
|
|
.store()
|
|
|
|
.load(self, &parser, &fileid)
|
|
|
|
.and_then(|file| {
|
|
|
|
info!("Created file in memory: {}", fileid);
|
|
|
|
Some(self.rt.store().persist(&parser, file))
|
|
|
|
})
|
|
|
|
.unwrap_or(false)
|
2015-12-30 10:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn command_list(&self, matches: &ArgMatches) -> bool {
|
2015-12-30 10:33:08 +00:00
|
|
|
use ui::file::{FilePrinter, TablePrinter};
|
|
|
|
use self::header::get_name_from_header;
|
|
|
|
use self::header::get_tags_from_header;
|
|
|
|
use std::process::exit;
|
|
|
|
use module::helpers::cli::CliFileFilter;
|
|
|
|
|
|
|
|
let parser = Parser::new(JsonHeaderParser::new(None));
|
|
|
|
|
|
|
|
let filter = {
|
|
|
|
let hash_filter = create_hash_filter(matches, "id", true);
|
|
|
|
let head_filter = create_text_header_field_grep_filter(matches, "match", "NAME", true);
|
|
|
|
let text_filter = create_content_grep_filter(matches, "match", true);
|
|
|
|
let tags_filter = create_tag_filter(matches, "tags", true);
|
|
|
|
hash_filter.or(Box::new(head_filter)).and(Box::new(text_filter)).and(Box::new(tags_filter))
|
|
|
|
};
|
|
|
|
|
|
|
|
let printer = TablePrinter::new(self.rt.is_verbose(), self.rt.is_debugging());
|
|
|
|
|
|
|
|
printer.print_files_custom(
|
|
|
|
self.rt.store()
|
|
|
|
.load_for_module(self, &parser)
|
|
|
|
.into_iter()
|
|
|
|
.filter(|f| filter.filter_file(f)),
|
|
|
|
&|file| {
|
|
|
|
let fl = file.deref().borrow();
|
|
|
|
let hdr = fl.header();
|
|
|
|
let name = get_name_from_header(hdr);
|
|
|
|
let tags = get_tags_from_header(hdr);
|
|
|
|
|
|
|
|
debug!("Custom printer field: name = '{:?}'", name);
|
|
|
|
debug!("Custom printer field: tags = '{:?}'", tags);
|
|
|
|
|
|
|
|
vec![name, tags.join(", ")]
|
|
|
|
}
|
|
|
|
);
|
|
|
|
true
|
2015-12-30 10:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn command_remove(&self, matches: &ArgMatches) -> bool {
|
2016-01-02 17:49:55 +00:00
|
|
|
let parser = Parser::new(JsonHeaderParser::new(None));
|
|
|
|
|
|
|
|
let filter = {
|
|
|
|
let hash_filter = create_hash_filter(matches, "id", false);
|
|
|
|
let text_filter = create_text_header_field_grep_filter(matches, "match", "URL", false);
|
|
|
|
let tags_filter = create_tag_filter(matches, "tags", false);
|
|
|
|
hash_filter.or(Box::new(text_filter)).or(Box::new(tags_filter))
|
|
|
|
};
|
|
|
|
|
|
|
|
let result = self.rt
|
|
|
|
.store()
|
|
|
|
.load_for_module(self, &parser)
|
|
|
|
.iter()
|
|
|
|
.filter(|file| filter.filter_file(file))
|
|
|
|
.map(|file| {
|
|
|
|
debug!("File loaded, can remove now: {:?}", file);
|
|
|
|
let f = file.deref().borrow();
|
|
|
|
self.rt.store().remove(f.id().clone())
|
|
|
|
})
|
|
|
|
.fold((0, 0), |acc, succeeded| {
|
|
|
|
let (worked, failed) = acc;
|
|
|
|
if succeeded {
|
|
|
|
(worked + 1, failed)
|
|
|
|
} else {
|
|
|
|
(worked, failed + 1)
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let (worked, failed) = result;
|
|
|
|
|
|
|
|
info!("Removing succeeded for {} files", worked);
|
|
|
|
info!("Removing failed for {} files", failed);
|
|
|
|
|
|
|
|
return failed == 0;
|
2015-12-30 10:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn command_add_tags(&self, matches: &ArgMatches) -> bool {
|
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn command_rm_tags(&self, matches: &ArgMatches) -> bool {
|
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn command_set_tags(&self, matches: &ArgMatches) -> bool {
|
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Module<'a> for Notes<'a> {
|
|
|
|
|
|
|
|
fn exec(&self, matches: &ArgMatches) -> bool {
|
|
|
|
match matches.subcommand_name() {
|
|
|
|
Some("add") => {
|
|
|
|
self.command_add(matches.subcommand_matches("add").unwrap())
|
|
|
|
},
|
|
|
|
|
|
|
|
Some("list") => {
|
|
|
|
self.command_list(matches.subcommand_matches("list").unwrap())
|
|
|
|
},
|
|
|
|
|
|
|
|
Some("remove") => {
|
|
|
|
self.command_remove(matches.subcommand_matches("remove").unwrap())
|
|
|
|
},
|
|
|
|
|
|
|
|
Some("add_tags") => {
|
|
|
|
self.command_add_tags(matches.subcommand_matches("add_tags").unwrap())
|
|
|
|
},
|
|
|
|
|
|
|
|
Some("rm_tags") => {
|
|
|
|
self.command_rm_tags(matches.subcommand_matches("rm_tags").unwrap())
|
|
|
|
},
|
|
|
|
|
|
|
|
Some("set_tags") => {
|
|
|
|
self.command_set_tags(matches.subcommand_matches("set_tags").unwrap())
|
|
|
|
},
|
|
|
|
|
|
|
|
Some(_) | None => {
|
|
|
|
info!("No command given, doing nothing");
|
|
|
|
false
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn name(&self) -> &'static str{
|
|
|
|
"notes"
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Debug for Notes<'a> {
|
|
|
|
|
|
|
|
fn fmt(&self, fmt: &mut Formatter) -> FMTResult {
|
|
|
|
write!(fmt, "[Module][Notes]");
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|