diff options
author | Josias <me@josias.dev> | 2020-11-22 17:11:05 +0100 |
---|---|---|
committer | Josias <me@josias.dev> | 2020-11-22 17:11:05 +0100 |
commit | 842596d4918f62d6bb017b797a086d688a75eccd (patch) | |
tree | c975d464f41b52812543e91f0e90192bab79c55f |
Add basic server
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.toml | 13 | ||||
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | search_engines.csv | 9 | ||||
-rw-r--r-- | src/main.rs | 85 |
5 files changed, 118 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d04df4b --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "oistos" +version = "0.1.0" +authors = ["Josias <me@josias.dev>"] +edition = "2018" +license = "MIT" + +[dependencies] +actix-web = "3.2.0" +serde = { version = "1.0", features = ["derive"] } +csv = "1.1" +anyhow = "1.0.34" +rand = "0.7.3" diff --git a/README.md b/README.md new file mode 100644 index 0000000..68c36ab --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# oistos + +A search engine redirector. + +Redirects all calls to `localhost:5005/search/query` to a random search engine (listed in `search_engines.csv`). Also supports shortcodes to choose a specific engine (e.g. `!ddg test`). + +This server is particularly useful for interacting with your browser's search bar. + +TODO: +- [ ] Use priority to determine chance of each search engine diff --git a/search_engines.csv b/search_engines.csv new file mode 100644 index 0000000..d915bac --- /dev/null +++ b/search_engines.csv @@ -0,0 +1,9 @@ +NAME, SHORT, URL, GENERAL, PRIORITY +DuckDuckGo,!ddg,https://duckduckgo.com/?q=%s,true,1 +Qwant,!wq,https://www.qwant.com/?q=%s,true,1 +StartPage,!sp,https://www.startpage.com/sp/search?query=%s,true,1 +Infinity Search,!infinity, https://infinitysearch.co/results?q=%s,true,2 +Searx,!sx,https://searx.neocities.org/#?q=%s,true,3 +metaGer,!mg,https://metager.org/meta/meta.ger3?eingabe=%s,true,2 +mojeek,!mk,https://www.mojeek.com/search?q=%s,true,2 +Ecosia,!ec,https://www.ecosia.org/search?q=%s,true,2 diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..3b8e2d0 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,85 @@ +use actix_web::{get, web, App, HttpResponse, HttpServer, Responder}; +use anyhow::Result; +use rand::seq::SliceRandom; +use serde::Deserialize; + +#[derive(Debug, Clone)] +struct Config { + search_engines: Vec<Engine>, +} + +impl Config { + fn load_from<R: std::io::Read>(reader: R) -> Result<Self> { + let mut rdr = csv::ReaderBuilder::new() + .trim(csv::Trim::All) + .from_reader(reader); + + let mut conf = Self { + search_engines: vec![], + }; + for result in rdr.deserialize() { + let record: Engine = result?; + conf.search_engines.push(record); + } + + Ok(conf) + } +} + +#[derive(Deserialize, Debug, Clone)] +struct Engine { + #[serde(rename = "NAME")] + name: String, + #[serde(rename = "SHORT")] + short: String, + #[serde(rename = "URL")] + url: String, + #[serde(rename = "GENERAL")] + general: bool, + #[serde(rename = "PRIORITY")] + priority: usize, +} + +#[get("/search/{query}")] +async fn search(config: web::Data<Config>, web::Path(query): web::Path<String>) -> impl Responder { + if query.starts_with('!') { + let mut split = query.split('+'); + let short = split.next(); + if let Some(short) = short { + let query = split.collect::<Vec<&str>>().join(" "); + + let mut url: &str = ""; + for se in &config.search_engines { + if se.short == short { + url = &se.url; + } + println!("hi"); + } + return HttpResponse::Found() + .header("Location", url.replace("%s", &query)) + .finish(); + } + } else { + let general: Vec<&Engine> = config + .search_engines + .iter() + .filter(|se| se.general) + .collect(); + let engine = general.choose(&mut rand::thread_rng()).unwrap(); + return HttpResponse::Found() + .header("Location", engine.url.replace("%s", &query)) + .finish(); + } + HttpResponse::BadRequest().finish() +} + +#[actix_web::main] +async fn main() -> std::io::Result<()> { + let f = std::fs::File::open("search_engines.csv").unwrap(); + let config = Config::load_from(f).unwrap(); + + HttpServer::new(move || App::new().data(config.clone()).service(search)) + .bind("127.0.0.1:5005")? + .run() + .await +} |