119 lines
3.9 KiB
Rust
119 lines
3.9 KiB
Rust
use clap::{App, Arg, ArgMatches, SubCommand};
|
|
|
|
use plume_models::{search::Searcher, Connection, CONFIG};
|
|
use std::fs::{read_dir, remove_file};
|
|
use std::io::ErrorKind;
|
|
use std::path::Path;
|
|
|
|
pub fn command<'a, 'b>() -> App<'a, 'b> {
|
|
SubCommand::with_name("search")
|
|
.about("Manage search index")
|
|
.subcommand(
|
|
SubCommand::with_name("init")
|
|
.arg(
|
|
Arg::with_name("path")
|
|
.short("p")
|
|
.long("path")
|
|
.takes_value(true)
|
|
.required(false)
|
|
.help("Path to Plume's working directory"),
|
|
)
|
|
.arg(
|
|
Arg::with_name("force")
|
|
.short("f")
|
|
.long("force")
|
|
.help("Ignore already using directory"),
|
|
)
|
|
.about("Initialize Plume's internal search engine"),
|
|
)
|
|
.subcommand(
|
|
SubCommand::with_name("refill")
|
|
.arg(
|
|
Arg::with_name("path")
|
|
.short("p")
|
|
.long("path")
|
|
.takes_value(true)
|
|
.required(false)
|
|
.help("Path to Plume's working directory"),
|
|
)
|
|
.about("Regenerate Plume's search index"),
|
|
)
|
|
.subcommand(
|
|
SubCommand::with_name("unlock")
|
|
.arg(
|
|
Arg::with_name("path")
|
|
.short("p")
|
|
.long("path")
|
|
.takes_value(true)
|
|
.required(false)
|
|
.help("Path to Plume's working directory"),
|
|
)
|
|
.about("Release lock on search directory"),
|
|
)
|
|
}
|
|
|
|
pub fn run<'a>(args: &ArgMatches<'a>, conn: &Connection) {
|
|
let conn = conn;
|
|
match args.subcommand() {
|
|
("init", Some(x)) => init(x, conn),
|
|
("refill", Some(x)) => refill(x, conn, None),
|
|
("unlock", Some(x)) => unlock(x),
|
|
("", None) => command().print_help().unwrap(),
|
|
_ => println!("Unknown subcommand"),
|
|
}
|
|
}
|
|
|
|
fn init<'a>(args: &ArgMatches<'a>, conn: &Connection) {
|
|
let path = args
|
|
.value_of("path")
|
|
.map(|p| Path::new(p).join("search_index"))
|
|
.unwrap_or_else(|| Path::new(&CONFIG.search_index).to_path_buf());
|
|
let force = args.is_present("force");
|
|
|
|
let can_do = match read_dir(path.clone()) {
|
|
// try to read the directory specified
|
|
Ok(mut contents) => contents.next().is_none(),
|
|
Err(e) => {
|
|
if e.kind() == ErrorKind::NotFound {
|
|
true
|
|
} else {
|
|
panic!("Error while initialising search index : {}", e);
|
|
}
|
|
}
|
|
};
|
|
if can_do || force {
|
|
let searcher = Searcher::create(&path, &CONFIG.search_tokenizers).unwrap();
|
|
refill(args, conn, Some(searcher));
|
|
} else {
|
|
eprintln!(
|
|
"Can't create new index, {} exist and is not empty",
|
|
path.to_str().unwrap()
|
|
);
|
|
}
|
|
}
|
|
|
|
fn refill<'a>(args: &ArgMatches<'a>, conn: &Connection, searcher: Option<Searcher>) {
|
|
let path = args.value_of("path");
|
|
let path = match path {
|
|
Some(path) => Path::new(path).join("search_index"),
|
|
None => Path::new(&CONFIG.search_index).to_path_buf(),
|
|
};
|
|
let searcher =
|
|
searcher.unwrap_or_else(|| Searcher::open(&path, &CONFIG.search_tokenizers).unwrap());
|
|
|
|
searcher.fill(conn).expect("Couldn't import post");
|
|
println!("Commiting result");
|
|
searcher.commit();
|
|
}
|
|
|
|
fn unlock(args: &ArgMatches) {
|
|
let path = match args.value_of("path") {
|
|
None => Path::new(&CONFIG.search_index),
|
|
Some(x) => Path::new(x),
|
|
};
|
|
let meta = Path::new(path).join(".tantivy-meta.lock");
|
|
remove_file(meta).unwrap();
|
|
let writer = Path::new(path).join(".tantivy-writer.lock");
|
|
remove_file(writer).unwrap();
|
|
}
|