mirror of
https://github.com/neon-mmd/websurfx.git
synced 2024-12-25 13:58:21 -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
|
||||
//! 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 log::LevelFilter;
|
||||
|
@ -1,5 +1,115 @@
|
||||
//! This module provides modules which provide the functionality to handle paths for different
|
||||
//! files present on different paths and provide one appropriate path on which it is present and
|
||||
//! can be used.
|
||||
//! 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.
|
||||
|
||||
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 cache::cacher::{Cache, SharedCache};
|
||||
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.
|
||||
///
|
||||
|
@ -2,7 +2,7 @@
|
||||
//! search engines and then removes duplicate results.
|
||||
|
||||
use super::user_agent::random_user_agent;
|
||||
use crate::handler::paths::{file_path, FileType};
|
||||
use crate::handler::{file_path, FileType};
|
||||
use crate::models::{
|
||||
aggregation_models::{EngineErrorInfo, SearchResult, SearchResults},
|
||||
engine_models::{EngineError, EngineHandler},
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use crate::{
|
||||
config::parser::Config,
|
||||
handler::paths::{file_path, FileType},
|
||||
handler::{file_path, FileType},
|
||||
};
|
||||
use actix_web::{get, web, HttpRequest, HttpResponse};
|
||||
use std::fs::read_to_string;
|
||||
|
@ -3,7 +3,7 @@
|
||||
use crate::{
|
||||
cache::cacher::SharedCache,
|
||||
config::parser::Config,
|
||||
handler::paths::{file_path, FileType},
|
||||
handler::{file_path, FileType},
|
||||
models::{
|
||||
aggregation_models::SearchResults,
|
||||
engine_models::{EngineError, EngineHandler},
|
||||
@ -47,54 +47,25 @@ pub async fn search(
|
||||
.insert_header(("location", "/"))
|
||||
.finish());
|
||||
}
|
||||
let page = match ¶ms.page {
|
||||
Some(page) => *page,
|
||||
None => 1,
|
||||
};
|
||||
|
||||
let (_, results, _) = join!(
|
||||
let get_results = |page| {
|
||||
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,
|
||||
&cache,
|
||||
query,
|
||||
page,
|
||||
req.clone(),
|
||||
¶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
|
||||
¶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(
|
||||
@ -129,7 +100,6 @@ pub async fn search(
|
||||
/// 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.
|
||||
async fn results(
|
||||
url: String,
|
||||
config: &Config,
|
||||
cache: &web::Data<SharedCache>,
|
||||
query: &str,
|
||||
@ -137,6 +107,14 @@ async fn results(
|
||||
req: HttpRequest,
|
||||
safe_search: &Option<u8>,
|
||||
) -> 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.
|
||||
let cached_results = cache.cached_json(&url).await;
|
||||
// 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 {
|
||||
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();
|
||||
cache.cache_results(&results, &url).await?;
|
||||
results.set_safe_search_level(safe_search_level);
|
||||
@ -264,14 +242,13 @@ fn is_match_from_filter_list(
|
||||
file_path: &str,
|
||||
query: &str,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let mut flag = false;
|
||||
let mut reader = BufReader::new(File::open(file_path)?);
|
||||
for line in reader.by_ref().lines() {
|
||||
let re = Regex::new(&line?)?;
|
||||
if re.is_match(query) {
|
||||
flag = true;
|
||||
break;
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
Ok(flag)
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! 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 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";
|
||||
}
|
||||
}
|
||||
@else{
|
||||
@else {
|
||||
.result_not_found {
|
||||
p{"Your search - "{(query)}" - did not match any documents."}
|
||||
p class="suggestions"{"Suggestions:"}
|
||||
|
Loading…
Reference in New Issue
Block a user