Skip to content

Commit

Permalink
Merge pull request #202 from neon-mmd/feat-disallow-user-to-search-vi…
Browse files Browse the repository at this point in the history
…a-lists

✨ `Safe search` levels and `filter lists` for the app
  • Loading branch information
alamin655 authored Sep 11, 2023
2 parents d3a7435 + 6c94b92 commit 867753a
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 80 deletions.
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "websurfx"
version = "0.18.6"
version = "0.19.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"
Expand All @@ -10,7 +10,7 @@ license = "AGPL-3.0"
reqwest = {version="0.11.20",features=["json"]}
tokio = {version="1.32.0",features=["rt-multi-thread","macros"]}
serde = {version="1.0.188",features=["derive"]}
handlebars = { version = "4.3.7", features = ["dir_source"] }
handlebars = { version = "4.4.0", features = ["dir_source"] }
scraper = {version="0.17.1"}
actix-web = {version="4.4.0", features = ["cookies"]}
actix-files = {version="0.6.2"}
Expand All @@ -19,8 +19,8 @@ serde_json = {version="1.0.105"}
fake-useragent = {version="0.1.3"}
env_logger = {version="0.10.0"}
log = {version="0.4.20"}
mlua = {version="0.8.10",features=["luajit"]}
redis = {version="0.23.2",features=["tokio-comp","connection-manager"]}
mlua = {version="0.8.10", features=["luajit"]}
redis = {version="0.23.3", features=["tokio-comp","connection-manager"]}
md5 = {version="0.7.0"}
rand={version="0.8.5"}
once_cell = {version="1.18.0"}
Expand Down
Binary file added public/images/barricade.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/filter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions public/static/themes/simple.css
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,35 @@ body {
width: 1.2rem;
height: 1.2rem;
}
.results .result_disallowed,
.results .result_filtered {
display: flex;
justify-content: center;
align-items: center;
gap: 10rem;
font-size: 2rem;
color: var(--foreground-color);
margin: 0rem 7rem;
}

.results .result_disallowed .user_query,
.results .result_filtered .user_query {
color: var(--background-color);
font-weight: 300;
}

.results .result_disallowed img,
.results .result_filtered img {
width: 30rem;
}

.results .result_disallowed div,
.results .result_filtered div {
display: flex;
flex-direction: column;
gap: 1rem;
line-break: strict;
}

/* styles for the footer and header */

Expand Down
92 changes: 62 additions & 30 deletions public/templates/search.html
Original file line number Diff line number Diff line change
@@ -1,37 +1,69 @@
{{>header this.style}}
<main class="results">
{{>search_bar this}}
<div class="results_aggregated">
{{#if results}} {{#each results}}
<div class="result">
<h1><a href="{{{this.url}}}">{{{this.title}}}</a></h1>
<small>{{{this.url}}}</small>
<p>{{{this.description}}}</p>
<div class="upstream_engines">
{{#each engine}}
<span>{{{this}}}</span>
{{/each}}
</div>
{{>search_bar this}}
<div class="results_aggregated">
{{#if results}} {{#each results}}
<div class="result">
<h1><a href="{{{this.url}}}">{{{this.title}}}</a></h1>
<small>{{{this.url}}}</small>
<p>{{{this.description}}}</p>
<div class="upstream_engines">
{{#each engine}}
<span>{{{this}}}</span>
{{/each}}
</div>
</div>
{{/each}} {{else}} {{#if disallowed}}
<div class="result_disallowed">
<div class="description">
<p>
Your search - <span class="user_query">{{{this.pageQuery}}}</span> -
has been disallowed.
</p>
<p class="description_paragraph">Dear user,</p>
<p class="description_paragraph">
The query - <span class="user_query">{{{this.pageQuery}}}</span> - has
been blacklisted via server configuration and hence disallowed by the
server. Henceforth no results could be displayed for your query.
</p>
</div>
<img src="./images/barricade.png" alt="Image of a Barricade" />
</div>
{{else}} {{#if filtered}}
<div class="result_filtered">
<div class="description">
<p>
Your search - <span class="user_query">{{{this.pageQuery}}}</span> -
has been filtered.
</p>
<p class="description_paragraph">Dear user,</p>
<p class="description_paragraph">
All the search results contain results that has been configured to be
filtered out via server configuration and henceforth has been
completely filtered out.
</p>
</div>
<img src="./images/filter.png" alt="Image of a paper inside a funnel" />
</div>
{{else}}
<div class="result_not_found">
<p>Your search - {{{this.pageQuery}}} - did not match any documents.</p>
<p class="suggestions">Suggestions:</p>
<ul>
<li>Make sure that all words are spelled correctly.</li>
<li>Try different keywords.</li>
<li>Try more general keywords.</li>
</ul>
<img src="./images/no_results.gif" alt="Man fishing gif" />
</div>
{{/if}} {{/if}} {{/if}}
</div>
{{/each}} {{else}}
<div class="result_not_found">
<p>Your search - {{{this.pageQuery}}} - did not match any documents.</p>
<p class="suggestions">Suggestions:</p>
<ul>
<li>Make sure that all words are spelled correctly.</li>
<li>Try different keywords.</li>
<li>Try more general keywords.</li>
</ul>
<img src="./images/no_results.gif" alt="Man fishing gif" />
<div class="page_navigation">
<button type="button" onclick="navigate_backward()">
&#8592; previous
</button>
<button type="button" onclick="navigate_forward()">next &#8594;</button>
</div>
{{/if}}
</div>
<div class="page_navigation">
<button type="button" onclick="navigate_backward()">
&#8592; previous
</button>
<button type="button" onclick="navigate_forward()">next &#8594;</button>
</div>
</main>
<script src="static/index.js"></script>
<script src="static/pagination.js"></script>
Expand Down
12 changes: 12 additions & 0 deletions src/config/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct Config {
pub upstream_search_engines: Vec<crate::engines::engine_models::EngineHandler>,
pub request_timeout: u8,
pub threads: u8,
pub safe_search: u8,
}

/// Configuration options for the aggregator.
Expand Down Expand Up @@ -89,6 +90,16 @@ impl Config {
parsed_threads
};

let parsed_safe_search: u8 = globals.get::<_, u8>("safe_search")?;
let safe_search: u8 = match parsed_safe_search {
0..=4 => parsed_safe_search,
_ => {
log::error!("Config Error: The value of `safe_search` option should be a non zero positive integer from 0 to 4.");
log::error!("Falling back to using the value `1` for the option");
1
}
};

Ok(Config {
port: globals.get::<_, u16>("port")?,
binding_ip: globals.get::<_, String>("binding_ip")?,
Expand All @@ -110,6 +121,7 @@ impl Config {
.collect(),
request_timeout: globals.get::<_, u8>("request_timeout")?,
threads,
safe_search,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions src/engines/duckduckgo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl SearchEngine for DuckDuckGo {
page: u32,
user_agent: &str,
request_timeout: u8,
_safe_search: u8,
) -> Result<HashMap<String, SearchResult>, EngineError> {
// Page number can be missing or empty string and so appropriate handling is required
// so that upstream server recieves valid page number.
Expand Down
1 change: 1 addition & 0 deletions src/engines/engine_models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub trait SearchEngine: Sync + Send {
page: u32,
user_agent: &str,
request_timeout: u8,
safe_search: u8,
) -> Result<HashMap<String, SearchResult>, EngineError>;
}

Expand Down
13 changes: 11 additions & 2 deletions src/engines/searx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,21 @@ impl SearchEngine for Searx {
page: u32,
user_agent: &str,
request_timeout: u8,
mut safe_search: u8,
) -> Result<HashMap<String, SearchResult>, EngineError> {
// Page number can be missing or empty string and so appropriate handling is required
// so that upstream server recieves valid page number.
if safe_search == 3 {
safe_search = 2;
};

let url: String = match page {
0 | 1 => format!("https://searx.work/search?q={query}&pageno=1"),
_ => format!("https://searx.work/search?q={query}&pageno={page}"),
0 | 1 => {
format!("https://searx.work/search?q={query}&pageno=1&safesearch={safe_search}")
}
_ => format!(
"https://searx.work/search?q={query}&pageno={page}&safesearch={safe_search}"
),
};

// initializing headers and adding appropriate headers.
Expand Down
37 changes: 33 additions & 4 deletions src/results/aggregation_models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,15 @@ impl EngineErrorInfo {
/// and the type of error that caused it.
/// * `empty_result_set` - Stores a boolean which indicates that no engines gave a result for the
/// given search query.
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct SearchResults {
pub results: Vec<SearchResult>,
pub page_query: String,
pub style: Style,
pub engine_errors_info: SmallVec<[EngineErrorInfo; 0]>,
pub engine_errors_info: Vec<EngineErrorInfo>,
pub disallowed: bool,
pub filtered: bool,
}

impl SearchResults {
Expand All @@ -122,6 +124,7 @@ impl SearchResults {
/// the search url.
/// * `empty_result_set` - Takes a boolean which indicates that no engines gave a result for the
/// given search query.
/// * ``
pub fn new(
results: Vec<SearchResult>,
page_query: &str,
Expand All @@ -131,12 +134,38 @@ impl SearchResults {
results,
page_query: page_query.to_owned(),
style: Style::default(),
engine_errors_info: SmallVec::from(engine_errors_info),
engine_errors_info: engine_errors_info.to_owned(),
disallowed: Default::default(),
filtered: Default::default(),
}
}

/// A setter function to add website style to the return search results.
pub fn add_style(&mut self, style: &Style) {
self.style = style.to_owned();
self.style = style.clone();
}

/// A setter function that sets disallowed to true.
pub fn set_disallowed(&mut self) {
self.disallowed = true;
}

/// A setter function to set the current page search query.
pub fn set_page_query(&mut self, page: &str) {
self.page_query = page.to_owned();
}

/// A setter function that sets the filtered to true.
pub fn set_filtered(&mut self) {
self.filtered = true;
}

/// A getter function that gets the value of `engine_errors_info`.
pub fn engine_errors_info(&mut self) -> Vec<EngineErrorInfo> {
std::mem::take(&mut self.engine_errors_info)
}
/// A getter function that gets the value of `results`.
pub fn results(&mut self) -> Vec<SearchResult> {
self.results.clone()
}
}
Loading

0 comments on commit 867753a

Please sign in to comment.