108 lines
2.3 KiB
Rust
108 lines
2.3 KiB
Rust
extern crate actix_web;
|
|
extern crate serde;
|
|
#[macro_use]
|
|
extern crate serde_derive;
|
|
extern crate grep;
|
|
extern crate time;
|
|
|
|
use actix_web::{fs, http, server, App, HttpResponse, Query};
|
|
|
|
use std::error::Error;
|
|
|
|
use grep::regex::RegexMatcherBuilder;
|
|
use grep::searcher::sinks::Lossy;
|
|
use grep::searcher::{BinaryDetection, SearcherBuilder};
|
|
use std::fs::File;
|
|
|
|
fn main() {
|
|
server::new(|| {
|
|
App::new()
|
|
.route("/service/search", http::Method::GET, search)
|
|
.handler(
|
|
"/",
|
|
fs::StaticFiles::new("../ui/dist/")
|
|
.unwrap()
|
|
.index_file("index.html"),
|
|
)
|
|
.finish()
|
|
}).bind("127.0.0.1:8080")
|
|
.unwrap()
|
|
.run();
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct SearchQuery {
|
|
q: String,
|
|
page: Option<usize>,
|
|
size: Option<usize>,
|
|
}
|
|
|
|
fn search(query: Query<SearchQuery>) -> HttpResponse {
|
|
HttpResponse::Ok()
|
|
.header("Access-Control-Allow-Origin", "*")
|
|
.content_type("text/csv")
|
|
.body(ripgrep(query))
|
|
}
|
|
|
|
fn ripgrep(query: Query<SearchQuery>) -> String {
|
|
let page = query.page.unwrap_or(1);
|
|
let size = query.size.unwrap_or(10);
|
|
let offset = size * (page - 1);
|
|
let csv_file = File::open("../../torrents.csv");
|
|
|
|
println!("query = {} , page = {}, size = {}", query.q, page, size);
|
|
|
|
let results = search_file(csv_file.unwrap(), &query.q).unwrap();
|
|
|
|
let last: usize = if offset + size < results.len() {
|
|
offset + size
|
|
} else {
|
|
results.len()
|
|
};
|
|
|
|
results[offset..last].join("")
|
|
}
|
|
|
|
fn search_file(file: File, query: &str) -> Result<Vec<String>, Box<Error>> {
|
|
let pattern = query.replace(" ", ".*");
|
|
|
|
let matcher = RegexMatcherBuilder::new()
|
|
.case_insensitive(true)
|
|
.build(&pattern)
|
|
.unwrap();
|
|
|
|
let mut matches: Vec<String> = vec![];
|
|
|
|
let mut searcher = SearcherBuilder::new()
|
|
.binary_detection(BinaryDetection::quit(b'\x00'))
|
|
// .line_number(false)
|
|
.build();
|
|
|
|
searcher.search_file(
|
|
&matcher,
|
|
&file,
|
|
Lossy(|_lnum, line| {
|
|
matches.push(line.to_string());
|
|
Ok(true)
|
|
}),
|
|
)?;
|
|
|
|
Ok(matches)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use std::fs::File;
|
|
use time::PreciseTime;
|
|
|
|
#[test]
|
|
fn test() {
|
|
let start = PreciseTime::now();
|
|
let results =
|
|
super::search_file(File::open("../../torrents.csv").unwrap(), "sherlock").unwrap();
|
|
assert!(results.len() > 2);
|
|
let end = PreciseTime::now();
|
|
println!("Query took {} seconds.", start.to(end));
|
|
}
|
|
}
|