diff --git a/src/module/bm/mod.rs b/src/module/bm/mod.rs index 07c6e907..ff56e591 100644 --- a/src/module/bm/mod.rs +++ b/src/module/bm/mod.rs @@ -6,6 +6,8 @@ use clap::ArgMatches; use runtime::Runtime; use module::Module; +use storage::file::hash::FileHash; +use storage::file::id::FileID; use storage::parser::FileHeaderParser; use storage::parser::Parser; use storage::json::parser::JsonHeaderParser; @@ -77,7 +79,107 @@ impl<'a> BM<'a> { } fn command_remove(&self, matches: &ArgMatches) -> bool { - unimplemented!() + use std::process::exit; + + let result = + if matches.is_present("id") { + debug!("Removing by ID (Hash)"); + let hash = FileHash::from(matches.value_of("id").unwrap()); + self.remove_by_hash(hash) + } else if matches.is_present("tags") { + debug!("Removing by tags"); + let tags = matches.value_of("tags") + .unwrap() + .split(",") + .map(String::from) + .collect::>(); + self.remove_by_tags(tags) + } else if matches.is_present("match") { + debug!("Removing by match"); + self.remove_by_match(String::from(matches.value_of("match").unwrap())) + } else { + error!("Unexpected error. Exiting"); + exit(1); + false + }; + + if result { + info!("Removing succeeded"); + } else { + info!("Removing failed"); + } + + return result; + } + + fn remove_by_hash(&self, hash: FileHash) -> bool { + use std::ops::Deref; + + debug!("Removing for hash = '{:?}'", hash); + let parser = Parser::new(JsonHeaderParser::new(None)); + + let file = self.rt.store().load_by_hash(self, &parser, hash); + debug!("file = {:?}", file); + file.map(|file| { + debug!("File loaded, can remove now: {:?}", file); + let f = file.deref().borrow(); + self.rt.store().remove(f.id().clone()) + }).unwrap_or(false) + } + + fn remove_by_tags(&self, tags: Vec) -> bool { + use std::fs::remove_file; + use std::ops::Deref; + use self::header::get_tags_from_header; + + let parser = Parser::new(JsonHeaderParser::new(None)); + self.rt + .store() + .load_for_module(self, &parser) + .iter() + .filter(|file| { + let f = file.deref().borrow(); + get_tags_from_header(f.header()).iter().any(|tag| { + tags.iter().any(|remtag| remtag == tag) + }) + }).map(|file| { + let f = file.deref().borrow(); + self.rt.store().remove(f.id().clone()) + }).all(|x| x) + } + + fn remove_by_match(&self, matcher: String) -> bool { + use self::header::get_url_from_header; + use std::fs::remove_file; + use std::ops::Deref; + use std::process::exit; + use regex::Regex; + + let re = Regex::new(&matcher[..]).unwrap_or_else(|e| { + error!("Cannot build regex out of '{}'", matcher); + error!("{}", e); + exit(1); + }); + + debug!("Compiled '{}' to regex: '{:?}'", matcher, re); + + let parser = Parser::new(JsonHeaderParser::new(None)); + self.rt + .store() + .load_for_module(self, &parser) + .iter() + .filter(|file| { + let f = file.deref().borrow(); + let url = get_url_from_header(f.header()); + debug!("url = {:?}", url); + url.map(|u| { + debug!("Matching '{}' ~= '{}'", re.as_str(), u); + re.is_match(&u[..]) + }).unwrap_or(false) + }).map(|file| { + let f = file.deref().borrow(); + self.rt.store().remove(f.id().clone()) + }).all(|x| x) } }