víctor commited on
Commit
5e2669b
1 Parent(s): 7e1a80d

:recycle: Clean some code, fix bug (#396)

Browse files

* :recycle: Improve src/handler

Removes unnecessary submoduling & adjusts some weird code

* :recycle: Cleaner code

* 🐛 Fixed issue where code would overflow if page=0

src/config/parser.rs CHANGED
@@ -1,7 +1,7 @@
1
  //! This module provides the functionality to parse the lua config and convert the config options
2
  //! into rust readable form.
3
 
4
- use crate::handler::paths::{file_path, FileType};
5
 
6
  use crate::models::parser_models::{AggregatorConfig, RateLimiter, Style};
7
  use log::LevelFilter;
 
1
  //! This module provides the functionality to parse the lua config and convert the config options
2
  //! into rust readable form.
3
 
4
+ use crate::handler::{file_path, FileType};
5
 
6
  use crate::models::parser_models::{AggregatorConfig, RateLimiter, Style};
7
  use log::LevelFilter;
src/handler/mod.rs CHANGED
@@ -1,5 +1,115 @@
1
- //! This module provides modules which provide the functionality to handle paths for different
2
- //! files present on different paths and provide one appropriate path on which it is present and
3
- //! can be used.
4
 
5
- pub mod paths;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! This module provides the functionality to handle theme folder present on different paths and
2
+ //! provide one appropriate path on which it is present and can be used.
 
3
 
4
+ use std::collections::HashMap;
5
+ use std::io::Error;
6
+ use std::path::Path;
7
+ use std::sync::OnceLock;
8
+
9
+ // ------- Constants --------
10
+ /// The constant holding the name of the theme folder.
11
+ const PUBLIC_DIRECTORY_NAME: &str = "public";
12
+ /// The constant holding the name of the common folder.
13
+ const COMMON_DIRECTORY_NAME: &str = "websurfx";
14
+ /// The constant holding the name of the config file.
15
+ const CONFIG_FILE_NAME: &str = "config.lua";
16
+ /// The constant holding the name of the AllowList text file.
17
+ const ALLOWLIST_FILE_NAME: &str = "allowlist.txt";
18
+ /// The constant holding the name of the BlockList text file.
19
+ const BLOCKLIST_FILE_NAME: &str = "blocklist.txt";
20
+
21
+ /// An enum type which provides different variants to handle paths for various files/folders.
22
+ #[derive(Hash, PartialEq, Eq, Debug)]
23
+ pub enum FileType {
24
+ /// This variant handles all the paths associated with the config file.
25
+ Config,
26
+ /// This variant handles all the paths associated with the Allowlist text file.
27
+ AllowList,
28
+ /// This variant handles all the paths associated with the BlockList text file.
29
+ BlockList,
30
+ /// This variant handles all the paths associated with the public folder (Theme folder).
31
+ Theme,
32
+ }
33
+
34
+ /// A static variable which stores the different filesystem paths for various file/folder types.
35
+ static FILE_PATHS_FOR_DIFF_FILE_TYPES: OnceLock<HashMap<FileType, Vec<String>>> = OnceLock::new();
36
+
37
+ /// A function which returns an appropriate path for thr provided file type by checking if the path
38
+ /// for the given file type exists on that path.
39
+ ///
40
+ /// # Error
41
+ ///
42
+ /// Returns a `<File Name> folder/file not found!!` error if the give file_type folder/file is not
43
+ /// present on the path on which it is being tested.
44
+ ///
45
+ /// # Example
46
+ ///
47
+ /// If this function is give the file_type of Theme variant then the theme folder is checked by the
48
+ /// following steps:
49
+ ///
50
+ /// 1. `/opt/websurfx` if it not present here then it fallbacks to the next one (2)
51
+ /// 2. Under project folder ( or codebase in other words) if it is not present
52
+ /// here then it returns an error as mentioned above.
53
+ pub fn file_path(file_type: FileType) -> Result<&'static str, Error> {
54
+ let home = env!("HOME");
55
+
56
+ let file_path: &Vec<String> = FILE_PATHS_FOR_DIFF_FILE_TYPES
57
+ .get_or_init(|| {
58
+ HashMap::from([
59
+ (
60
+ FileType::Config,
61
+ vec![
62
+ format!(
63
+ "{}/.config/{}/{}",
64
+ home, COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME
65
+ ),
66
+ format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
67
+ format!("./{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
68
+ ],
69
+ ),
70
+ (
71
+ FileType::Theme,
72
+ vec![
73
+ format!("/opt/websurfx/{}/", PUBLIC_DIRECTORY_NAME),
74
+ format!("./{}/", PUBLIC_DIRECTORY_NAME),
75
+ ],
76
+ ),
77
+ (
78
+ FileType::AllowList,
79
+ vec![
80
+ format!(
81
+ "{}/.config/{}/{}",
82
+ home, COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME
83
+ ),
84
+ format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
85
+ format!("./{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
86
+ ],
87
+ ),
88
+ (
89
+ FileType::BlockList,
90
+ vec![
91
+ format!(
92
+ "{}/.config/{}/{}",
93
+ home, COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME
94
+ ),
95
+ format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
96
+ format!("./{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
97
+ ],
98
+ ),
99
+ ])
100
+ })
101
+ .get(&file_type)
102
+ .unwrap();
103
+
104
+ for path in file_path.iter() {
105
+ if Path::new(path).exists() {
106
+ return Ok(path);
107
+ }
108
+ }
109
+
110
+ // if no of the configs above exist, return error
111
+ Err(Error::new(
112
+ std::io::ErrorKind::NotFound,
113
+ format!("{:?} file/folder not found!!", file_type),
114
+ ))
115
+ }
src/handler/paths.rs DELETED
@@ -1,119 +0,0 @@
1
- //! This module provides the functionality to handle theme folder present on different paths and
2
- //! provide one appropriate path on which it is present and can be used.
3
-
4
- use std::collections::HashMap;
5
- use std::io::Error;
6
- use std::path::Path;
7
- use std::sync::OnceLock;
8
-
9
- // ------- Constants --------
10
- /// The constant holding the name of the theme folder.
11
- const PUBLIC_DIRECTORY_NAME: &str = "public";
12
- /// The constant holding the name of the common folder.
13
- const COMMON_DIRECTORY_NAME: &str = "websurfx";
14
- /// The constant holding the name of the config file.
15
- const CONFIG_FILE_NAME: &str = "config.lua";
16
- /// The constant holding the name of the AllowList text file.
17
- const ALLOWLIST_FILE_NAME: &str = "allowlist.txt";
18
- /// The constant holding the name of the BlockList text file.
19
- const BLOCKLIST_FILE_NAME: &str = "blocklist.txt";
20
-
21
- /// An enum type which provides different variants to handle paths for various files/folders.
22
- #[derive(Hash, PartialEq, Eq, Debug)]
23
- pub enum FileType {
24
- /// This variant handles all the paths associated with the config file.
25
- Config,
26
- /// This variant handles all the paths associated with the Allowlist text file.
27
- AllowList,
28
- /// This variant handles all the paths associated with the BlockList text file.
29
- BlockList,
30
- /// This variant handles all the paths associated with the public folder (Theme folder).
31
- Theme,
32
- }
33
-
34
- /// A static variable which stores the different filesystem paths for various file/folder types.
35
- static FILE_PATHS_FOR_DIFF_FILE_TYPES: OnceLock<HashMap<FileType, Vec<String>>> = OnceLock::new();
36
-
37
- /// A function which returns an appropriate path for thr provided file type by checking if the path
38
- /// for the given file type exists on that path.
39
- ///
40
- /// # Error
41
- ///
42
- /// Returns a `<File Name> folder/file not found!!` error if the give file_type folder/file is not
43
- /// present on the path on which it is being tested.
44
- ///
45
- /// # Example
46
- ///
47
- /// If this function is give the file_type of Theme variant then the theme folder is checked by the
48
- /// following steps:
49
- ///
50
- /// 1. `/opt/websurfx` if it not present here then it fallbacks to the next one (2)
51
- /// 2. Under project folder ( or codebase in other words) if it is not present
52
- /// here then it returns an error as mentioned above.
53
- pub fn file_path(file_type: FileType) -> Result<&'static str, Error> {
54
- let file_path: &Vec<String> = FILE_PATHS_FOR_DIFF_FILE_TYPES
55
- .get_or_init(|| {
56
- HashMap::from([
57
- (
58
- FileType::Config,
59
- vec![
60
- format!(
61
- "{}/.config/{}/{}",
62
- std::env::var("HOME").unwrap(),
63
- COMMON_DIRECTORY_NAME,
64
- CONFIG_FILE_NAME
65
- ),
66
- format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
67
- format!("./{}/{}", COMMON_DIRECTORY_NAME, CONFIG_FILE_NAME),
68
- ],
69
- ),
70
- (
71
- FileType::Theme,
72
- vec![
73
- format!("/opt/websurfx/{}/", PUBLIC_DIRECTORY_NAME),
74
- format!("./{}/", PUBLIC_DIRECTORY_NAME),
75
- ],
76
- ),
77
- (
78
- FileType::AllowList,
79
- vec![
80
- format!(
81
- "{}/.config/{}/{}",
82
- std::env::var("HOME").unwrap(),
83
- COMMON_DIRECTORY_NAME,
84
- ALLOWLIST_FILE_NAME
85
- ),
86
- format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
87
- format!("./{}/{}", COMMON_DIRECTORY_NAME, ALLOWLIST_FILE_NAME),
88
- ],
89
- ),
90
- (
91
- FileType::BlockList,
92
- vec![
93
- format!(
94
- "{}/.config/{}/{}",
95
- std::env::var("HOME").unwrap(),
96
- COMMON_DIRECTORY_NAME,
97
- BLOCKLIST_FILE_NAME
98
- ),
99
- format!("/etc/xdg/{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
100
- format!("./{}/{}", COMMON_DIRECTORY_NAME, BLOCKLIST_FILE_NAME),
101
- ],
102
- ),
103
- ])
104
- })
105
- .get(&file_type)
106
- .unwrap();
107
-
108
- for (idx, _) in file_path.iter().enumerate() {
109
- if Path::new(file_path[idx].as_str()).exists() {
110
- return Ok(std::mem::take(&mut &*file_path[idx]));
111
- }
112
- }
113
-
114
- // if no of the configs above exist, return error
115
- Err(Error::new(
116
- std::io::ErrorKind::NotFound,
117
- format!("{:?} file/folder not found!!", file_type),
118
- ))
119
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib.rs CHANGED
@@ -24,7 +24,7 @@ use actix_governor::{Governor, GovernorConfigBuilder};
24
  use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer};
25
  use cache::cacher::{Cache, SharedCache};
26
  use config::parser::Config;
27
- use handler::paths::{file_path, FileType};
28
 
29
  /// Runs the web server on the provided TCP listener and returns a `Server` instance.
30
  ///
 
24
  use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer};
25
  use cache::cacher::{Cache, SharedCache};
26
  use config::parser::Config;
27
+ use handler::{file_path, FileType};
28
 
29
  /// Runs the web server on the provided TCP listener and returns a `Server` instance.
30
  ///
src/results/aggregator.rs CHANGED
@@ -2,7 +2,7 @@
2
  //! search engines and then removes duplicate results.
3
 
4
  use super::user_agent::random_user_agent;
5
- use crate::handler::paths::{file_path, FileType};
6
  use crate::models::{
7
  aggregation_models::{EngineErrorInfo, SearchResult, SearchResults},
8
  engine_models::{EngineError, EngineHandler},
 
2
  //! search engines and then removes duplicate results.
3
 
4
  use super::user_agent::random_user_agent;
5
+ use crate::handler::{file_path, FileType};
6
  use crate::models::{
7
  aggregation_models::{EngineErrorInfo, SearchResult, SearchResults},
8
  engine_models::{EngineError, EngineHandler},
src/server/router.rs CHANGED
@@ -4,7 +4,7 @@
4
 
5
  use crate::{
6
  config::parser::Config,
7
- handler::paths::{file_path, FileType},
8
  };
9
  use actix_web::{get, web, HttpRequest, HttpResponse};
10
  use std::fs::read_to_string;
 
4
 
5
  use crate::{
6
  config::parser::Config,
7
+ handler::{file_path, FileType},
8
  };
9
  use actix_web::{get, web, HttpRequest, HttpResponse};
10
  use std::fs::read_to_string;
src/server/routes/search.rs CHANGED
@@ -3,7 +3,7 @@
3
  use crate::{
4
  cache::cacher::SharedCache,
5
  config::parser::Config,
6
- handler::paths::{file_path, FileType},
7
  models::{
8
  aggregation_models::SearchResults,
9
  engine_models::{EngineError, EngineHandler},
@@ -47,54 +47,25 @@ pub async fn search(
47
  .insert_header(("location", "/"))
48
  .finish());
49
  }
50
- let page = match &params.page {
51
- Some(page) => *page,
52
- None => 1,
53
- };
54
 
55
- let (_, results, _) = join!(
56
- results(
57
- format!(
58
- "http://{}:{}/search?q={}&page={}&safesearch=",
59
- config.binding_ip,
60
- config.port,
61
- query,
62
- page - 1,
63
- ),
64
- &config,
65
- &cache,
66
- query,
67
- page - 1,
68
- req.clone(),
69
- &params.safesearch
70
- ),
71
  results(
72
- format!(
73
- "http://{}:{}/search?q={}&page={}&safesearch=",
74
- config.binding_ip, config.port, query, page
75
- ),
76
  &config,
77
  &cache,
78
  query,
79
  page,
80
  req.clone(),
81
- &params.safesearch
82
- ),
83
- results(
84
- format!(
85
- "http://{}:{}/search?q={}&page={}&safesearch=",
86
- config.binding_ip,
87
- config.port,
88
- query,
89
- page + 1,
90
- ),
91
- &config,
92
- &cache,
93
- query,
94
- page + 1,
95
- req.clone(),
96
- &params.safesearch
97
  )
 
 
 
 
 
 
 
 
 
98
  );
99
 
100
  Ok(HttpResponse::Ok().body(
@@ -129,7 +100,6 @@ pub async fn search(
129
  /// It returns the `SearchResults` struct if the search results could be successfully fetched from
130
  /// the cache or from the upstream search engines otherwise it returns an appropriate error.
131
  async fn results(
132
- url: String,
133
  config: &Config,
134
  cache: &web::Data<SharedCache>,
135
  query: &str,
@@ -137,6 +107,14 @@ async fn results(
137
  req: HttpRequest,
138
  safe_search: &Option<u8>,
139
  ) -> Result<SearchResults, Box<dyn std::error::Error>> {
 
 
 
 
 
 
 
 
140
  // fetch the cached results json.
141
  let cached_results = cache.cached_json(&url).await;
142
  // check if fetched cache results was indeed fetched or it was an error and if so
@@ -157,11 +135,11 @@ async fn results(
157
 
158
  if safe_search_level == 4 {
159
  let mut results: SearchResults = SearchResults::default();
160
- let mut _flag: bool =
161
- is_match_from_filter_list(file_path(FileType::BlockList)?, query)?;
162
- _flag = !is_match_from_filter_list(file_path(FileType::AllowList)?, query)?;
163
 
164
- if _flag {
 
 
 
165
  results.set_disallowed();
166
  cache.cache_results(&results, &url).await?;
167
  results.set_safe_search_level(safe_search_level);
@@ -264,14 +242,13 @@ fn is_match_from_filter_list(
264
  file_path: &str,
265
  query: &str,
266
  ) -> Result<bool, Box<dyn std::error::Error>> {
267
- let mut flag = false;
268
  let mut reader = BufReader::new(File::open(file_path)?);
269
  for line in reader.by_ref().lines() {
270
  let re = Regex::new(&line?)?;
271
  if re.is_match(query) {
272
- flag = true;
273
- break;
274
  }
275
  }
276
- Ok(flag)
 
277
  }
 
3
  use crate::{
4
  cache::cacher::SharedCache,
5
  config::parser::Config,
6
+ handler::{file_path, FileType},
7
  models::{
8
  aggregation_models::SearchResults,
9
  engine_models::{EngineError, EngineHandler},
 
47
  .insert_header(("location", "/"))
48
  .finish());
49
  }
 
 
 
 
50
 
51
+ let get_results = |page| {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  results(
 
 
 
 
53
  &config,
54
  &cache,
55
  query,
56
  page,
57
  req.clone(),
58
+ &params.safesearch,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  )
60
+ };
61
+
62
+ // .max(1) makes sure that the page > 0.
63
+ let page = params.page.unwrap_or(1).max(1);
64
+
65
+ let (_, results, _) = join!(
66
+ get_results(page - 1),
67
+ get_results(page),
68
+ get_results(page + 1)
69
  );
70
 
71
  Ok(HttpResponse::Ok().body(
 
100
  /// It returns the `SearchResults` struct if the search results could be successfully fetched from
101
  /// the cache or from the upstream search engines otherwise it returns an appropriate error.
102
  async fn results(
 
103
  config: &Config,
104
  cache: &web::Data<SharedCache>,
105
  query: &str,
 
107
  req: HttpRequest,
108
  safe_search: &Option<u8>,
109
  ) -> Result<SearchResults, Box<dyn std::error::Error>> {
110
+ let url = format!(
111
+ "http://{}:{}/search?q={}&page={}&safesearch=",
112
+ config.binding_ip,
113
+ config.port,
114
+ query,
115
+ page - 1,
116
+ );
117
+
118
  // fetch the cached results json.
119
  let cached_results = cache.cached_json(&url).await;
120
  // check if fetched cache results was indeed fetched or it was an error and if so
 
135
 
136
  if safe_search_level == 4 {
137
  let mut results: SearchResults = SearchResults::default();
 
 
 
138
 
139
+ let flag: bool =
140
+ !is_match_from_filter_list(file_path(FileType::BlockList)?, query)?;
141
+
142
+ if flag {
143
  results.set_disallowed();
144
  cache.cache_results(&results, &url).await?;
145
  results.set_safe_search_level(safe_search_level);
 
242
  file_path: &str,
243
  query: &str,
244
  ) -> Result<bool, Box<dyn std::error::Error>> {
 
245
  let mut reader = BufReader::new(File::open(file_path)?);
246
  for line in reader.by_ref().lines() {
247
  let re = Regex::new(&line?)?;
248
  if re.is_match(query) {
249
+ return Ok(true);
 
250
  }
251
  }
252
+
253
+ Ok(false)
254
  }
src/templates/partials/settings_tabs/user_interface.rs CHANGED
@@ -1,6 +1,6 @@
1
  //! A module that handles the user interface tab for setting page view in the `websurfx` frontend.
2
 
3
- use crate::handler::paths::{file_path, FileType};
4
  use maud::{html, Markup};
5
  use std::fs::read_dir;
6
 
 
1
  //! A module that handles the user interface tab for setting page view in the `websurfx` frontend.
2
 
3
+ use crate::handler::{file_path, FileType};
4
  use maud::{html, Markup};
5
  use std::fs::read_dir;
6
 
src/templates/views/search.rs CHANGED
@@ -93,7 +93,7 @@ pub fn search(
93
  img src="./images/no_selection.png" alt="Image of a white cross inside a red circle";
94
  }
95
  }
96
- @else{
97
  .result_not_found {
98
  p{"Your search - "{(query)}" - did not match any documents."}
99
  p class="suggestions"{"Suggestions:"}
 
93
  img src="./images/no_selection.png" alt="Image of a white cross inside a red circle";
94
  }
95
  }
96
+ @else {
97
  .result_not_found {
98
  p{"Your search - "{(query)}" - did not match any documents."}
99
  p class="suggestions"{"Suggestions:"}