mirror of
https://github.com/neon-mmd/websurfx.git
synced 2024-11-24 23:18:22 -05:00
♻️ Clean some code, fix bug (#396)
* ♻️ Improve src/handler Removes unnecessary submoduling & adjusts some weird code * ♻️ Cleaner code * 🐛 Fixed issue where code would overflow if page=0
This commit is contained in:
parent
7e1a80dc7e
commit
5e2669b6de
@ -1,7 +1,7 @@
|
|||||||
//! This module provides the functionality to parse the lua config and convert the config options
|
//! This module provides the functionality to parse the lua config and convert the config options
|
||||||
//! into rust readable form.
|
//! into rust readable form.
|
||||||
|
|
||||||
use crate::handler::paths::{file_path, FileType};
|
use crate::handler::{file_path, FileType};
|
||||||
|
|
||||||
use crate::models::parser_models::{AggregatorConfig, RateLimiter, Style};
|
use crate::models::parser_models::{AggregatorConfig, RateLimiter, Style};
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
|
@ -1,5 +1,115 @@
|
|||||||
//! This module provides modules which provide the functionality to handle paths for different
|
//! This module provides the functionality to handle theme folder present on different paths and
|
||||||
//! files present on different paths and provide one appropriate path on which it is present and
|
//! provide one appropriate path on which it is present and can be used.
|
||||||
//! can be used.
|
|
||||||
|
|
||||||
pub mod paths;
|
use std::collections::HashMap;
|
||||||
|
use std::io::Error;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
// ------- Constants --------
|
||||||
|
/// The constant holding the name of the theme folder.
|
||||||
|
const PUBLIC_DIRECTORY_NAME: &str = "public";
|
||||||
|
/// The constant holding the name of the common folder.
|
||||||
|
const COMMON_DIRECTORY_NAME: &str = "websurfx";
|
||||||
|
/// The constant holding the name of the config file.
|
||||||
|
const CONFIG_FILE_NAME: &str = "config.lua";
|
||||||
|
/// The constant holding the name of the AllowList text file.
|
||||||
|
const ALLOWLIST_FILE_NAME: &str = "allowlist.txt";
|
||||||
|
/// The constant holding the name of the BlockList text file.
|
||||||
|
const BLOCKLIST_FILE_NAME: &str = "blocklist.txt";
|
||||||
|
|
||||||
|
/// An enum type which provides different variants to handle paths for various files/folders.
|
||||||
|
#[derive(Hash, PartialEq, Eq, Debug)]
|
||||||
|
pub enum FileType {
|
||||||
|
/// This variant handles all the paths associated with the config file.
|
||||||
|
Config,
|
||||||
|
/// This variant handles all the paths associated with the Allowlist text file.
|
||||||
|
AllowList,
|
||||||
|
/// This variant handles all the paths associated with the BlockList text file.
|
||||||
|
BlockList,
|
||||||
|
/// This variant handles all the paths associated with the public folder (Theme folder).
|
||||||
|
Theme,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A static variable which stores the different filesystem paths for various file/folder types.
|
||||||
|
static FILE_PATHS_FOR_DIFF_FILE_TYPES: OnceLock<HashMap<FileType, Vec<String>>> = OnceLock::new();
|
||||||
|
|
||||||
|
/// A function which returns an appropriate path for thr provided file type by checking if the path
|
||||||
|
/// for the given file type exists on that path.
|
||||||
|
///
|
||||||
|
/// # Error
|
||||||
|
///
|
||||||
|
/// Returns a `<File Name> folder/file not found!!` error if the give file_type folder/file is not
|
||||||
|
/// present on the path on which it is being tested.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// If this function is give the file_type of Theme variant then the theme folder is checked by the
|
||||||
|
/// following steps:
|
||||||
|
///
|
||||||
|
/// 1. `/opt/websurfx` if it not present here then it fallbacks to the next one (2)
|
||||||
|
/// 2. Under project folder ( or codebase in other words) if it is not present
|
||||||
|
/// here then it returns an error as mentioned above.
|
||||||
|
pub fn file_path(file_type: FileType) -> Result<&'static str, Error> {
|
||||||
|
let home = env!("HOME");
|
||||||
|
|
||||||
|
let file_path: &Vec<String> = FILE_PATHS_FOR_DIFF_FILE_TYPES
|
||||||
|
.get_or_init(|| {
|
||||||
|
HashMap::from([
|
||||||
|
(
|
||||||
|
FileType::Config,
|
||||||
|
vec![
|
||||||
|
format!(
|
||||||
|
"{}/.config/{}/{}",
|
||||||
|
home, COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME
|
||||||
|
),
|
||||||
|
format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
|
||||||
|
format!("./{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FileType::Theme,
|
||||||
|
vec![
|
||||||
|
format!("/opt/websurfx/{}/", PUBLIC_DIRECTORY_NAME),
|
||||||
|
format!("./{}/", PUBLIC_DIRECTORY_NAME),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FileType::AllowList,
|
||||||
|
vec![
|
||||||
|
format!(
|
||||||
|
"{}/.config/{}/{}",
|
||||||
|
home, COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME
|
||||||
|
),
|
||||||
|
format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
|
||||||
|
format!("./{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FileType::BlockList,
|
||||||
|
vec![
|
||||||
|
format!(
|
||||||
|
"{}/.config/{}/{}",
|
||||||
|
home, COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME
|
||||||
|
),
|
||||||
|
format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
|
||||||
|
format!("./{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
.get(&file_type)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for path in file_path.iter() {
|
||||||
|
if Path::new(path).exists() {
|
||||||
|
return Ok(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no of the configs above exist, return error
|
||||||
|
Err(Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
format!("{:?} file/folder not found!!", file_type),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
//! This module provides the functionality to handle theme folder present on different paths and
|
|
||||||
//! provide one appropriate path on which it is present and can be used.
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::io::Error;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::sync::OnceLock;
|
|
||||||
|
|
||||||
// ------- Constants --------
|
|
||||||
/// The constant holding the name of the theme folder.
|
|
||||||
const PUBLIC_DIRECTORY_NAME: &str = "public";
|
|
||||||
/// The constant holding the name of the common folder.
|
|
||||||
const COMMON_DIRECTORY_NAME: &str = "websurfx";
|
|
||||||
/// The constant holding the name of the config file.
|
|
||||||
const CONFIG_FILE_NAME: &str = "config.lua";
|
|
||||||
/// The constant holding the name of the AllowList text file.
|
|
||||||
const ALLOWLIST_FILE_NAME: &str = "allowlist.txt";
|
|
||||||
/// The constant holding the name of the BlockList text file.
|
|
||||||
const BLOCKLIST_FILE_NAME: &str = "blocklist.txt";
|
|
||||||
|
|
||||||
/// An enum type which provides different variants to handle paths for various files/folders.
|
|
||||||
#[derive(Hash, PartialEq, Eq, Debug)]
|
|
||||||
pub enum FileType {
|
|
||||||
/// This variant handles all the paths associated with the config file.
|
|
||||||
Config,
|
|
||||||
/// This variant handles all the paths associated with the Allowlist text file.
|
|
||||||
AllowList,
|
|
||||||
/// This variant handles all the paths associated with the BlockList text file.
|
|
||||||
BlockList,
|
|
||||||
/// This variant handles all the paths associated with the public folder (Theme folder).
|
|
||||||
Theme,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A static variable which stores the different filesystem paths for various file/folder types.
|
|
||||||
static FILE_PATHS_FOR_DIFF_FILE_TYPES: OnceLock<HashMap<FileType, Vec<String>>> = OnceLock::new();
|
|
||||||
|
|
||||||
/// A function which returns an appropriate path for thr provided file type by checking if the path
|
|
||||||
/// for the given file type exists on that path.
|
|
||||||
///
|
|
||||||
/// # Error
|
|
||||||
///
|
|
||||||
/// Returns a `<File Name> folder/file not found!!` error if the give file_type folder/file is not
|
|
||||||
/// present on the path on which it is being tested.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// If this function is give the file_type of Theme variant then the theme folder is checked by the
|
|
||||||
/// following steps:
|
|
||||||
///
|
|
||||||
/// 1. `/opt/websurfx` if it not present here then it fallbacks to the next one (2)
|
|
||||||
/// 2. Under project folder ( or codebase in other words) if it is not present
|
|
||||||
/// here then it returns an error as mentioned above.
|
|
||||||
pub fn file_path(file_type: FileType) -> Result<&'static str, Error> {
|
|
||||||
let file_path: &Vec<String> = FILE_PATHS_FOR_DIFF_FILE_TYPES
|
|
||||||
.get_or_init(|| {
|
|
||||||
HashMap::from([
|
|
||||||
(
|
|
||||||
FileType::Config,
|
|
||||||
vec![
|
|
||||||
format!(
|
|
||||||
"{}/.config/{}/{}",
|
|
||||||
std::env::var("HOME").unwrap(),
|
|
||||||
COMMON_DIRECTORY_NAME,
|
|
||||||
CONFIG_FILE_NAME
|
|
||||||
),
|
|
||||||
format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
|
|
||||||
format!("./{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
FileType::Theme,
|
|
||||||
vec![
|
|
||||||
format!("/opt/websurfx/{}/", PUBLIC_DIRECTORY_NAME),
|
|
||||||
format!("./{}/", PUBLIC_DIRECTORY_NAME),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
FileType::AllowList,
|
|
||||||
vec![
|
|
||||||
format!(
|
|
||||||
"{}/.config/{}/{}",
|
|
||||||
std::env::var("HOME").unwrap(),
|
|
||||||
COMMON_DIRECTORY_NAME,
|
|
||||||
ALLOWLIST_FILE_NAME
|
|
||||||
),
|
|
||||||
format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
|
|
||||||
format!("./{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
FileType::BlockList,
|
|
||||||
vec![
|
|
||||||
format!(
|
|
||||||
"{}/.config/{}/{}",
|
|
||||||
std::env::var("HOME").unwrap(),
|
|
||||||
COMMON_DIRECTORY_NAME,
|
|
||||||
BLOCKLIST_FILE_NAME
|
|
||||||
),
|
|
||||||
format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
|
|
||||||
format!("./{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
])
|
|
||||||
})
|
|
||||||
.get(&file_type)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for (idx, _) in file_path.iter().enumerate() {
|
|
||||||
if Path::new(file_path[idx].as_str()).exists() {
|
|
||||||
return Ok(std::mem::take(&mut &*file_path[idx]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no of the configs above exist, return error
|
|
||||||
Err(Error::new(
|
|
||||||
std::io::ErrorKind::NotFound,
|
|
||||||
format!("{:?} file/folder not found!!", file_type),
|
|
||||||
))
|
|
||||||
}
|
|
@ -24,7 +24,7 @@ use actix_governor::{Governor, GovernorConfigBuilder};
|
|||||||
use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer};
|
use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer};
|
||||||
use cache::cacher::{Cache, SharedCache};
|
use cache::cacher::{Cache, SharedCache};
|
||||||
use config::parser::Config;
|
use config::parser::Config;
|
||||||
use handler::paths::{file_path, FileType};
|
use handler::{file_path, FileType};
|
||||||
|
|
||||||
/// Runs the web server on the provided TCP listener and returns a `Server` instance.
|
/// Runs the web server on the provided TCP listener and returns a `Server` instance.
|
||||||
///
|
///
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//! search engines and then removes duplicate results.
|
//! search engines and then removes duplicate results.
|
||||||
|
|
||||||
use super::user_agent::random_user_agent;
|
use super::user_agent::random_user_agent;
|
||||||
use crate::handler::paths::{file_path, FileType};
|
use crate::handler::{file_path, FileType};
|
||||||
use crate::models::{
|
use crate::models::{
|
||||||
aggregation_models::{EngineErrorInfo, SearchResult, SearchResults},
|
aggregation_models::{EngineErrorInfo, SearchResult, SearchResults},
|
||||||
engine_models::{EngineError, EngineHandler},
|
engine_models::{EngineError, EngineHandler},
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::parser::Config,
|
config::parser::Config,
|
||||||
handler::paths::{file_path, FileType},
|
handler::{file_path, FileType},
|
||||||
};
|
};
|
||||||
use actix_web::{get, web, HttpRequest, HttpResponse};
|
use actix_web::{get, web, HttpRequest, HttpResponse};
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cache::cacher::SharedCache,
|
cache::cacher::SharedCache,
|
||||||
config::parser::Config,
|
config::parser::Config,
|
||||||
handler::paths::{file_path, FileType},
|
handler::{file_path, FileType},
|
||||||
models::{
|
models::{
|
||||||
aggregation_models::SearchResults,
|
aggregation_models::SearchResults,
|
||||||
engine_models::{EngineError, EngineHandler},
|
engine_models::{EngineError, EngineHandler},
|
||||||
@ -47,54 +47,25 @@ pub async fn search(
|
|||||||
.insert_header(("location", "/"))
|
.insert_header(("location", "/"))
|
||||||
.finish());
|
.finish());
|
||||||
}
|
}
|
||||||
let page = match ¶ms.page {
|
|
||||||
Some(page) => *page,
|
|
||||||
None => 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
let (_, results, _) = join!(
|
let get_results = |page| {
|
||||||
results(
|
results(
|
||||||
format!(
|
|
||||||
"http://{}:{}/search?q={}&page={}&safesearch=",
|
|
||||||
config.binding_ip,
|
|
||||||
config.port,
|
|
||||||
query,
|
|
||||||
page - 1,
|
|
||||||
),
|
|
||||||
&config,
|
|
||||||
&cache,
|
|
||||||
query,
|
|
||||||
page - 1,
|
|
||||||
req.clone(),
|
|
||||||
¶ms.safesearch
|
|
||||||
),
|
|
||||||
results(
|
|
||||||
format!(
|
|
||||||
"http://{}:{}/search?q={}&page={}&safesearch=",
|
|
||||||
config.binding_ip, config.port, query, page
|
|
||||||
),
|
|
||||||
&config,
|
&config,
|
||||||
&cache,
|
&cache,
|
||||||
query,
|
query,
|
||||||
page,
|
page,
|
||||||
req.clone(),
|
req.clone(),
|
||||||
¶ms.safesearch
|
¶ms.safesearch,
|
||||||
),
|
|
||||||
results(
|
|
||||||
format!(
|
|
||||||
"http://{}:{}/search?q={}&page={}&safesearch=",
|
|
||||||
config.binding_ip,
|
|
||||||
config.port,
|
|
||||||
query,
|
|
||||||
page + 1,
|
|
||||||
),
|
|
||||||
&config,
|
|
||||||
&cache,
|
|
||||||
query,
|
|
||||||
page + 1,
|
|
||||||
req.clone(),
|
|
||||||
¶ms.safesearch
|
|
||||||
)
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// .max(1) makes sure that the page > 0.
|
||||||
|
let page = params.page.unwrap_or(1).max(1);
|
||||||
|
|
||||||
|
let (_, results, _) = join!(
|
||||||
|
get_results(page - 1),
|
||||||
|
get_results(page),
|
||||||
|
get_results(page + 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().body(
|
Ok(HttpResponse::Ok().body(
|
||||||
@ -129,7 +100,6 @@ pub async fn search(
|
|||||||
/// It returns the `SearchResults` struct if the search results could be successfully fetched from
|
/// It returns the `SearchResults` struct if the search results could be successfully fetched from
|
||||||
/// the cache or from the upstream search engines otherwise it returns an appropriate error.
|
/// the cache or from the upstream search engines otherwise it returns an appropriate error.
|
||||||
async fn results(
|
async fn results(
|
||||||
url: String,
|
|
||||||
config: &Config,
|
config: &Config,
|
||||||
cache: &web::Data<SharedCache>,
|
cache: &web::Data<SharedCache>,
|
||||||
query: &str,
|
query: &str,
|
||||||
@ -137,6 +107,14 @@ async fn results(
|
|||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
safe_search: &Option<u8>,
|
safe_search: &Option<u8>,
|
||||||
) -> Result<SearchResults, Box<dyn std::error::Error>> {
|
) -> Result<SearchResults, Box<dyn std::error::Error>> {
|
||||||
|
let url = format!(
|
||||||
|
"http://{}:{}/search?q={}&page={}&safesearch=",
|
||||||
|
config.binding_ip,
|
||||||
|
config.port,
|
||||||
|
query,
|
||||||
|
page - 1,
|
||||||
|
);
|
||||||
|
|
||||||
// fetch the cached results json.
|
// fetch the cached results json.
|
||||||
let cached_results = cache.cached_json(&url).await;
|
let cached_results = cache.cached_json(&url).await;
|
||||||
// check if fetched cache results was indeed fetched or it was an error and if so
|
// check if fetched cache results was indeed fetched or it was an error and if so
|
||||||
@ -157,11 +135,11 @@ async fn results(
|
|||||||
|
|
||||||
if safe_search_level == 4 {
|
if safe_search_level == 4 {
|
||||||
let mut results: SearchResults = SearchResults::default();
|
let mut results: SearchResults = SearchResults::default();
|
||||||
let mut _flag: bool =
|
|
||||||
is_match_from_filter_list(file_path(FileType::BlockList)?, query)?;
|
|
||||||
_flag = !is_match_from_filter_list(file_path(FileType::AllowList)?, query)?;
|
|
||||||
|
|
||||||
if _flag {
|
let flag: bool =
|
||||||
|
!is_match_from_filter_list(file_path(FileType::BlockList)?, query)?;
|
||||||
|
|
||||||
|
if flag {
|
||||||
results.set_disallowed();
|
results.set_disallowed();
|
||||||
cache.cache_results(&results, &url).await?;
|
cache.cache_results(&results, &url).await?;
|
||||||
results.set_safe_search_level(safe_search_level);
|
results.set_safe_search_level(safe_search_level);
|
||||||
@ -264,14 +242,13 @@ fn is_match_from_filter_list(
|
|||||||
file_path: &str,
|
file_path: &str,
|
||||||
query: &str,
|
query: &str,
|
||||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||||
let mut flag = false;
|
|
||||||
let mut reader = BufReader::new(File::open(file_path)?);
|
let mut reader = BufReader::new(File::open(file_path)?);
|
||||||
for line in reader.by_ref().lines() {
|
for line in reader.by_ref().lines() {
|
||||||
let re = Regex::new(&line?)?;
|
let re = Regex::new(&line?)?;
|
||||||
if re.is_match(query) {
|
if re.is_match(query) {
|
||||||
flag = true;
|
return Ok(true);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(flag)
|
|
||||||
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! A module that handles the user interface tab for setting page view in the `websurfx` frontend.
|
//! A module that handles the user interface tab for setting page view in the `websurfx` frontend.
|
||||||
|
|
||||||
use crate::handler::paths::{file_path, FileType};
|
use crate::handler::{file_path, FileType};
|
||||||
use maud::{html, Markup};
|
use maud::{html, Markup};
|
||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ pub fn search(
|
|||||||
img src="./images/no_selection.png" alt="Image of a white cross inside a red circle";
|
img src="./images/no_selection.png" alt="Image of a white cross inside a red circle";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@else{
|
@else {
|
||||||
.result_not_found {
|
.result_not_found {
|
||||||
p{"Your search - "{(query)}" - did not match any documents."}
|
p{"Your search - "{(query)}" - did not match any documents."}
|
||||||
p class="suggestions"{"Suggestions:"}
|
p class="suggestions"{"Suggestions:"}
|
||||||
|
Loading…
Reference in New Issue
Block a user