alamin655 commited on
Commit
017036e
β€’
2 Parent(s): de91f76 5c9559b

Merge branch 'rolling' into feat-inform-user-when-no-engines-are-selected

Browse files
README.md CHANGED
@@ -4,6 +4,7 @@
4
  <p align="center">
5
  <b align="center"><a href="README.md">Readme</a></b> |
6
  <b><a href="https://discord.gg/SWnda7Mw5u">Discord</a></b> |
 
7
  <b><a href="https://github.com/neon-mmd/websurfx">GitHub</a></b> |
8
  <b><a href="../../tree/HEAD/docs/">Documentation</a></b>
9
  <br /><br />
@@ -57,28 +58,19 @@
57
  <p>
58
 
59
  - **Getting Started**
60
- - [πŸ”­ Preview](#preview-)
61
- - [πŸš€ Features](#features-)
62
- - [πŸ› οΈ Installation and Testing](#installation-and-testing-%EF%B8%8F)
63
- - [πŸ”§ Configuration](#configuration-)
64
  - **Feature Overview**
65
- - [🎨 Theming](#theming-)
66
- - [🌍 Multi-Language Support](#multi-language-support-)
67
- - **Community**
68
- - [πŸ“Š System Requirements](#system-requirements-)
69
- - [πŸ—¨οΈ FAQ (Frequently Asked Questions)](#faq-frequently-asked-questions-)
70
- - [πŸ“£ More Contributors Wanted](#more-contributors-wanted-)
71
- - [πŸ’– Supporting Websurfx](#supporting-websurfx-)
72
- - [πŸ“˜ Documentation](#documentation-)
73
- - [πŸ›£οΈ Roadmap](#roadmap-)
74
- - [πŸ™‹ Contributing](#contributing-)
75
- - [πŸ“œ License](#license-)
76
- - [🀝 Credits](#credits-)
77
 
78
  </p>
79
  </details>
80
 
81
- # Preview πŸ”­
82
 
83
  ## Home Page
84
 
@@ -94,7 +86,7 @@
94
 
95
  **[⬆️ Back to Top](#--)**
96
 
97
- # Features πŸš€
98
 
99
  - 🎨 Make Websurfx uniquely yours with twelve color schemes provided by default. It also supports creation of custom themes and color schemes in a quick and easy way, so unleash your creativity!
100
  - πŸ” Fast, private, and secure
@@ -104,7 +96,7 @@
104
 
105
  **[⬆️ Back to Top](#--)**
106
 
107
- # Installation and Testing πŸ› οΈ
108
 
109
  > For full setup instructions, see: [**Installation**](./docs/installation.md)
110
 
@@ -112,7 +104,7 @@ Before you can start building `websurfx`, you will need to have `Cargo` installe
112
 
113
  To get started with Websurfx, clone the repository, edit the config file, which is located in the `websurfx/` directory, and install the Redis server by following the instructions located [here](https://redis.io/docs/getting-started/) and then run the websurfx server and redis server using the following commands:
114
 
115
- ``` shell
116
  git clone https://github.com/neon-mmd/websurfx.git
117
  cd websurfx
118
  git checkout stable
@@ -128,7 +120,7 @@ Once you have started the server, open your preferred web browser and navigate t
128
 
129
  **[⬆️ Back to Top](#--)**
130
 
131
- # Configuration πŸ”§
132
 
133
  > For full configuration instructions, see: [**Configuration**](./docs/configuration.md)
134
 
@@ -136,7 +128,7 @@ Websurfx is configured through the config.lua file, located at `websurfx/config.
136
 
137
  **[⬆️ Back to Top](#--)**
138
 
139
- # Theming 🎨
140
 
141
  > For full theming and customization instructions, see: [**Theming**](./docs/theming.md)
142
 
@@ -173,7 +165,7 @@ Websurfx is based on Rust due to its memory safety features, which prevents vuln
173
 
174
  **[⬆️ Back to Top](#--)**
175
 
176
- # More Contributors Wanted πŸ“£
177
 
178
  We are looking for more willing contributors to help grow this project. For more information on how you can contribute, check out the [project board](https://github.com/neon-mmd/websurfx/projects?query=is%3Aopen) and the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines and rules for making contributions.
179
 
@@ -186,6 +178,7 @@ We are looking for more willing contributors to help grow this project. For more
186
  If you use Websurfx and would like to contribute to its development, we're glad to have you on board! Contributions of any size or type are always welcome, and we will always acknowledge your efforts.
187
 
188
  Several areas that we need a bit of help with at the moment are:
 
189
  - **Better and more color schemes**: Help fix color schemes and add other famous color schemes.
190
  - **Improve evasion code for bot detection** - Help improve code related to evading IP blocking and emulating human behaviors located in everyone's engine file.
191
  - **Logo** - Help create a logo for the project and website.
@@ -198,7 +191,7 @@ Several areas that we need a bit of help with at the moment are:
198
  # Documentation πŸ“˜
199
 
200
  > **Note**
201
- > We welcome any contributions to the [documentation](../../tree/HEAD/docs/) as this will benefit everyone who uses this project.
202
 
203
  **[⬆️ Back to Top](#--)**
204
 
@@ -208,7 +201,7 @@ Several areas that we need a bit of help with at the moment are:
208
 
209
  **[⬆️ Back to Top](#--)**
210
 
211
- # Contributing πŸ™‹
212
 
213
  Contributions are welcome from anyone. It doesn't matter who you are; you can still contribute to the project in your own way.
214
 
@@ -222,13 +215,13 @@ If you are a developer, have a look at the [CONTRIBUTING.org](CONTRIBUTING.md) d
222
 
223
  **[⬆️ Back to Top](#--)**
224
 
225
- # License πŸ“œ
226
 
227
  Websurfx is licensed under the [AGPLv3](LICENSE) license.
228
 
229
  **[⬆️ Back to Top](#--)**
230
 
231
- # Credits 🀝
232
 
233
  We would like to thank the following people for their contributions and support:
234
 
 
4
  <p align="center">
5
  <b align="center"><a href="README.md">Readme</a></b> |
6
  <b><a href="https://discord.gg/SWnda7Mw5u">Discord</a></b> |
7
+ <b><a href="https://discord.gg/VKCAememnr">User Showcase</a></b> |
8
  <b><a href="https://github.com/neon-mmd/websurfx">GitHub</a></b> |
9
  <b><a href="../../tree/HEAD/docs/">Documentation</a></b>
10
  <br /><br />
 
58
  <p>
59
 
60
  - **Getting Started**
61
+ - [πŸ”­ Preview](#preview-)
62
+ - [πŸš€ Features](#features-)
63
+ - [πŸ› οΈ Installation and Testing](#installation-and-testing-%EF%B8%8F)
64
+ - [πŸ”§ Configuration](#configuration-)
65
  - **Feature Overview**
66
+ - [🎨 Theming](#theming-)
67
+ - [🌍 Multi-Language Support](#multi-language-support-)
68
+ - **Community** - [πŸ“Š System Requirements](#system-requirements-) - [πŸ—¨οΈ FAQ (Frequently Asked Questions)](#faq-frequently-asked-questions-) - [πŸ“£ More Contributors Wanted](#more-contributors-wanted-) - [πŸ’– Supporting Websurfx](#supporting-websurfx-) - [πŸ“˜ Documentation](#documentation-) - [πŸ›£οΈ Roadmap](#roadmap-) - [πŸ™‹ Contributing](#contributing-) - [πŸ“œ License](#license-) - [🀝 Credits](#credits-)
 
 
 
 
 
 
 
 
 
69
 
70
  </p>
71
  </details>
72
 
73
+ # Preview πŸ”­
74
 
75
  ## Home Page
76
 
 
86
 
87
  **[⬆️ Back to Top](#--)**
88
 
89
+ # Features πŸš€
90
 
91
  - 🎨 Make Websurfx uniquely yours with twelve color schemes provided by default. It also supports creation of custom themes and color schemes in a quick and easy way, so unleash your creativity!
92
  - πŸ” Fast, private, and secure
 
96
 
97
  **[⬆️ Back to Top](#--)**
98
 
99
+ # Installation and Testing πŸ› οΈ
100
 
101
  > For full setup instructions, see: [**Installation**](./docs/installation.md)
102
 
 
104
 
105
  To get started with Websurfx, clone the repository, edit the config file, which is located in the `websurfx/` directory, and install the Redis server by following the instructions located [here](https://redis.io/docs/getting-started/) and then run the websurfx server and redis server using the following commands:
106
 
107
+ ```shell
108
  git clone https://github.com/neon-mmd/websurfx.git
109
  cd websurfx
110
  git checkout stable
 
120
 
121
  **[⬆️ Back to Top](#--)**
122
 
123
+ # Configuration πŸ”§
124
 
125
  > For full configuration instructions, see: [**Configuration**](./docs/configuration.md)
126
 
 
128
 
129
  **[⬆️ Back to Top](#--)**
130
 
131
+ # Theming 🎨
132
 
133
  > For full theming and customization instructions, see: [**Theming**](./docs/theming.md)
134
 
 
165
 
166
  **[⬆️ Back to Top](#--)**
167
 
168
+ # More Contributors Wanted πŸ“£
169
 
170
  We are looking for more willing contributors to help grow this project. For more information on how you can contribute, check out the [project board](https://github.com/neon-mmd/websurfx/projects?query=is%3Aopen) and the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines and rules for making contributions.
171
 
 
178
  If you use Websurfx and would like to contribute to its development, we're glad to have you on board! Contributions of any size or type are always welcome, and we will always acknowledge your efforts.
179
 
180
  Several areas that we need a bit of help with at the moment are:
181
+
182
  - **Better and more color schemes**: Help fix color schemes and add other famous color schemes.
183
  - **Improve evasion code for bot detection** - Help improve code related to evading IP blocking and emulating human behaviors located in everyone's engine file.
184
  - **Logo** - Help create a logo for the project and website.
 
191
  # Documentation πŸ“˜
192
 
193
  > **Note**
194
+ > We welcome any contributions to the [documentation](../../tree/HEAD/docs/) as this will benefit everyone who uses this project.
195
 
196
  **[⬆️ Back to Top](#--)**
197
 
 
201
 
202
  **[⬆️ Back to Top](#--)**
203
 
204
+ # Contributing πŸ™‹
205
 
206
  Contributions are welcome from anyone. It doesn't matter who you are; you can still contribute to the project in your own way.
207
 
 
215
 
216
  **[⬆️ Back to Top](#--)**
217
 
218
+ # License πŸ“œ
219
 
220
  Websurfx is licensed under the [AGPLv3](LICENSE) license.
221
 
222
  **[⬆️ Back to Top](#--)**
223
 
224
+ # Credits 🀝
225
 
226
  We would like to thank the following people for their contributions and support:
227
 
public/static/cookies.js CHANGED
@@ -16,8 +16,9 @@ document.addEventListener(
16
  let cookie = decodeURIComponent(document.cookie)
17
  // Set the value of the input field to the decoded cookie value if it is not empty
18
  // Otherwise, display a message indicating that no cookies have been saved on the user's system
19
- document.querySelector('.cookies input').value =
20
- cookie !== '' ? cookie : 'No cookies have been saved on your system'
 
21
  } catch (error) {
22
  // If there is an error decoding the cookie, log the error to the console
23
  // and display an error message in the input field
@@ -25,5 +26,5 @@ document.addEventListener(
25
  document.querySelector('.cookies input').value = 'Error decoding cookie'
26
  }
27
  },
28
- false
29
  )
 
16
  let cookie = decodeURIComponent(document.cookie)
17
  // Set the value of the input field to the decoded cookie value if it is not empty
18
  // Otherwise, display a message indicating that no cookies have been saved on the user's system
19
+ document.querySelector('.cookies input').value = cookie.length
20
+ ? cookie
21
+ : 'No cookies have been saved on your system'
22
  } catch (error) {
23
  // If there is an error decoding the cookie, log the error to the console
24
  // and display an error message in the input field
 
26
  document.querySelector('.cookies input').value = 'Error decoding cookie'
27
  }
28
  },
29
+ false,
30
  )
public/static/index.js CHANGED
@@ -2,16 +2,25 @@
2
  * Selects the input element for the search box
3
  * @type {HTMLInputElement}
4
  */
5
- const searchBox = document.querySelector('input');
6
 
7
  /**
8
  * Redirects the user to the search results page with the query parameter
9
  */
10
  function searchWeb() {
11
- const query = searchBox.value.trim();
12
- if (query) {
13
- window.location.href = `search?q=${encodeURIComponent(query)}`;
14
- }
 
 
 
 
 
 
 
 
 
15
  }
16
 
17
  /**
@@ -19,7 +28,7 @@ function searchWeb() {
19
  * @param {KeyboardEvent} e - The keyboard event object
20
  */
21
  searchBox.addEventListener('keyup', (e) => {
22
- if (e.key === 'Enter') {
23
- searchWeb();
24
- }
25
- });
 
2
  * Selects the input element for the search box
3
  * @type {HTMLInputElement}
4
  */
5
+ const searchBox = document.querySelector('input')
6
 
7
  /**
8
  * Redirects the user to the search results page with the query parameter
9
  */
10
  function searchWeb() {
11
+ const query = searchBox.value.trim()
12
+ try {
13
+ let safeSearchLevel = document.querySelector('.search_options select').value
14
+ if (query) {
15
+ window.location.href = `search?q=${encodeURIComponent(
16
+ query,
17
+ )}&safesearch=${encodeURIComponent(safeSearchLevel)}`
18
+ }
19
+ } catch (error) {
20
+ if (query) {
21
+ window.location.href = `search?q=${encodeURIComponent(query)}`
22
+ }
23
+ }
24
  }
25
 
26
  /**
 
28
  * @param {KeyboardEvent} e - The keyboard event object
29
  */
30
  searchBox.addEventListener('keyup', (e) => {
31
+ if (e.key === 'Enter') {
32
+ searchWeb()
33
+ }
34
+ })
public/static/pagination.js CHANGED
@@ -3,8 +3,8 @@
3
  * @returns {void}
4
  */
5
  function navigate_forward() {
6
- const url = new URL(window.location);
7
- const searchParams = url.searchParams;
8
 
9
  let q = searchParams.get('q');
10
  let page = parseInt(searchParams.get('page'));
@@ -23,8 +23,8 @@ function navigate_forward() {
23
  * @returns {void}
24
  */
25
  function navigate_backward() {
26
- const url = new URL(window.location);
27
- const searchParams = url.searchParams;
28
 
29
  let q = searchParams.get('q');
30
  let page = parseInt(searchParams.get('page'));
 
3
  * @returns {void}
4
  */
5
  function navigate_forward() {
6
+ let url = new URL(window.location);
7
+ let searchParams = url.searchParams;
8
 
9
  let q = searchParams.get('q');
10
  let page = parseInt(searchParams.get('page'));
 
23
  * @returns {void}
24
  */
25
  function navigate_backward() {
26
+ let url = new URL(window.location);
27
+ let searchParams = url.searchParams;
28
 
29
  let q = searchParams.get('q');
30
  let page = parseInt(searchParams.get('page'));
public/static/search_area_options.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener(
2
+ 'DOMContentLoaded',
3
+ () => {
4
+ let url = new URL(window.location)
5
+ let searchParams = url.searchParams
6
+
7
+ let safeSearchLevel = searchParams.get('safesearch')
8
+
9
+ if (
10
+ safeSearchLevel >= 0 &&
11
+ safeSearchLevel <= 2 &&
12
+ safeSearchLevel !== null
13
+ ) {
14
+ document.querySelector('.search_options select').value = safeSearchLevel
15
+ }
16
+ },
17
+ false,
18
+ )
public/static/settings.js CHANGED
@@ -1,5 +1,5 @@
1
  /**
2
- * This function handles the toggling of selections of all upstream search engines
3
  * options in the settings page under the tab engines.
4
  */
5
  function toggleAllSelection() {
@@ -8,12 +8,12 @@ function toggleAllSelection() {
8
  .forEach(
9
  (engine_checkbox) =>
10
  (engine_checkbox.checked =
11
- document.querySelector('.select_all').checked)
12
  )
13
  }
14
 
15
  /**
16
- * This function adds the functionality to sidebar buttons to only show settings
17
  * related to that tab.
18
  * @param {HTMLElement} current_tab - The current tab that was clicked.
19
  */
@@ -43,20 +43,28 @@ function setClientSettings() {
43
 
44
  // Loop through all select tags and add their values to the cookie dictionary
45
  document.querySelectorAll('select').forEach((select_tag) => {
46
- if (select_tag.name === 'themes') {
47
- cookie_dictionary['theme'] = select_tag.value
48
- } else if (select_tag.name === 'colorschemes') {
49
- cookie_dictionary['colorscheme'] = select_tag.value
 
 
 
 
 
 
50
  }
51
  })
52
 
53
  // Loop through all engine checkboxes and add their values to the cookie dictionary
54
  let engines = []
 
55
  document.querySelectorAll('.engine').forEach((engine_checkbox) => {
56
- if (engine_checkbox.checked === true) {
57
  engines.push(engine_checkbox.parentNode.parentNode.innerText.trim())
58
  }
59
  })
 
60
  cookie_dictionary['engines'] = engines
61
 
62
  // Set the expiration date for the cookie to 1 year from the current date
@@ -65,7 +73,7 @@ function setClientSettings() {
65
 
66
  // Save the cookie to the user's machine
67
  document.cookie = `appCookie=${JSON.stringify(
68
- cookie_dictionary
69
  )}; expires=${expiration_date.toUTCString()}`
70
 
71
  // Display a success message to the user
@@ -79,9 +87,9 @@ function setClientSettings() {
79
  }
80
 
81
  /**
82
- * This functions gets the saved cookies if it is present on the user's machine If it
83
- * is available then it is parsed and converted to an object which is then used to
84
- * retrieve the preferences that the user had selected previously and is then loaded in the
85
  * website otherwise the function does nothing and the default server side settings are loaded.
86
  */
87
  function getClientSettings() {
@@ -89,21 +97,19 @@ function getClientSettings() {
89
  let cookie = decodeURIComponent(document.cookie)
90
 
91
  // If the cookie is not empty, parse it and use it to set the user's preferences
92
- if (cookie !== '') {
93
- let cookie_value = decodeURIComponent(document.cookie)
94
  .split(';')
95
  .map((item) => item.split('='))
96
  .reduce((acc, [_, v]) => (acc = JSON.parse(v)) && acc, {})
97
 
98
  // Loop through all link tags and update their href values to match the user's preferences
99
- let links = Array.from(document.querySelectorAll('link')).forEach(
100
- (item) => {
101
- if (item.href.includes('static/themes')) {
102
- item.href = `static/themes/${cookie_value['theme']}.css`
103
- } else if (item.href.includes('static/colorschemes')) {
104
- item.href = `static/colorschemes/${cookie_value['colorscheme']}.css`
105
- }
106
  }
107
- )
108
  }
109
  }
 
1
  /**
2
+ * This function handles the toggling of selections of all upstream search engines
3
  * options in the settings page under the tab engines.
4
  */
5
  function toggleAllSelection() {
 
8
  .forEach(
9
  (engine_checkbox) =>
10
  (engine_checkbox.checked =
11
+ document.querySelector('.select_all').checked),
12
  )
13
  }
14
 
15
  /**
16
+ * This function adds the functionality to sidebar buttons to only show settings
17
  * related to that tab.
18
  * @param {HTMLElement} current_tab - The current tab that was clicked.
19
  */
 
43
 
44
  // Loop through all select tags and add their values to the cookie dictionary
45
  document.querySelectorAll('select').forEach((select_tag) => {
46
+ switch (select_tag.name) {
47
+ case 'themes':
48
+ cookie_dictionary['theme'] = select_tag.value
49
+ break
50
+ case 'colorschemes':
51
+ cookie_dictionary['colorscheme'] = select_tag.value
52
+ break
53
+ case 'safe_search_levels':
54
+ cookie_dictionary['safe_search_level'] = Number(select_tag.value)
55
+ break
56
  }
57
  })
58
 
59
  // Loop through all engine checkboxes and add their values to the cookie dictionary
60
  let engines = []
61
+
62
  document.querySelectorAll('.engine').forEach((engine_checkbox) => {
63
+ if (engine_checkbox.checked) {
64
  engines.push(engine_checkbox.parentNode.parentNode.innerText.trim())
65
  }
66
  })
67
+
68
  cookie_dictionary['engines'] = engines
69
 
70
  // Set the expiration date for the cookie to 1 year from the current date
 
73
 
74
  // Save the cookie to the user's machine
75
  document.cookie = `appCookie=${JSON.stringify(
76
+ cookie_dictionary,
77
  )}; expires=${expiration_date.toUTCString()}`
78
 
79
  // Display a success message to the user
 
87
  }
88
 
89
  /**
90
+ * This functions gets the saved cookies if it is present on the user's machine If it
91
+ * is available then it is parsed and converted to an object which is then used to
92
+ * retrieve the preferences that the user had selected previously and is then loaded in the
93
  * website otherwise the function does nothing and the default server side settings are loaded.
94
  */
95
  function getClientSettings() {
 
97
  let cookie = decodeURIComponent(document.cookie)
98
 
99
  // If the cookie is not empty, parse it and use it to set the user's preferences
100
+ if (cookie.length) {
101
+ let cookie_value = cookie
102
  .split(';')
103
  .map((item) => item.split('='))
104
  .reduce((acc, [_, v]) => (acc = JSON.parse(v)) && acc, {})
105
 
106
  // Loop through all link tags and update their href values to match the user's preferences
107
+ Array.from(document.querySelectorAll('link')).forEach((item) => {
108
+ if (item.href.includes('static/themes')) {
109
+ item.href = `static/themes/${cookie_value['theme']}.css`
110
+ } else if (item.href.includes('static/colorschemes')) {
111
+ item.href = `static/colorschemes/${cookie_value['colorscheme']}.css`
 
 
112
  }
113
+ })
114
  }
115
  }
public/static/themes/simple.css CHANGED
@@ -70,6 +70,28 @@ body {
70
  filter: brightness(1.2);
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  .result_not_found {
74
  display: flex;
75
  flex-direction: column;
@@ -503,7 +525,8 @@ footer {
503
  color: var(--foreground-color);
504
  }
505
 
506
- .settings_container .user_interface select {
 
507
  margin: 0.7rem 0;
508
  width: 20rem;
509
  background-color: var(--background-color);
@@ -515,7 +538,8 @@ footer {
515
  text-transform: capitalize;
516
  }
517
 
518
- .settings_container .user_interface option:hover {
 
519
  background-color: var(--color-one);
520
  }
521
 
 
70
  filter: brightness(1.2);
71
  }
72
 
73
+ .search_area .search_options {
74
+ display: flex;
75
+ justify-content: space-between;
76
+ align-items: center;
77
+ }
78
+
79
+ .search_area .search_options select {
80
+ margin: 0.7rem 0;
81
+ width: 20rem;
82
+ background-color: var(--color-one);
83
+ color: var(--foreground-color);
84
+ padding: 1rem 2rem;
85
+ border-radius: 0.5rem;
86
+ outline: none;
87
+ border: none;
88
+ text-transform: capitalize;
89
+ }
90
+
91
+ .search_area .search_options option:hover {
92
+ background-color: var(--color-one);
93
+ }
94
+
95
  .result_not_found {
96
  display: flex;
97
  flex-direction: column;
 
525
  color: var(--foreground-color);
526
  }
527
 
528
+ .settings_container .user_interface select,
529
+ .settings_container .general select {
530
  margin: 0.7rem 0;
531
  width: 20rem;
532
  background-color: var(--background-color);
 
538
  text-transform: capitalize;
539
  }
540
 
541
+ .settings_container .user_interface option:hover,
542
+ .settings_container .general option:hover {
543
  background-color: var(--color-one);
544
  }
545
 
public/templates/engines_tab.html CHANGED
@@ -1,4 +1,5 @@
1
  <div class="engines tab">
 
2
  <h3>select search engines</h3>
3
  <p class="description">
4
  Select the search engines from the list of engines that you want results
 
1
  <div class="engines tab">
2
+ <h1>Engines</h1>
3
  <h3>select search engines</h3>
4
  <p class="description">
5
  Select the search engines from the list of engines that you want results
public/templates/general_tab.html CHANGED
@@ -1,4 +1,13 @@
1
  <div class="general tab active">
2
  <h1>General</h1>
3
- <p class="description">Coming soon!!</p>
 
 
 
 
 
 
 
 
 
4
  </div>
 
1
  <div class="general tab active">
2
  <h1>General</h1>
3
+ <h3>Select a safe search level</h3>
4
+ <p class="description">
5
+ Select a safe search level from the menu below to filter content based on
6
+ the level.
7
+ </p>
8
+ <select name="safe_search_levels">
9
+ <option value=0>None</option>
10
+ <option value=1>Low</option>
11
+ <option value=2>Moderate</option>
12
+ </select>
13
  </div>
public/templates/search.html CHANGED
@@ -80,6 +80,7 @@
80
  </div>
81
  </main>
82
  <script src="static/index.js"></script>
 
83
  <script src="static/pagination.js"></script>
84
  <script src="static/error_box.js"></script>
85
  {{>footer}}
 
80
  </div>
81
  </main>
82
  <script src="static/index.js"></script>
83
+ <script src="static/search_area_options.js"></script>
84
  <script src="static/pagination.js"></script>
85
  <script src="static/error_box.js"></script>
86
  {{>footer}}
public/templates/search_bar.html CHANGED
@@ -1,27 +1,36 @@
1
- {{>bar this}}
2
- <div class="error_box">
3
- {{#if engineErrorsInfo}}
4
- <button onclick="toggleErrorBox()" class="error_box_toggle_button">
5
- <img src="./images/warning.svg" alt="Info icon for error box" />
6
- </button>
7
- <div class="dropdown_error_box">
8
- {{#each engineErrorsInfo}}
9
- <div class="error_item">
10
- <span class="engine_name">{{{this.engine}}}</span>
11
- <span class="engine_name">{{{this.error}}}</span>
12
- <span class="severity_color" style="background: {{{this.severity_color}}};"></span>
 
 
 
13
  </div>
14
- {{/each}}
15
- </div>
16
- {{else}}
17
- <button onclick="toggleErrorBox()" class="error_box_toggle_button">
18
- <img src="./images/info.svg" alt="Warning icon for error box" />
19
- </button>
20
- <div class="dropdown_error_box">
21
- <div class="no_errors">
22
- Everything looks good πŸ™‚!!
23
  </div>
 
24
  </div>
25
- {{/if}}
 
 
 
 
 
 
26
  </div>
27
  </div>
 
1
+ <div class="search_area">
2
+ {{>bar this}}
3
+ <div class="error_box">
4
+ {{#if engineErrorsInfo}}
5
+ <button onclick="toggleErrorBox()" class="error_box_toggle_button">
6
+ <img src="./images/warning.svg" alt="Info icon for error box" />
7
+ </button>
8
+ <div class="dropdown_error_box">
9
+ {{#each engineErrorsInfo}}
10
+ <div class="error_item">
11
+ <span class="engine_name">{{{this.engine}}}</span>
12
+ <span class="engine_name">{{{this.error}}}</span>
13
+ <span class="severity_color" style="background: {{{this.severity_color}}};"></span>
14
+ </div>
15
+ {{/each}}
16
  </div>
17
+ {{else}}
18
+ <button onclick="toggleErrorBox()" class="error_box_toggle_button">
19
+ <img src="./images/info.svg" alt="Warning icon for error box" />
20
+ </button>
21
+ <div class="dropdown_error_box">
22
+ <div class="no_errors">
23
+ Everything looks good πŸ™‚!!
24
+ </div>
 
25
  </div>
26
+ {{/if}}
27
  </div>
28
+ </div>
29
+ <div class="search_options">
30
+ <select name="safe_search_levels" {{#if (gte safeSearchLevel 3)}} disabled {{/if}}>
31
+ <option value=0 {{#if (eq safeSearchLevel 0)}} selected {{/if}}>SafeSearch: None</option>
32
+ <option value=1 {{#if (eq safeSearchLevel 1)}} selected {{/if}}>SafeSearch: Low</option>
33
+ <option value=2 {{#if (eq safeSearchLevel 2)}} selected {{/if}}>SafeSearch: Moderate</option>
34
+ </select>
35
  </div>
36
  </div>
public/templates/user_interface_tab.html CHANGED
@@ -1,4 +1,5 @@
1
  <div class="user_interface tab">
 
2
  <h3>select theme</h3>
3
  <p class="description">
4
  Select the theme from the available themes to be used in user interface
 
1
  <div class="user_interface tab">
2
+ <h1>User Interface</h1>
3
  <h3>select theme</h3>
4
  <p class="description">
5
  Select the theme from the available themes to be used in user interface
src/models/server_models.rs CHANGED
@@ -26,4 +26,6 @@ pub struct Cookie<'a> {
26
  pub colorscheme: &'a str,
27
  /// It stores the user selected upstream search engines selected from the UI.
28
  pub engines: Vec<&'a str>,
 
 
29
  }
 
26
  pub colorscheme: &'a str,
27
  /// It stores the user selected upstream search engines selected from the UI.
28
  pub engines: Vec<&'a str>,
29
+ /// It stores the user selected safe search level from the UI.
30
+ pub safe_search_level: u8,
31
  }
src/server/routes/search.rs CHANGED
@@ -67,61 +67,48 @@ pub async fn search(
67
  None => 1,
68
  };
69
 
70
- let safe_search: u8 = match config.safe_search {
71
- 3..=4 => config.safe_search,
72
- _ => match &params.safesearch {
73
- Some(safesearch) => match safesearch {
74
- 0..=2 => *safesearch,
75
- _ => 1,
76
- },
77
- None => config.safe_search,
78
- },
79
- };
80
-
81
  let (_, results, _) = join!(
82
  results(
83
  format!(
84
- "http://{}:{}/search?q={}&page={}&safesearch={}",
85
  config.binding_ip,
86
  config.port,
87
  query,
88
  page - 1,
89
- safe_search
90
  ),
91
  &config,
92
  &cache,
93
  query,
94
  page - 1,
95
  req.clone(),
96
- safe_search
97
  ),
98
  results(
99
  format!(
100
- "http://{}:{}/search?q={}&page={}&safesearch={}",
101
- config.binding_ip, config.port, query, page, safe_search
102
  ),
103
  &config,
104
  &cache,
105
  query,
106
  page,
107
  req.clone(),
108
- safe_search
109
  ),
110
  results(
111
  format!(
112
- "http://{}:{}/search?q={}&page={}&safesearch={}",
113
  config.binding_ip,
114
  config.port,
115
  query,
116
  page + 1,
117
- safe_search
118
  ),
119
  &config,
120
  &cache,
121
  query,
122
  page + 1,
123
  req.clone(),
124
- safe_search
125
  )
126
  );
127
 
@@ -156,7 +143,7 @@ async fn results(
156
  query: &str,
157
  page: u32,
158
  req: HttpRequest,
159
- safe_search: u8,
160
  ) -> Result<SearchResults, Box<dyn std::error::Error>> {
161
  // fetch the cached results json.
162
  let cached_results = cache.cached_json(&url).await;
@@ -165,7 +152,18 @@ async fn results(
165
  match cached_results {
166
  Ok(results) => Ok(results),
167
  Err(_) => {
168
- if safe_search == 4 {
 
 
 
 
 
 
 
 
 
 
 
169
  let mut results: SearchResults = SearchResults::default();
170
  let mut _flag: bool =
171
  is_match_from_filter_list(file_path(FileType::BlockList)?, query)?;
@@ -176,6 +174,7 @@ async fn results(
176
  results.add_style(&config.style);
177
  results.set_page_query(query);
178
  cache.cache_results(&results, &url).await?;
 
179
  return Ok(results);
180
  }
181
  }
@@ -195,6 +194,17 @@ async fn results(
195
  .filter_map(|name| EngineHandler::new(name))
196
  .collect();
197
 
 
 
 
 
 
 
 
 
 
 
 
198
  match engines.is_empty() {
199
  false => {
200
  aggregate(
@@ -224,7 +234,7 @@ async fn results(
224
  config.debug,
225
  &config.upstream_search_engines,
226
  config.request_timeout,
227
- safe_search,
228
  )
229
  .await?
230
  }
@@ -236,7 +246,10 @@ async fn results(
236
  results.set_filtered();
237
  }
238
  results.add_style(&config.style);
239
- cache.cache_results(&results, &url).await?;
 
 
 
240
  Ok(results)
241
  }
242
  }
 
67
  None => 1,
68
  };
69
 
 
 
 
 
 
 
 
 
 
 
 
70
  let (_, results, _) = join!(
71
  results(
72
  format!(
73
+ "http://{}:{}/search?q={}&page={}&safesearch=",
74
  config.binding_ip,
75
  config.port,
76
  query,
77
  page - 1,
 
78
  ),
79
  &config,
80
  &cache,
81
  query,
82
  page - 1,
83
  req.clone(),
84
+ &params.safesearch
85
  ),
86
  results(
87
  format!(
88
+ "http://{}:{}/search?q={}&page={}&safesearch=",
89
+ config.binding_ip, config.port, query, page
90
  ),
91
  &config,
92
  &cache,
93
  query,
94
  page,
95
  req.clone(),
96
+ &params.safesearch
97
  ),
98
  results(
99
  format!(
100
+ "http://{}:{}/search?q={}&page={}&safesearch=",
101
  config.binding_ip,
102
  config.port,
103
  query,
104
  page + 1,
 
105
  ),
106
  &config,
107
  &cache,
108
  query,
109
  page + 1,
110
  req.clone(),
111
+ &params.safesearch
112
  )
113
  );
114
 
 
143
  query: &str,
144
  page: u32,
145
  req: HttpRequest,
146
+ safe_search: &Option<u8>,
147
  ) -> Result<SearchResults, Box<dyn std::error::Error>> {
148
  // fetch the cached results json.
149
  let cached_results = cache.cached_json(&url).await;
 
152
  match cached_results {
153
  Ok(results) => Ok(results),
154
  Err(_) => {
155
+ let mut safe_search_level: u8 = match config.safe_search {
156
+ 3..=4 => config.safe_search,
157
+ _ => match safe_search {
158
+ Some(safesearch) => match safesearch {
159
+ 0..=2 => *safesearch,
160
+ _ => config.safe_search,
161
+ },
162
+ None => config.safe_search,
163
+ },
164
+ };
165
+
166
+ if safe_search_level == 4 {
167
  let mut results: SearchResults = SearchResults::default();
168
  let mut _flag: bool =
169
  is_match_from_filter_list(file_path(FileType::BlockList)?, query)?;
 
174
  results.add_style(&config.style);
175
  results.set_page_query(query);
176
  cache.cache_results(&results, &url).await?;
177
+ results.set_safe_search_level(safe_search_level);
178
  return Ok(results);
179
  }
180
  }
 
194
  .filter_map(|name| EngineHandler::new(name))
195
  .collect();
196
 
197
+ safe_search_level = match config.safe_search {
198
+ 3..=4 => config.safe_search,
199
+ _ => match safe_search {
200
+ Some(safesearch) => match safesearch {
201
+ 0..=2 => *safesearch,
202
+ _ => config.safe_search,
203
+ },
204
+ None => cookie_value.safe_search_level,
205
+ },
206
+ };
207
+
208
  match engines.is_empty() {
209
  false => {
210
  aggregate(
 
234
  config.debug,
235
  &config.upstream_search_engines,
236
  config.request_timeout,
237
+ safe_search_level,
238
  )
239
  .await?
240
  }
 
246
  results.set_filtered();
247
  }
248
  results.add_style(&config.style);
249
+ cache
250
+ .cache_results(&results, &(format!("{url}{safe_search_level}")))
251
+ .await?;
252
+ results.set_safe_search_level(safe_search_level);
253
  Ok(results)
254
  }
255
  }