clippy and fixes
This commit is contained in:
parent
e6239134a4
commit
944c35f12c
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -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",
|
||||||
|
@ -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"
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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!(
|
||||||
|
@ -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)]
|
||||||
|
@ -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)
|
||||||
|
}))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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";
|
||||||
|
});
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user