From fb2b6608fe9c297155aff7282d509354fb7513fa Mon Sep 17 00:00:00 2001 From: aocosmic <51456343+cybrejon@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:29:44 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=92=84`websurfx`=20logo=20redesign=20?= =?UTF-8?q?for=20better=20understandability=20(#418)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lazyload search result text with css content-visibility * typo, lightning-fast is grammatically correct * revamped logo to look more modern * added class to control how new logo looks and behaves * added class to control how new logo looks and behaves --------- Co-authored-by: neon_arch --- public/images/websurfx_logo.png | Bin 7397 -> 8501 bytes public/images/websurfx_logo.svg | 7 +++++++ public/static/themes/simple.css | 4 ++++ src/templates/views/index.rs | 2 +- 4 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 public/images/websurfx_logo.svg diff --git a/public/images/websurfx_logo.png b/public/images/websurfx_logo.png index 8667af39a450f3841851a10436c108abad0ec7b0..24d39e15326b389340444fefc230fa2ab8373791 100644 GIT binary patch literal 8501 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 literal 7397 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 diff --git a/public/images/websurfx_logo.svg b/public/images/websurfx_logo.svg new file mode 100644 index 0000000..2574345 --- /dev/null +++ b/public/images/websurfx_logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/static/themes/simple.css b/public/static/themes/simple.css index 7c01ca5..5eb8949 100644 --- a/public/static/themes/simple.css +++ b/public/static/themes/simple.css @@ -33,6 +33,10 @@ body { display: flex; } +.websurfx-logo { + width: clamp(12rem, 40rem, 48rem); +} + /* styles for the search box and search button */ .search_bar { diff --git a/src/templates/views/index.rs b/src/templates/views/index.rs index 3816f22..cfa1eb6 100644 --- a/src/templates/views/index.rs +++ b/src/templates/views/index.rs @@ -18,7 +18,7 @@ pub fn index(colorscheme: &str, theme: &str) -> Markup { html!( (header(colorscheme, theme)) main class="search-container"{ - img src="../images/websurfx_logo.png" alt="Websurfx meta-search engine logo"; + img class="websurfx-logo" src="../images/websurfx_logo.svg" alt="Websurfx meta-search engine logo"; (bar(&String::default())) (PreEscaped("")) } From e1e426c51769f5e71d52f8fdb87fc20d8588c63d Mon Sep 17 00:00:00 2001 From: neon_arch Date: Tue, 5 Dec 2023 20:47:28 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20feat(engine):=20provide=20start?= =?UTF-8?q?page=20search=20engine=20(#314)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engines/mod.rs | 1 + src/engines/startpage.rs | 96 +++++++++++++++++++++++++++++++++++++ src/models/engine_models.rs | 4 ++ 3 files changed, 101 insertions(+) create mode 100644 src/engines/startpage.rs diff --git a/src/engines/mod.rs b/src/engines/mod.rs index 2892445..53d720b 100644 --- a/src/engines/mod.rs +++ b/src/engines/mod.rs @@ -7,3 +7,4 @@ pub mod brave; pub mod duckduckgo; pub mod search_result_parser; pub mod searx; +pub mod startpage; diff --git a/src/engines/startpage.rs b/src/engines/startpage.rs new file mode 100644 index 0000000..44135e1 --- /dev/null +++ b/src/engines/startpage.rs @@ -0,0 +1,96 @@ +//! The `duckduckgo` module handles the scraping of results from the duckduckgo search engine +//! by querying the upstream duckduckgo search engine with user provided query and with a page +//! number if provided. + +use std::collections::HashMap; + +use reqwest::header::HeaderMap; +use reqwest::Client; +use scraper::Html; + +use crate::models::aggregation_models::SearchResult; + +use crate::models::engine_models::{EngineError, SearchEngine}; + +use error_stack::{Report, Result, ResultExt}; + +use super::search_result_parser::SearchResultParser; + +/// A new Startpage engine type defined in-order to implement the `SearchEngine` trait which allows to +/// reduce code duplication as well as allows to create vector of different search engines easily. +pub struct Startpage { + /// The parser, used to interpret the search result. + parser: SearchResultParser, +} + +impl Startpage { + /// Creates the Startpage parser. + pub fn new() -> Result { + Ok(Self { + parser: SearchResultParser::new( + ".no-results", + ".w-gl__result__main", + ".w-gl__result-second-line-container>.w-gl__result-title>h3", + ".w-gl__result-url", + ".w-gl__description", + )?, + }) + } +} + +#[async_trait::async_trait] +impl SearchEngine for Startpage { + async fn results( + &self, + query: &str, + page: u32, + user_agent: &str, + client: &Client, + _safe_search: u8, + ) -> Result, EngineError> { + // Page number can be missing or empty string and so appropriate handling is required + // so that upstream server recieves valid page number. + let url: String = match page { + 1 | 0 => { + format!("https://startpage.com/do/dsearch?q={query}&num=10&start=0") + } + _ => { + format!( + "https://startpage.com/do/dsearch?q={query}&num=10&start={}", + page * 10, + ) + } + }; + + // initializing HeaderMap and adding appropriate headers. + let header_map = HeaderMap::try_from(&HashMap::from([ + ("USER_AGENT".to_string(), user_agent.to_string()), + ("REFERER".to_string(), "https://google.com/".to_string()), + ( + "CONTENT_TYPE".to_string(), + "application/x-www-form-urlencoded".to_string(), + ), + ("COOKIE".to_string(), "preferences=connect_to_serverEEE0N1Ndate_timeEEEworldN1Ndisable_family_filterEEE0N1Ndisable_open_in_new_windowEEE0N1Nenable_post_methodEEE1N1Nenable_proxy_safety_suggestEEE1N1Nenable_stay_controlEEE0N1Ninstant_answersEEE1N1Nlang_homepageEEEs%2Fnight%2FenN1NlanguageEEEenglishN1Nlanguage_uiEEEenglishN1Nnum_of_resultsEEE10N1Nsearch_results_regionEEEallN1NsuggestionsEEE1N1Nwt_unitEEEcelsius".to_string()), + ])) + .change_context(EngineError::UnexpectedError)?; + + let document: Html = Html::parse_document( + &Startpage::fetch_html_from_upstream(self, &url, header_map, client).await?, + ); + + if self.parser.parse_for_no_results(&document).next().is_some() { + return Err(Report::new(EngineError::EmptyResultSet)); + } + + // scrape all the results from the html + self.parser + .parse_for_results(&document, |title, url, desc| { + Some(SearchResult::new( + title.inner_html().trim(), + &format!("{}", url.inner_html().trim()), + desc.inner_html().trim(), + &["startpage"], + )) + }) + } +} diff --git a/src/models/engine_models.rs b/src/models/engine_models.rs index f8e966e..1ab04ed 100644 --- a/src/models/engine_models.rs +++ b/src/models/engine_models.rs @@ -154,6 +154,10 @@ impl EngineHandler { let engine = crate::engines::brave::Brave::new()?; ("brave", Box::new(engine)) } + "startpage" => { + let engine = crate::engines::startpage::Startpage::new()?; + ("startpage", Box::new(engine)) + } _ => { return Err(Report::from(EngineError::NoSuchEngineFound( engine_name.to_string(), From e8a64f587493fdb3d7412d41b0dfaaa756a9df1f Mon Sep 17 00:00:00 2001 From: neon_arch Date: Tue, 5 Dec 2023 20:49:28 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9C=A8=20feat(engine):=20provide=20start?= =?UTF-8?q?page=20search=20engine=20in=20the=20config=20(#314)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- websurfx/config.lua | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/websurfx/config.lua b/websurfx/config.lua index 57d552c..22e2c4f 100644 --- a/websurfx/config.lua +++ b/websurfx/config.lua @@ -1,18 +1,18 @@ -- ### General ### logging = true -- an option to enable or disable logs. -debug = false -- an option to enable or disable debug mode. -threads = 10 -- the amount of threads that the app will use to run (the value should be greater than 0). +debug = false -- an option to enable or disable debug mode. +threads = 10 -- the amount of threads that the app will use to run (the value should be greater than 0). -- ### Server ### -port = "8080" -- port on which server should be launched +port = "8080" -- port on which server should be launched binding_ip = "127.0.0.1" --ip address on the which server should be launched. -production_use = false -- whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users (more than one)) +production_use = false -- whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users (more than one)) -- if production_use is set to true -- There will be a random delay before sending the request to the search engines, this is to prevent DDoSing the upstream search engines from a large number of simultaneous requests. -request_timeout = 30 -- timeout for the search requests sent to the upstream search engines to be fetched (value in seconds). +request_timeout = 30 -- timeout for the search requests sent to the upstream search engines to be fetched (value in seconds). rate_limiter = { - number_of_requests = 20, -- The number of request that are allowed within a provided time limit. - time_limit = 3, -- The time limit in which the quantity of requests that should be accepted. + number_of_requests = 20, -- The number of request that are allowed within a provided time limit. + time_limit = 3, -- The time limit in which the quantity of requests that should be accepted. } -- ### Search ### @@ -43,14 +43,15 @@ safe_search = 2 -- tomorrow-night -- }} colorscheme = "catppuccin-mocha" -- the colorscheme name which should be used for the website theme -theme = "simple" -- the theme name which should be used for the website +theme = "simple" -- the theme name which should be used for the website -- ### Caching ### redis_url = "redis://127.0.0.1:8082" -- redis connection url address on which the client should connect on. -cache_expiry_time = 600 -- This option takes the expiry time of the search results (value in seconds and the value should be greater than or equal to 60 seconds). +cache_expiry_time = 600 -- This option takes the expiry time of the search results (value in seconds and the value should be greater than or equal to 60 seconds). -- ### Search Engines ### upstream_search_engines = { - DuckDuckGo = true, - Searx = false, - Brave = false, + DuckDuckGo = true, + Searx = false, + Brave = false, + Startpage = false, } -- select the upstream search engines from which the results should be fetched. From 89032e63bd701c3a06d3c5a16c65c205d612883c Mon Sep 17 00:00:00 2001 From: neon_arch Date: Tue, 5 Dec 2023 20:50:30 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=94=96=20chore(release):=20bump=20the?= =?UTF-8?q?=20app=20version=20(#314)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b716074..0bc2c36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4066,7 +4066,7 @@ checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "websurfx" -version = "1.3.6" +version = "1.4.0" dependencies = [ "actix-cors", "actix-files", diff --git a/Cargo.toml b/Cargo.toml index 1f92639..3a0beb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "websurfx" -version = "1.3.6" +version = "1.4.0" edition = "2021" description = "An open-source alternative to Searx that provides clean, ad-free, and organic results with incredible speed while keeping privacy and security in mind." repository = "https://github.com/neon-mmd/websurfx"