forked from asklyphe-public/asklyphe
Compare commits
9 commits
spellcheck
...
develop
Author | SHA1 | Date | |
---|---|---|---|
24067eca99 | |||
3696d4cb6d | |||
f06b84bf66 | |||
43aae463e8 | |||
87458f30b6 | |||
64a771f8cc | |||
bac21898c9 | |||
245744a317 | |||
109e20c7b4 |
3 changed files with 118 additions and 0 deletions
106
asklyphe-frontend/src/bangs.rs
Normal file
106
asklyphe-frontend/src/bangs.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
use tracing::{debug, error};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use url_encoded_data;
|
||||||
|
|
||||||
|
pub static BANG_PREFIX: &str = "!";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Bang<'a> {
|
||||||
|
pub url: &'a str,
|
||||||
|
pub aliases: &'a [&'a str]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Bang<'_> {
|
||||||
|
fn new(url: &'a str, aliases: &'a [&'a str]) -> Bang<'a> {
|
||||||
|
Bang {url, aliases}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BUILTIN_BANGS: Lazy<BTreeMap<&str, Bang>> = Lazy::new(|| {
|
||||||
|
let mut bangs = BTreeMap::new();
|
||||||
|
bangs.insert("Google", Bang::new("https://google.com/search?q={}", &["g", "google"] as &[&str]));
|
||||||
|
|
||||||
|
bangs.insert("DuckDuckGo", Bang::new("https://duckduckgo.com/?q={}", &["d", "ddg", "duckduckgo"] as &[&str]));
|
||||||
|
|
||||||
|
bangs.insert("Wikipedia", Bang::new("https://wikipedia.org/w/index.php?search={}", &["w", "wiki", "wikipedia"] as &[&str]));
|
||||||
|
bangs
|
||||||
|
});
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct BangLoc<'b> {
|
||||||
|
pub url: &'b str,
|
||||||
|
pub start_idx: usize,
|
||||||
|
pub len: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> BangLoc<'_> {
|
||||||
|
fn new(url: &'b str, start_idx: usize, len: usize) -> BangLoc<'b> {
|
||||||
|
BangLoc {url, start_idx, len}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redirect_bang(query: &String) -> Option<String> {
|
||||||
|
if !query.contains(BANG_PREFIX) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let bangs = query.match_indices(BANG_PREFIX).filter(|(bang_start_idx, _)| {
|
||||||
|
if *bang_start_idx == 0 || query.chars().nth(*bang_start_idx - 1).unwrap().is_whitespace() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}).map(|(bang_start_idx, _)| {
|
||||||
|
let rest = query.get(bang_start_idx + 1..query.len()).unwrap();
|
||||||
|
BUILTIN_BANGS.iter().map(|(_, bang)| {
|
||||||
|
let alias = bang.aliases.iter()
|
||||||
|
.filter(|alias| rest.starts_with(**alias))
|
||||||
|
.filter(
|
||||||
|
|alias| rest.chars()
|
||||||
|
.nth(alias.len())
|
||||||
|
.unwrap_or(' ')
|
||||||
|
.is_whitespace())
|
||||||
|
.max_by(|a, b| a.len().cmp(&b.len()))?;
|
||||||
|
Some(BangLoc::new(bang.url, bang_start_idx, alias.len()))
|
||||||
|
}).filter(|bang| bang.is_some()).map(|bang| bang.unwrap()).next()
|
||||||
|
}).filter(|bang| bang.is_some())
|
||||||
|
.map(|bang| bang.unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
||||||
|
let bang = bangs.first()?;
|
||||||
|
let end_idx = {
|
||||||
|
let mut end_idx = bang.start_idx + 1 + bang.len;
|
||||||
|
if end_idx < query.len() {
|
||||||
|
end_idx += 1;
|
||||||
|
}
|
||||||
|
end_idx
|
||||||
|
};
|
||||||
|
|
||||||
|
let start_idx = if end_idx == query.len() && bang.start_idx > 0 {
|
||||||
|
bang.start_idx - 1
|
||||||
|
} else {
|
||||||
|
bang.start_idx
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let query_split = query.split_once(query.get(start_idx..end_idx).unwrap()).unwrap();
|
||||||
|
|
||||||
|
let query_trimmed = format!("{}{}", query_split.0, query_split.1);
|
||||||
|
|
||||||
|
// A hack to get URL escaping without using a proper URL layout, hopefully has no other issues apart from prepending '=' to the string
|
||||||
|
let query_encoded = url_encoded_data::stringify(&[("", query_trimmed.as_str())]);
|
||||||
|
let query_encoded = query_encoded.get(1..query_encoded.len()).unwrap().to_owned();
|
||||||
|
|
||||||
|
|
||||||
|
let bang_url_split = bang.url.split_once("{}").unwrap();
|
||||||
|
|
||||||
|
let bang_url = format!(
|
||||||
|
"{}{}{}",
|
||||||
|
bang_url_split.0,
|
||||||
|
query_encoded,
|
||||||
|
bang_url_split.1
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(bang_url)
|
||||||
|
}
|
|
@ -14,6 +14,7 @@
|
||||||
pub mod searchbot;
|
pub mod searchbot;
|
||||||
pub mod wikipedia;
|
pub mod wikipedia;
|
||||||
pub mod unit_converter;
|
pub mod unit_converter;
|
||||||
|
pub mod bangs;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
use std::{env, process};
|
use std::{env, process};
|
||||||
|
|
|
@ -18,6 +18,7 @@ use crate::unit_converter;
|
||||||
use crate::unit_converter::UnitConversion;
|
use crate::unit_converter::UnitConversion;
|
||||||
use crate::wikipedia::WikipediaSummary;
|
use crate::wikipedia::WikipediaSummary;
|
||||||
use crate::{wikipedia, Opts, ALPHA, BUILT_ON, GIT_COMMIT, VERSION, YEAR};
|
use crate::{wikipedia, Opts, ALPHA, BUILT_ON, GIT_COMMIT, VERSION, YEAR};
|
||||||
|
use crate::bangs;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use asklyphe_common::nats;
|
use asklyphe_common::nats;
|
||||||
use asklyphe_common::nats::bingservice::{
|
use asklyphe_common::nats::bingservice::{
|
||||||
|
@ -170,6 +171,11 @@ pub async fn search_js(
|
||||||
unit_query = unit_query.replace("metre", "meter");
|
unit_query = unit_query.replace("metre", "meter");
|
||||||
let unit_comp = unit_converter::convert_unit(&unit_query);
|
let unit_comp = unit_converter::convert_unit(&unit_query);
|
||||||
complications.unit_converter = unit_comp;
|
complications.unit_converter = unit_comp;
|
||||||
|
|
||||||
|
let bang_redirect = bangs::redirect_bang(&query);
|
||||||
|
if let Some(redirect) = bang_redirect {
|
||||||
|
return Redirect::to(&redirect).into_response();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
complications.disabled = true;
|
complications.disabled = true;
|
||||||
query = query.replace("-complications", "");
|
query = query.replace("-complications", "");
|
||||||
|
@ -282,6 +288,11 @@ pub async fn search_nojs(
|
||||||
unit_query = unit_query.replace("metre", "meter");
|
unit_query = unit_query.replace("metre", "meter");
|
||||||
let unit_comp = unit_converter::convert_unit(&unit_query);
|
let unit_comp = unit_converter::convert_unit(&unit_query);
|
||||||
complications.unit_converter = unit_comp;
|
complications.unit_converter = unit_comp;
|
||||||
|
|
||||||
|
let bang_redirect = bangs::redirect_bang(&query);
|
||||||
|
if let Some(redirect) = bang_redirect {
|
||||||
|
return Redirect::to(&redirect).into_response();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
complications.disabled = true;
|
complications.disabled = true;
|
||||||
query = query.replace("-complications", "");
|
query = query.replace("-complications", "");
|
||||||
|
|
Loading…
Add table
Reference in a new issue