clippy and fixes

This commit is contained in:
mat 2023-12-21 03:00:18 -06:00
parent e6239134a4
commit 944c35f12c
11 changed files with 78 additions and 23 deletions

7
Cargo.lock generated
View File

@ -52,12 +52,6 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]] [[package]]
name = "async-stream" name = "async-stream"
version = "0.3.5" version = "0.3.5"
@ -812,7 +806,6 @@ name = "metasearch2"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ammonia", "ammonia",
"anyhow",
"async-stream", "async-stream",
"axum", "axum",
"base64", "base64",

View File

@ -7,7 +7,6 @@ edition = "2021"
[dependencies] [dependencies]
ammonia = "3.3.0" ammonia = "3.3.0"
anyhow = "1.0.75"
async-stream = "0.3.5" async-stream = "0.3.5"
axum = { version = "0.7.2", features = ["http2"] } axum = { version = "0.7.2", features = ["http2"] }
base64 = "0.21.5" base64 = "0.21.5"

View File

@ -1,5 +1,7 @@
use crate::engines::EngineResponse; use crate::engines::EngineResponse;
use super::regex;
pub fn request(query: &str) -> EngineResponse { pub fn request(query: &str) -> EngineResponse {
let Some(result_html) = evaluate(query, true) else { let Some(result_html) = evaluate(query, true) else {
return EngineResponse::new(); return EngineResponse::new();
@ -19,7 +21,7 @@ pub fn request_autocomplete(query: &str) -> Vec<String> {
results.push(format!("{query}={result}")); results.push(format!("{query}={result}"));
} }
return results; results
} }
fn evaluate(query: &str, html: bool) -> Option<String> { fn evaluate(query: &str, html: bool) -> Option<String> {
@ -28,13 +30,18 @@ fn evaluate(query: &str, html: bool) -> Option<String> {
return None; return None;
} }
// probably a query operator thing or a url, fend evaluates these but it shouldn't
if regex!("^[a-z]{2,}:").is_match(query) {
return None;
}
let mut context = fend_core::Context::new(); let mut context = fend_core::Context::new();
// make lowercase f and c work // make lowercase f and c work
context.define_custom_unit_v1("f", "f", "°F", &fend_core::CustomUnitAttribute::Alias); context.define_custom_unit_v1("f", "f", "°F", &fend_core::CustomUnitAttribute::Alias);
context.define_custom_unit_v1("c", "c", "°C", &fend_core::CustomUnitAttribute::Alias); context.define_custom_unit_v1("c", "c", "°C", &fend_core::CustomUnitAttribute::Alias);
// make random work // make random work
context.set_random_u32_fn(|| rand::random::<u32>()); context.set_random_u32_fn(rand::random::<u32>);
if html { if html {
// this makes it generate slightly nicer outputs for some queries like 2d6 // this makes it generate slightly nicer outputs for some queries like 2d6
context.set_output_mode_terminal(); context.set_output_mode_terminal();
@ -71,5 +78,5 @@ fn evaluate(query: &str, html: bool) -> Option<String> {
} }
} }
return Some(result_html); Some(result_html)
} }

View File

@ -14,6 +14,6 @@ pub fn request(query: &SearchQuery) -> EngineResponse {
EngineResponse::answer_html(if let Some(user_agent) = user_agent { EngineResponse::answer_html(if let Some(user_agent) = user_agent {
format!("<h3><b>{user_agent}</b></h3>") format!("<h3><b>{user_agent}</b></h3>")
} else { } else {
format!("You don't have a user agent") "You don't have a user agent".to_string()
}) })
} }

View File

@ -76,14 +76,14 @@ pub fn parse_response(body: &str) -> eyre::Result<EngineResponse> {
extract, extract,
thumbnail: _, thumbnail: _,
} = page; } = page;
if extract.ends_with(":") { if extract.ends_with(':') {
return Ok(EngineResponse::new()); return Ok(EngineResponse::new());
} }
// this is present on the wikipedia article for google // this is present on the wikipedia article for google
let extract = extract.replace("( )", ""); let extract = extract.replace("( )", "");
let page_title = title.replace(" ", "_"); let page_title = title.replace(' ', "_");
let page_url = format!("https://en.wikipedia.org/wiki/{page_title}"); let page_url = format!("https://en.wikipedia.org/wiki/{page_title}");
Ok(EngineResponse::infobox_html(format!( Ok(EngineResponse::infobox_html(format!(

View File

@ -262,7 +262,7 @@ pub async fn search_with_engines(
requests.push(async { requests.push(async {
let engine = *engine; let engine = *engine;
let request_response = engine.request(query).into(); let request_response = engine.request(query);
let response = match request_response { let response = match request_response {
RequestResponse::Http(request) => { RequestResponse::Http(request) => {
@ -424,12 +424,12 @@ pub async fn search(
progress_tx: mpsc::UnboundedSender<ProgressUpdate>, progress_tx: mpsc::UnboundedSender<ProgressUpdate>,
) -> eyre::Result<()> { ) -> eyre::Result<()> {
let engines = Engine::all(); let engines = Engine::all();
search_with_engines(&engines, &query, progress_tx).await search_with_engines(engines, &query, progress_tx).await
} }
pub async fn autocomplete(query: &str) -> eyre::Result<Vec<String>> { pub async fn autocomplete(query: &str) -> eyre::Result<Vec<String>> {
let engines = Engine::all(); let engines = Engine::all();
autocomplete_with_engines(&engines, query).await autocomplete_with_engines(engines, query).await
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -38,7 +38,35 @@ pub fn parse_response(body: &str) -> eyre::Result<EngineResponse> {
.unwrap_or_default(); .unwrap_or_default();
clean_url(url) clean_url(url)
}))) })))
.description(".b_caption > p, p.b_algoSlug, .b_caption .ipText"), .description(QueryMethod::Manual(Box::new(|el: &ElementRef| {
let mut description = String::new();
for inner_node in el
.select(
&Selector::parse(".b_caption > p, p.b_algoSlug, .b_caption .ipText")
.unwrap(),
)
.next()
.map(|n| n.children().collect::<Vec<_>>())
.unwrap_or_default()
{
match inner_node.value() {
scraper::Node::Text(t) => {
description.push_str(&t.text);
}
scraper::Node::Element(inner_el) => {
if !inner_el
.has_class("algoSlug_icon", scraper::CaseSensitivity::CaseSensitive)
{
let element_ref = ElementRef::wrap(inner_node).unwrap();
description.push_str(&element_ref.text().collect::<String>());
}
}
_ => {}
}
}
Ok(description)
}))),
) )
} }

View File

@ -44,10 +44,19 @@ pub fn normalize_url(url: &str) -> eyre::Result<String> {
)); ));
} }
// convert minecraft.fandom.com/wiki/ to minecraft.wiki/w/
if url.host_str() == Some("minecraft.fandom.com") {
let path = url.path().to_string();
if let Some(path) = path.strip_prefix("/wiki/") {
url.set_host(Some("minecraft.wiki")).unwrap();
url.set_path(&format!("/w/{path}"));
}
}
// url decode and encode path // url decode and encode path
let path = url.path().to_string(); let path = url.path().to_string();
let path = urlencoding::decode(&path)?; let path = urlencoding::decode(&path)?;
url.set_path(&path.to_string()); url.set_path(path.as_ref());
let url = url.to_string(); let url = url.to_string();
// remove trailing slash // remove trailing slash
@ -57,5 +66,5 @@ pub fn normalize_url(url: &str) -> eyre::Result<String> {
url url
}; };
return Ok(url); Ok(url)
} }

View File

@ -72,12 +72,14 @@ impl ParseOpts {
} }
} }
type ManualQueryMethod = Box<dyn Fn(&scraper::ElementRef) -> eyre::Result<String>>;
#[derive(Default)] #[derive(Default)]
pub enum QueryMethod { pub enum QueryMethod {
#[default] #[default]
None, None,
CssSelector(&'static str), CssSelector(&'static str),
Manual(Box<dyn Fn(&scraper::ElementRef) -> eyre::Result<String>>), Manual(ManualQueryMethod),
} }
impl From<&'static str> for QueryMethod { impl From<&'static str> for QueryMethod {

View File

@ -118,6 +118,14 @@ document.addEventListener("keydown", (e) => {
searchInputEl.focus(); searchInputEl.focus();
searchInputEl.setSelectionRange(0, 0); searchInputEl.setSelectionRange(0, 0);
} }
// backspace key focuses it at the end
else if (e.key === "Backspace") {
searchInputEl.focus();
searchInputEl.setSelectionRange(
searchInputEl.value.length,
searchInputEl.value.length
);
}
}); });
// update the input suggestions on input // update the input suggestions on input
@ -127,3 +135,7 @@ searchInputEl.addEventListener("input", () => {
}); });
// and on focus // and on focus
searchInputEl.addEventListener("focus", updateSuggestions); searchInputEl.addEventListener("focus", updateSuggestions);
// on unfocus hide the suggestions
searchInputEl.addEventListener("blur", () => {
suggestionsEl.style.visibility = "hidden";
});

View File

@ -53,6 +53,9 @@ a {
a:visited { a:visited {
color: #92e; color: #92e;
} }
pre {
white-space: pre-wrap;
}
/* index page */ /* index page */
.main-container { .main-container {
@ -219,13 +222,15 @@ h1 {
.infobox p { .infobox p {
margin: 0; margin: 0;
} }
.infobox-stackoverflow-answer pre > code { .infobox-stackoverflow-answer pre > code,
.infobox-github-readme pre {
border: 1px solid #234; border: 1px solid #234;
padding: 0.5rem; padding: 0.5rem;
display: block; display: block;
font-weight: normal; font-weight: normal;
} }
.infobox-stackoverflow-answer code { .infobox-stackoverflow-answer code,
.infobox-github-readme code {
font-weight: bold; font-weight: bold;
} }
.postsearch-infobox p { .postsearch-infobox p {