alamin655 commited on
Commit
0139fc5
2 Parent(s): 0facfdb 9b1d894

Merge pull request #383 from neon-mmd/REFACTOR/302_rewrite-the-search-engine-frontend-with-maud-html-framework

Browse files
Files changed (42) hide show
  1. Cargo.lock +134 -167
  2. Cargo.toml +2 -2
  3. public/templates/404.html +0 -10
  4. public/templates/about.html +0 -29
  5. public/templates/bar.html +0 -3
  6. public/templates/cookies_tab.html +0 -12
  7. public/templates/engines_tab.html +0 -32
  8. public/templates/footer.html +0 -16
  9. public/templates/general_tab.html +0 -13
  10. public/templates/header.html +0 -16
  11. public/templates/index.html +0 -8
  12. public/templates/navbar.html +0 -6
  13. public/templates/search.html +0 -86
  14. public/templates/search_bar.html +0 -36
  15. public/templates/settings.html +0 -22
  16. public/templates/user_interface_tab.html +0 -28
  17. src/config/parser.rs +2 -7
  18. src/lib.rs +1 -10
  19. src/models/aggregation_models.rs +2 -23
  20. src/models/parser_models.rs +1 -3
  21. src/results/aggregator.rs +1 -1
  22. src/server/router.rs +26 -20
  23. src/server/routes/search.rs +29 -36
  24. src/templates/mod.rs +5 -0
  25. src/templates/partials/bar.rs +21 -0
  26. src/templates/partials/footer.rs +29 -0
  27. src/templates/partials/header.rs +35 -0
  28. src/templates/partials/mod.rs +8 -0
  29. src/templates/partials/navbar.rs +19 -0
  30. src/templates/partials/search_bar.rs +76 -0
  31. src/templates/partials/settings_tabs/cookies.rs +25 -0
  32. src/templates/partials/settings_tabs/engines.rs +43 -0
  33. src/templates/partials/settings_tabs/general.rs +28 -0
  34. src/templates/partials/settings_tabs/mod.rs +7 -0
  35. src/templates/partials/settings_tabs/user_interface.rs +65 -0
  36. src/templates/views/about.rs +48 -0
  37. src/templates/views/index.rs +28 -0
  38. src/templates/views/mod.rs +8 -0
  39. src/templates/views/not_found.rs +29 -0
  40. src/templates/views/search.rs +122 -0
  41. src/templates/views/settings.rs +56 -0
  42. tests/index.rs +2 -16
Cargo.lock CHANGED
@@ -14,7 +14,7 @@ dependencies = [
14
  "futures-sink",
15
  "memchr",
16
  "pin-project-lite",
17
- "tokio 1.33.0",
18
  "tokio-util",
19
  "tracing",
20
  ]
@@ -31,7 +31,7 @@ dependencies = [
31
  "futures-util",
32
  "log",
33
  "once_cell",
34
- "smallvec 1.11.1",
35
  ]
36
 
37
  [[package]]
@@ -87,7 +87,7 @@ dependencies = [
87
  "derive_more",
88
  "encoding_rs",
89
  "futures-core",
90
- "http 0.2.9",
91
  "httparse",
92
  "httpdate",
93
  "itoa 1.0.9",
@@ -98,8 +98,8 @@ dependencies = [
98
  "pin-project-lite",
99
  "rand 0.8.5",
100
  "sha1",
101
- "smallvec 1.11.1",
102
- "tokio 1.33.0",
103
  "tokio-util",
104
  "tracing",
105
  ]
@@ -121,7 +121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
121
  checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799"
122
  dependencies = [
123
  "bytestring",
124
- "http 0.2.9",
125
  "regex",
126
  "serde",
127
  "tracing",
@@ -134,7 +134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
134
  checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d"
135
  dependencies = [
136
  "futures-core",
137
- "tokio 1.33.0",
138
  ]
139
 
140
  [[package]]
@@ -150,7 +150,7 @@ dependencies = [
150
  "futures-util",
151
  "mio 0.8.9",
152
  "socket2 0.5.5",
153
- "tokio 1.33.0",
154
  "tracing",
155
  ]
156
 
@@ -209,7 +209,7 @@ dependencies = [
209
  "serde",
210
  "serde_json",
211
  "serde_urlencoded 0.7.1",
212
- "smallvec 1.11.1",
213
  "socket2 0.5.5",
214
  "time 0.3.30",
215
  "url 2.4.1",
@@ -414,9 +414,9 @@ dependencies = [
414
 
415
  [[package]]
416
  name = "bstr"
417
- version = "1.7.0"
418
  source = "registry+https://github.com/rust-lang/crates.io-index"
419
- checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019"
420
  dependencies = [
421
  "memchr",
422
  "serde",
@@ -562,18 +562,18 @@ dependencies = [
562
 
563
  [[package]]
564
  name = "clap"
565
- version = "4.4.7"
566
  source = "registry+https://github.com/rust-lang/crates.io-index"
567
- checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
568
  dependencies = [
569
  "clap_builder",
570
  ]
571
 
572
  [[package]]
573
  name = "clap_builder"
574
- version = "4.4.7"
575
  source = "registry+https://github.com/rust-lang/crates.io-index"
576
- checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
577
  dependencies = [
578
  "anstyle",
579
  "clap_lex",
@@ -604,7 +604,7 @@ dependencies = [
604
  "futures-core",
605
  "memchr",
606
  "pin-project-lite",
607
- "tokio 1.33.0",
608
  "tokio-util",
609
  ]
610
 
@@ -828,7 +828,7 @@ dependencies = [
828
  "dtoa-short",
829
  "itoa 1.0.9",
830
  "phf 0.11.2",
831
- "smallvec 1.11.1",
832
  ]
833
 
834
  [[package]]
@@ -841,7 +841,7 @@ dependencies = [
841
  "dtoa-short",
842
  "itoa 1.0.9",
843
  "phf 0.11.2",
844
- "smallvec 1.11.1",
845
  ]
846
 
847
  [[package]]
@@ -974,9 +974,9 @@ dependencies = [
974
 
975
  [[package]]
976
  name = "env_logger"
977
- version = "0.10.0"
978
  source = "registry+https://github.com/rust-lang/crates.io-index"
979
- checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
980
  dependencies = [
981
  "log",
982
  ]
@@ -988,14 +988,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
988
  checksum = "a2d328fc287c61314c4a61af7cfdcbd7e678e39778488c7cb13ec133ce0f4059"
989
  dependencies = [
990
  "fsio",
991
- "indexmap",
992
  ]
993
 
 
 
 
 
 
 
994
  [[package]]
995
  name = "errno"
996
- version = "0.3.6"
997
  source = "registry+https://github.com/rust-lang/crates.io-index"
998
- checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e"
999
  dependencies = [
1000
  "libc",
1001
  "windows-sys",
@@ -1314,7 +1320,7 @@ dependencies = [
1314
  "parking_lot 0.12.1",
1315
  "quanta",
1316
  "rand 0.8.5",
1317
- "smallvec 1.11.1",
1318
  ]
1319
 
1320
  [[package]]
@@ -1328,7 +1334,7 @@ dependencies = [
1328
  "fnv",
1329
  "futures 0.1.31",
1330
  "http 0.1.21",
1331
- "indexmap",
1332
  "log",
1333
  "slab",
1334
  "string",
@@ -1337,19 +1343,19 @@ dependencies = [
1337
 
1338
  [[package]]
1339
  name = "h2"
1340
- version = "0.3.21"
1341
  source = "registry+https://github.com/rust-lang/crates.io-index"
1342
- checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833"
1343
  dependencies = [
1344
  "bytes 1.5.0",
1345
  "fnv",
1346
  "futures-core",
1347
  "futures-sink",
1348
  "futures-util",
1349
- "http 0.2.9",
1350
- "indexmap",
1351
  "slab",
1352
- "tokio 1.33.0",
1353
  "tokio-util",
1354
  "tracing",
1355
  ]
@@ -1360,21 +1366,6 @@ version = "1.8.2"
1360
  source = "registry+https://github.com/rust-lang/crates.io-index"
1361
  checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
1362
 
1363
- [[package]]
1364
- name = "handlebars"
1365
- version = "4.4.0"
1366
- source = "registry+https://github.com/rust-lang/crates.io-index"
1367
- checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683"
1368
- dependencies = [
1369
- "log",
1370
- "pest",
1371
- "pest_derive",
1372
- "serde",
1373
- "serde_json",
1374
- "thiserror",
1375
- "walkdir",
1376
- ]
1377
-
1378
  [[package]]
1379
  name = "hashbrown"
1380
  version = "0.12.3"
@@ -1453,9 +1444,9 @@ dependencies = [
1453
 
1454
  [[package]]
1455
  name = "http"
1456
- version = "0.2.9"
1457
  source = "registry+https://github.com/rust-lang/crates.io-index"
1458
- checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
1459
  dependencies = [
1460
  "bytes 1.5.0",
1461
  "fnv",
@@ -1481,7 +1472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1481
  checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
1482
  dependencies = [
1483
  "bytes 1.5.0",
1484
- "http 0.2.9",
1485
  "pin-project-lite",
1486
  ]
1487
 
@@ -1543,15 +1534,15 @@ dependencies = [
1543
  "futures-channel",
1544
  "futures-core",
1545
  "futures-util",
1546
- "h2 0.3.21",
1547
- "http 0.2.9",
1548
  "http-body 0.4.5",
1549
  "httparse",
1550
  "httpdate",
1551
  "itoa 1.0.9",
1552
  "pin-project-lite",
1553
  "socket2 0.4.10",
1554
- "tokio 1.33.0",
1555
  "tower-service",
1556
  "tracing",
1557
  "want 0.3.1",
@@ -1564,10 +1555,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1564
  checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
1565
  dependencies = [
1566
  "futures-util",
1567
- "http 0.2.9",
1568
  "hyper 0.14.27",
1569
  "rustls",
1570
- "tokio 1.33.0",
1571
  "tokio-rustls",
1572
  ]
1573
 
@@ -1626,6 +1617,16 @@ dependencies = [
1626
  "hashbrown 0.12.3",
1627
  ]
1628
 
 
 
 
 
 
 
 
 
 
 
1629
  [[package]]
1630
  name = "iovec"
1631
  version = "0.1.4"
@@ -1737,7 +1738,7 @@ dependencies = [
1737
  "parcel_selectors",
1738
  "paste",
1739
  "pathdiff",
1740
- "smallvec 1.11.1",
1741
  ]
1742
 
1743
  [[package]]
@@ -1859,6 +1860,30 @@ version = "0.1.10"
1859
  source = "registry+https://github.com/rust-lang/crates.io-index"
1860
  checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
1861
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1862
  [[package]]
1863
  name = "maybe-uninit"
1864
  version = "2.0.0"
@@ -1921,7 +1946,7 @@ dependencies = [
1921
  "crossbeam-utils 0.8.16",
1922
  "dashmap",
1923
  "skeptic",
1924
- "smallvec 1.11.1",
1925
  "tagptr",
1926
  "triomphe",
1927
  ]
@@ -2174,7 +2199,7 @@ dependencies = [
2174
  "phf 0.10.1",
2175
  "phf_codegen 0.10.0",
2176
  "precomputed-hash",
2177
- "smallvec 1.11.1",
2178
  ]
2179
 
2180
  [[package]]
@@ -2222,7 +2247,7 @@ dependencies = [
2222
  "cfg-if 1.0.0",
2223
  "libc",
2224
  "redox_syscall 0.4.1",
2225
- "smallvec 1.11.1",
2226
  "windows-targets",
2227
  ]
2228
 
@@ -2263,51 +2288,6 @@ version = "2.3.0"
2263
  source = "registry+https://github.com/rust-lang/crates.io-index"
2264
  checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
2265
 
2266
- [[package]]
2267
- name = "pest"
2268
- version = "2.7.5"
2269
- source = "registry+https://github.com/rust-lang/crates.io-index"
2270
- checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5"
2271
- dependencies = [
2272
- "memchr",
2273
- "thiserror",
2274
- "ucd-trie",
2275
- ]
2276
-
2277
- [[package]]
2278
- name = "pest_derive"
2279
- version = "2.7.5"
2280
- source = "registry+https://github.com/rust-lang/crates.io-index"
2281
- checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2"
2282
- dependencies = [
2283
- "pest",
2284
- "pest_generator",
2285
- ]
2286
-
2287
- [[package]]
2288
- name = "pest_generator"
2289
- version = "2.7.5"
2290
- source = "registry+https://github.com/rust-lang/crates.io-index"
2291
- checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227"
2292
- dependencies = [
2293
- "pest",
2294
- "pest_meta",
2295
- "proc-macro2 1.0.69",
2296
- "quote 1.0.33",
2297
- "syn 2.0.39",
2298
- ]
2299
-
2300
- [[package]]
2301
- name = "pest_meta"
2302
- version = "2.7.5"
2303
- source = "registry+https://github.com/rust-lang/crates.io-index"
2304
- checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6"
2305
- dependencies = [
2306
- "once_cell",
2307
- "pest",
2308
- "sha2",
2309
- ]
2310
-
2311
  [[package]]
2312
  name = "phf"
2313
  version = "0.7.24"
@@ -2482,6 +2462,30 @@ version = "0.1.1"
2482
  source = "registry+https://github.com/rust-lang/crates.io-index"
2483
  checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
2484
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2485
  [[package]]
2486
  name = "proc-macro2"
2487
  version = "0.4.30"
@@ -2725,7 +2729,7 @@ dependencies = [
2725
  "percent-encoding 2.3.0",
2726
  "pin-project-lite",
2727
  "ryu",
2728
- "tokio 1.33.0",
2729
  "tokio-retry",
2730
  "tokio-util",
2731
  "url 2.4.1",
@@ -2820,8 +2824,8 @@ dependencies = [
2820
  "encoding_rs",
2821
  "futures-core",
2822
  "futures-util",
2823
- "h2 0.3.21",
2824
- "http 0.2.9",
2825
  "http-body 0.4.5",
2826
  "hyper 0.14.27",
2827
  "hyper-rustls",
@@ -2838,7 +2842,7 @@ dependencies = [
2838
  "serde_json",
2839
  "serde_urlencoded 0.7.1",
2840
  "system-configuration",
2841
- "tokio 1.33.0",
2842
  "tokio-rustls",
2843
  "tower-service",
2844
  "url 2.4.1",
@@ -2895,9 +2899,9 @@ dependencies = [
2895
 
2896
  [[package]]
2897
  name = "rustix"
2898
- version = "0.38.21"
2899
  source = "registry+https://github.com/rust-lang/crates.io-index"
2900
- checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
2901
  dependencies = [
2902
  "bitflags 2.4.1",
2903
  "errno",
@@ -2908,9 +2912,9 @@ dependencies = [
2908
 
2909
  [[package]]
2910
  name = "rustls"
2911
- version = "0.21.8"
2912
  source = "registry+https://github.com/rust-lang/crates.io-index"
2913
- checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c"
2914
  dependencies = [
2915
  "log",
2916
  "ring",
@@ -2920,9 +2924,9 @@ dependencies = [
2920
 
2921
  [[package]]
2922
  name = "rustls-pemfile"
2923
- version = "1.0.3"
2924
  source = "registry+https://github.com/rust-lang/crates.io-index"
2925
- checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
2926
  dependencies = [
2927
  "base64 0.21.5",
2928
  ]
@@ -3053,7 +3057,7 @@ dependencies = [
3053
  "phf_codegen 0.10.0",
3054
  "precomputed-hash",
3055
  "servo_arc",
3056
- "smallvec 1.11.1",
3057
  ]
3058
 
3059
  [[package]]
@@ -3155,17 +3159,6 @@ dependencies = [
3155
  "digest",
3156
  ]
3157
 
3158
- [[package]]
3159
- name = "sha2"
3160
- version = "0.10.8"
3161
- source = "registry+https://github.com/rust-lang/crates.io-index"
3162
- checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
3163
- dependencies = [
3164
- "cfg-if 1.0.0",
3165
- "cpufeatures",
3166
- "digest",
3167
- ]
3168
-
3169
  [[package]]
3170
  name = "signal-hook-registry"
3171
  version = "1.4.1"
@@ -3222,9 +3215,9 @@ dependencies = [
3222
 
3223
  [[package]]
3224
  name = "smallvec"
3225
- version = "1.11.1"
3226
  source = "registry+https://github.com/rust-lang/crates.io-index"
3227
- checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
3228
  dependencies = [
3229
  "serde",
3230
  ]
@@ -3436,26 +3429,6 @@ dependencies = [
3436
  "utf-8",
3437
  ]
3438
 
3439
- [[package]]
3440
- name = "thiserror"
3441
- version = "1.0.50"
3442
- source = "registry+https://github.com/rust-lang/crates.io-index"
3443
- checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
3444
- dependencies = [
3445
- "thiserror-impl",
3446
- ]
3447
-
3448
- [[package]]
3449
- name = "thiserror-impl"
3450
- version = "1.0.50"
3451
- source = "registry+https://github.com/rust-lang/crates.io-index"
3452
- checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
3453
- dependencies = [
3454
- "proc-macro2 1.0.69",
3455
- "quote 1.0.33",
3456
- "syn 2.0.39",
3457
- ]
3458
-
3459
  [[package]]
3460
  name = "thousands"
3461
  version = "0.2.0"
@@ -3548,9 +3521,9 @@ dependencies = [
3548
 
3549
  [[package]]
3550
  name = "tokio"
3551
- version = "1.33.0"
3552
  source = "registry+https://github.com/rust-lang/crates.io-index"
3553
- checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
3554
  dependencies = [
3555
  "backtrace",
3556
  "bytes 1.5.0",
@@ -3609,9 +3582,9 @@ dependencies = [
3609
 
3610
  [[package]]
3611
  name = "tokio-macros"
3612
- version = "2.1.0"
3613
  source = "registry+https://github.com/rust-lang/crates.io-index"
3614
- checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
3615
  dependencies = [
3616
  "proc-macro2 1.0.69",
3617
  "quote 1.0.33",
@@ -3645,7 +3618,7 @@ checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f"
3645
  dependencies = [
3646
  "pin-project",
3647
  "rand 0.8.5",
3648
- "tokio 1.33.0",
3649
  ]
3650
 
3651
  [[package]]
@@ -3655,7 +3628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
3655
  checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
3656
  dependencies = [
3657
  "rustls",
3658
- "tokio 1.33.0",
3659
  ]
3660
 
3661
  [[package]]
@@ -3721,7 +3694,7 @@ dependencies = [
3721
  "futures-core",
3722
  "futures-sink",
3723
  "pin-project-lite",
3724
- "tokio 1.33.0",
3725
  "tracing",
3726
  ]
3727
 
@@ -3787,12 +3760,6 @@ version = "1.17.0"
3787
  source = "registry+https://github.com/rust-lang/crates.io-index"
3788
  checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
3789
 
3790
- [[package]]
3791
- name = "ucd-trie"
3792
- version = "0.1.6"
3793
- source = "registry+https://github.com/rust-lang/crates.io-index"
3794
- checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
3795
-
3796
  [[package]]
3797
  name = "unicase"
3798
  version = "2.7.0"
@@ -4022,7 +3989,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
4022
 
4023
  [[package]]
4024
  name = "websurfx"
4025
- version = "1.2.25"
4026
  dependencies = [
4027
  "actix-cors",
4028
  "actix-files",
@@ -4036,9 +4003,9 @@ dependencies = [
4036
  "error-stack",
4037
  "fake-useragent",
4038
  "futures 0.3.29",
4039
- "handlebars",
4040
  "lightningcss",
4041
  "log",
 
4042
  "md5",
4043
  "mimalloc",
4044
  "mini-moka",
@@ -4051,9 +4018,9 @@ dependencies = [
4051
  "scraper",
4052
  "serde",
4053
  "serde_json",
4054
- "smallvec 1.11.1",
4055
  "tempfile",
4056
- "tokio 1.33.0",
4057
  ]
4058
 
4059
  [[package]]
@@ -4208,18 +4175,18 @@ dependencies = [
4208
 
4209
  [[package]]
4210
  name = "zerocopy"
4211
- version = "0.7.25"
4212
  source = "registry+https://github.com/rust-lang/crates.io-index"
4213
- checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557"
4214
  dependencies = [
4215
  "zerocopy-derive",
4216
  ]
4217
 
4218
  [[package]]
4219
  name = "zerocopy-derive"
4220
- version = "0.7.25"
4221
  source = "registry+https://github.com/rust-lang/crates.io-index"
4222
- checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b"
4223
  dependencies = [
4224
  "proc-macro2 1.0.69",
4225
  "quote 1.0.33",
 
14
  "futures-sink",
15
  "memchr",
16
  "pin-project-lite",
17
+ "tokio 1.34.0",
18
  "tokio-util",
19
  "tracing",
20
  ]
 
31
  "futures-util",
32
  "log",
33
  "once_cell",
34
+ "smallvec 1.11.2",
35
  ]
36
 
37
  [[package]]
 
87
  "derive_more",
88
  "encoding_rs",
89
  "futures-core",
90
+ "http 0.2.11",
91
  "httparse",
92
  "httpdate",
93
  "itoa 1.0.9",
 
98
  "pin-project-lite",
99
  "rand 0.8.5",
100
  "sha1",
101
+ "smallvec 1.11.2",
102
+ "tokio 1.34.0",
103
  "tokio-util",
104
  "tracing",
105
  ]
 
121
  checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799"
122
  dependencies = [
123
  "bytestring",
124
+ "http 0.2.11",
125
  "regex",
126
  "serde",
127
  "tracing",
 
134
  checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d"
135
  dependencies = [
136
  "futures-core",
137
+ "tokio 1.34.0",
138
  ]
139
 
140
  [[package]]
 
150
  "futures-util",
151
  "mio 0.8.9",
152
  "socket2 0.5.5",
153
+ "tokio 1.34.0",
154
  "tracing",
155
  ]
156
 
 
209
  "serde",
210
  "serde_json",
211
  "serde_urlencoded 0.7.1",
212
+ "smallvec 1.11.2",
213
  "socket2 0.5.5",
214
  "time 0.3.30",
215
  "url 2.4.1",
 
414
 
415
  [[package]]
416
  name = "bstr"
417
+ version = "1.8.0"
418
  source = "registry+https://github.com/rust-lang/crates.io-index"
419
+ checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
420
  dependencies = [
421
  "memchr",
422
  "serde",
 
562
 
563
  [[package]]
564
  name = "clap"
565
+ version = "4.4.8"
566
  source = "registry+https://github.com/rust-lang/crates.io-index"
567
+ checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
568
  dependencies = [
569
  "clap_builder",
570
  ]
571
 
572
  [[package]]
573
  name = "clap_builder"
574
+ version = "4.4.8"
575
  source = "registry+https://github.com/rust-lang/crates.io-index"
576
+ checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc"
577
  dependencies = [
578
  "anstyle",
579
  "clap_lex",
 
604
  "futures-core",
605
  "memchr",
606
  "pin-project-lite",
607
+ "tokio 1.34.0",
608
  "tokio-util",
609
  ]
610
 
 
828
  "dtoa-short",
829
  "itoa 1.0.9",
830
  "phf 0.11.2",
831
+ "smallvec 1.11.2",
832
  ]
833
 
834
  [[package]]
 
841
  "dtoa-short",
842
  "itoa 1.0.9",
843
  "phf 0.11.2",
844
+ "smallvec 1.11.2",
845
  ]
846
 
847
  [[package]]
 
974
 
975
  [[package]]
976
  name = "env_logger"
977
+ version = "0.10.1"
978
  source = "registry+https://github.com/rust-lang/crates.io-index"
979
+ checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
980
  dependencies = [
981
  "log",
982
  ]
 
988
  checksum = "a2d328fc287c61314c4a61af7cfdcbd7e678e39778488c7cb13ec133ce0f4059"
989
  dependencies = [
990
  "fsio",
991
+ "indexmap 1.9.3",
992
  ]
993
 
994
+ [[package]]
995
+ name = "equivalent"
996
+ version = "1.0.1"
997
+ source = "registry+https://github.com/rust-lang/crates.io-index"
998
+ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
999
+
1000
  [[package]]
1001
  name = "errno"
1002
+ version = "0.3.7"
1003
  source = "registry+https://github.com/rust-lang/crates.io-index"
1004
+ checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8"
1005
  dependencies = [
1006
  "libc",
1007
  "windows-sys",
 
1320
  "parking_lot 0.12.1",
1321
  "quanta",
1322
  "rand 0.8.5",
1323
+ "smallvec 1.11.2",
1324
  ]
1325
 
1326
  [[package]]
 
1334
  "fnv",
1335
  "futures 0.1.31",
1336
  "http 0.1.21",
1337
+ "indexmap 1.9.3",
1338
  "log",
1339
  "slab",
1340
  "string",
 
1343
 
1344
  [[package]]
1345
  name = "h2"
1346
+ version = "0.3.22"
1347
  source = "registry+https://github.com/rust-lang/crates.io-index"
1348
+ checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178"
1349
  dependencies = [
1350
  "bytes 1.5.0",
1351
  "fnv",
1352
  "futures-core",
1353
  "futures-sink",
1354
  "futures-util",
1355
+ "http 0.2.11",
1356
+ "indexmap 2.1.0",
1357
  "slab",
1358
+ "tokio 1.34.0",
1359
  "tokio-util",
1360
  "tracing",
1361
  ]
 
1366
  source = "registry+https://github.com/rust-lang/crates.io-index"
1367
  checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
1368
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1369
  [[package]]
1370
  name = "hashbrown"
1371
  version = "0.12.3"
 
1444
 
1445
  [[package]]
1446
  name = "http"
1447
+ version = "0.2.11"
1448
  source = "registry+https://github.com/rust-lang/crates.io-index"
1449
+ checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
1450
  dependencies = [
1451
  "bytes 1.5.0",
1452
  "fnv",
 
1472
  checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
1473
  dependencies = [
1474
  "bytes 1.5.0",
1475
+ "http 0.2.11",
1476
  "pin-project-lite",
1477
  ]
1478
 
 
1534
  "futures-channel",
1535
  "futures-core",
1536
  "futures-util",
1537
+ "h2 0.3.22",
1538
+ "http 0.2.11",
1539
  "http-body 0.4.5",
1540
  "httparse",
1541
  "httpdate",
1542
  "itoa 1.0.9",
1543
  "pin-project-lite",
1544
  "socket2 0.4.10",
1545
+ "tokio 1.34.0",
1546
  "tower-service",
1547
  "tracing",
1548
  "want 0.3.1",
 
1555
  checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
1556
  dependencies = [
1557
  "futures-util",
1558
+ "http 0.2.11",
1559
  "hyper 0.14.27",
1560
  "rustls",
1561
+ "tokio 1.34.0",
1562
  "tokio-rustls",
1563
  ]
1564
 
 
1617
  "hashbrown 0.12.3",
1618
  ]
1619
 
1620
+ [[package]]
1621
+ name = "indexmap"
1622
+ version = "2.1.0"
1623
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1624
+ checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
1625
+ dependencies = [
1626
+ "equivalent",
1627
+ "hashbrown 0.14.2",
1628
+ ]
1629
+
1630
  [[package]]
1631
  name = "iovec"
1632
  version = "0.1.4"
 
1738
  "parcel_selectors",
1739
  "paste",
1740
  "pathdiff",
1741
+ "smallvec 1.11.2",
1742
  ]
1743
 
1744
  [[package]]
 
1860
  source = "registry+https://github.com/rust-lang/crates.io-index"
1861
  checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
1862
 
1863
+ [[package]]
1864
+ name = "maud"
1865
+ version = "0.25.0"
1866
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1867
+ checksum = "b0bab19cef8a7fe1c18a43e881793bfc9d4ea984befec3ae5bd0415abf3ecf00"
1868
+ dependencies = [
1869
+ "actix-web",
1870
+ "futures-util",
1871
+ "itoa 1.0.9",
1872
+ "maud_macros",
1873
+ ]
1874
+
1875
+ [[package]]
1876
+ name = "maud_macros"
1877
+ version = "0.25.0"
1878
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1879
+ checksum = "0be95d66c3024ffce639216058e5bae17a83ecaf266ffc6e4d060ad447c9eed2"
1880
+ dependencies = [
1881
+ "proc-macro-error",
1882
+ "proc-macro2 1.0.69",
1883
+ "quote 1.0.33",
1884
+ "syn 1.0.109",
1885
+ ]
1886
+
1887
  [[package]]
1888
  name = "maybe-uninit"
1889
  version = "2.0.0"
 
1946
  "crossbeam-utils 0.8.16",
1947
  "dashmap",
1948
  "skeptic",
1949
+ "smallvec 1.11.2",
1950
  "tagptr",
1951
  "triomphe",
1952
  ]
 
2199
  "phf 0.10.1",
2200
  "phf_codegen 0.10.0",
2201
  "precomputed-hash",
2202
+ "smallvec 1.11.2",
2203
  ]
2204
 
2205
  [[package]]
 
2247
  "cfg-if 1.0.0",
2248
  "libc",
2249
  "redox_syscall 0.4.1",
2250
+ "smallvec 1.11.2",
2251
  "windows-targets",
2252
  ]
2253
 
 
2288
  source = "registry+https://github.com/rust-lang/crates.io-index"
2289
  checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
2290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2291
  [[package]]
2292
  name = "phf"
2293
  version = "0.7.24"
 
2462
  source = "registry+https://github.com/rust-lang/crates.io-index"
2463
  checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
2464
 
2465
+ [[package]]
2466
+ name = "proc-macro-error"
2467
+ version = "1.0.4"
2468
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2469
+ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
2470
+ dependencies = [
2471
+ "proc-macro-error-attr",
2472
+ "proc-macro2 1.0.69",
2473
+ "quote 1.0.33",
2474
+ "syn 1.0.109",
2475
+ "version_check",
2476
+ ]
2477
+
2478
+ [[package]]
2479
+ name = "proc-macro-error-attr"
2480
+ version = "1.0.4"
2481
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2482
+ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
2483
+ dependencies = [
2484
+ "proc-macro2 1.0.69",
2485
+ "quote 1.0.33",
2486
+ "version_check",
2487
+ ]
2488
+
2489
  [[package]]
2490
  name = "proc-macro2"
2491
  version = "0.4.30"
 
2729
  "percent-encoding 2.3.0",
2730
  "pin-project-lite",
2731
  "ryu",
2732
+ "tokio 1.34.0",
2733
  "tokio-retry",
2734
  "tokio-util",
2735
  "url 2.4.1",
 
2824
  "encoding_rs",
2825
  "futures-core",
2826
  "futures-util",
2827
+ "h2 0.3.22",
2828
+ "http 0.2.11",
2829
  "http-body 0.4.5",
2830
  "hyper 0.14.27",
2831
  "hyper-rustls",
 
2842
  "serde_json",
2843
  "serde_urlencoded 0.7.1",
2844
  "system-configuration",
2845
+ "tokio 1.34.0",
2846
  "tokio-rustls",
2847
  "tower-service",
2848
  "url 2.4.1",
 
2899
 
2900
  [[package]]
2901
  name = "rustix"
2902
+ version = "0.38.24"
2903
  source = "registry+https://github.com/rust-lang/crates.io-index"
2904
+ checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234"
2905
  dependencies = [
2906
  "bitflags 2.4.1",
2907
  "errno",
 
2912
 
2913
  [[package]]
2914
  name = "rustls"
2915
+ version = "0.21.9"
2916
  source = "registry+https://github.com/rust-lang/crates.io-index"
2917
+ checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9"
2918
  dependencies = [
2919
  "log",
2920
  "ring",
 
2924
 
2925
  [[package]]
2926
  name = "rustls-pemfile"
2927
+ version = "1.0.4"
2928
  source = "registry+https://github.com/rust-lang/crates.io-index"
2929
+ checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
2930
  dependencies = [
2931
  "base64 0.21.5",
2932
  ]
 
3057
  "phf_codegen 0.10.0",
3058
  "precomputed-hash",
3059
  "servo_arc",
3060
+ "smallvec 1.11.2",
3061
  ]
3062
 
3063
  [[package]]
 
3159
  "digest",
3160
  ]
3161
 
 
 
 
 
 
 
 
 
 
 
 
3162
  [[package]]
3163
  name = "signal-hook-registry"
3164
  version = "1.4.1"
 
3215
 
3216
  [[package]]
3217
  name = "smallvec"
3218
+ version = "1.11.2"
3219
  source = "registry+https://github.com/rust-lang/crates.io-index"
3220
+ checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
3221
  dependencies = [
3222
  "serde",
3223
  ]
 
3429
  "utf-8",
3430
  ]
3431
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3432
  [[package]]
3433
  name = "thousands"
3434
  version = "0.2.0"
 
3521
 
3522
  [[package]]
3523
  name = "tokio"
3524
+ version = "1.34.0"
3525
  source = "registry+https://github.com/rust-lang/crates.io-index"
3526
+ checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9"
3527
  dependencies = [
3528
  "backtrace",
3529
  "bytes 1.5.0",
 
3582
 
3583
  [[package]]
3584
  name = "tokio-macros"
3585
+ version = "2.2.0"
3586
  source = "registry+https://github.com/rust-lang/crates.io-index"
3587
+ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
3588
  dependencies = [
3589
  "proc-macro2 1.0.69",
3590
  "quote 1.0.33",
 
3618
  dependencies = [
3619
  "pin-project",
3620
  "rand 0.8.5",
3621
+ "tokio 1.34.0",
3622
  ]
3623
 
3624
  [[package]]
 
3628
  checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
3629
  dependencies = [
3630
  "rustls",
3631
+ "tokio 1.34.0",
3632
  ]
3633
 
3634
  [[package]]
 
3694
  "futures-core",
3695
  "futures-sink",
3696
  "pin-project-lite",
3697
+ "tokio 1.34.0",
3698
  "tracing",
3699
  ]
3700
 
 
3760
  source = "registry+https://github.com/rust-lang/crates.io-index"
3761
  checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
3762
 
 
 
 
 
 
 
3763
  [[package]]
3764
  name = "unicase"
3765
  version = "2.7.0"
 
3989
 
3990
  [[package]]
3991
  name = "websurfx"
3992
+ version = "1.2.26"
3993
  dependencies = [
3994
  "actix-cors",
3995
  "actix-files",
 
4003
  "error-stack",
4004
  "fake-useragent",
4005
  "futures 0.3.29",
 
4006
  "lightningcss",
4007
  "log",
4008
+ "maud",
4009
  "md5",
4010
  "mimalloc",
4011
  "mini-moka",
 
4018
  "scraper",
4019
  "serde",
4020
  "serde_json",
4021
+ "smallvec 1.11.2",
4022
  "tempfile",
4023
+ "tokio 1.34.0",
4024
  ]
4025
 
4026
  [[package]]
 
4175
 
4176
  [[package]]
4177
  name = "zerocopy"
4178
+ version = "0.7.26"
4179
  source = "registry+https://github.com/rust-lang/crates.io-index"
4180
+ checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0"
4181
  dependencies = [
4182
  "zerocopy-derive",
4183
  ]
4184
 
4185
  [[package]]
4186
  name = "zerocopy-derive"
4187
+ version = "0.7.26"
4188
  source = "registry+https://github.com/rust-lang/crates.io-index"
4189
+ checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
4190
  dependencies = [
4191
  "proc-macro2 1.0.69",
4192
  "quote 1.0.33",
Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
  [package]
2
  name = "websurfx"
3
- version = "1.2.25"
4
  edition = "2021"
5
  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."
6
  repository = "https://github.com/neon-mmd/websurfx"
@@ -17,7 +17,7 @@ reqwest = {version="0.11.22", default-features=false, features=["rustls-tls"]}
17
  tokio = {version="1.32.0",features=["rt-multi-thread","macros"], default-features = false}
18
  serde = {version="1.0.190", default-features=false, features=["derive"]}
19
  serde_json = {version="1.0.108", default-features=false}
20
- handlebars = { version = "4.4.0", features = ["dir_source"], default-features = false }
21
  scraper = {version="0.18.1", default-features = false}
22
  actix-web = {version="4.4.0", features = ["cookies", "macros"], default-features=false}
23
  actix-files = {version="0.6.2", default-features=false}
 
1
  [package]
2
  name = "websurfx"
3
+ version = "1.2.26"
4
  edition = "2021"
5
  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."
6
  repository = "https://github.com/neon-mmd/websurfx"
 
17
  tokio = {version="1.32.0",features=["rt-multi-thread","macros"], default-features = false}
18
  serde = {version="1.0.190", default-features=false, features=["derive"]}
19
  serde_json = {version="1.0.108", default-features=false}
20
+ maud = {version="0.25.0", default-features=false, features=["actix-web"]}
21
  scraper = {version="0.18.1", default-features = false}
22
  actix-web = {version="4.4.0", features = ["cookies", "macros"], default-features=false}
23
  actix-files = {version="0.6.2", default-features=false}
public/templates/404.html DELETED
@@ -1,10 +0,0 @@
1
- {{>header this}}
2
- <main class="error_container">
3
- <img src="images/robot-404.svg" alt="Image of broken robot." />
4
- <div class="error_content">
5
- <h1>Aw! snap</h1>
6
- <h2>404 Page Not Found!</h2>
7
- <p>Go to <a href="/">search page</a></p>
8
- </div>
9
- </main>
10
- {{>footer}}
 
 
 
 
 
 
 
 
 
 
 
public/templates/about.html DELETED
@@ -1,29 +0,0 @@
1
- {{>header this}}
2
- <main class="about-container">
3
- <article >
4
- <div>
5
- <h1 >Websurfx</h1>
6
- <hr size="4" width="100%" color="#a6e3a1">
7
- </div>
8
- <p>A modern-looking, lightning-fast, privacy-respecting, secure meta search engine written in Rust. It provides a fast and secure search experience while respecting user privacy.<br> It aggregates results from multiple search engines and presents them in an unbiased manner, filtering out trackers and ads.
9
- </p>
10
-
11
- <h2>Some of the Top Features:</h2>
12
-
13
- <ul><strong>Lightning fast </strong>- Results load within milliseconds for an instant search experience.</ul>
14
-
15
- <ul><strong>Secure search</strong> - All searches are performed over an encrypted connection to prevent snooping.</ul>
16
-
17
- <ul><strong>Ad free results</strong> - All search results are ad free and clutter free for a clean search experience.</ul>
18
-
19
- <ul><strong>Privacy focused</strong> - Websurface does not track, store or sell your search data. Your privacy is our priority.</ul>
20
-
21
- <ul><strong>Free and Open source</strong> - The entire project's code is open source and available for free on <a href="https://github.com/neon-mmd/websurfx">GitHub</a> under an GNU Affero General Public License.</ul>
22
-
23
- <ul><strong>Highly customizable</strong> - Websurface comes with 9 built-in color themes and supports creating custom themes effortlessly.</ul>
24
- </article>
25
-
26
- <h3>Devoloped by: <a href="https://github.com/neon-mmd/websurfx">Websurfx team</a></h3>
27
- </main>
28
- {{>footer}}
29
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/templates/bar.html DELETED
@@ -1,3 +0,0 @@
1
- <div class="search_bar">
2
- <input type="search" name="search-box" value="{{this.pageQuery}}" placeholder="Type to search" />
3
- <button type="submit" onclick="searchWeb()">search</button>
 
 
 
 
public/templates/cookies_tab.html DELETED
@@ -1,12 +0,0 @@
1
- <div class="cookies tab">
2
- <h1>Cookies</h1>
3
- <p class="description">
4
- This is the cookies are saved on your system and it contains the preferences
5
- you chose in the settings page
6
- </p>
7
- <input type="text" name="cookie_field" value="" readonly />
8
- <p class="description">
9
- The cookies stored are not used by us for any malicious intend or for
10
- tracking you in any way.
11
- </p>
12
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
public/templates/engines_tab.html DELETED
@@ -1,32 +0,0 @@
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
6
- from
7
- </p>
8
- <div class="engine_selection">
9
- <div class="toggle_btn">
10
- <label class="switch">
11
- <input type="checkbox" class="select_all" onchange="toggleAllSelection()" />
12
- <span class="slider round"></span>
13
- </label>
14
- Select All
15
- </div>
16
- <hr />
17
- <div class="toggle_btn">
18
- <label class="switch">
19
- <input type="checkbox" class="engine" />
20
- <span class="slider round"></span>
21
- </label>
22
- DuckDuckGo
23
- </div>
24
- <div class="toggle_btn">
25
- <label class="switch">
26
- <input type="checkbox" class="engine" />
27
- <span class="slider round"></span>
28
- </label>
29
- Searx
30
- </div>
31
- </div>
32
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/templates/footer.html DELETED
@@ -1,16 +0,0 @@
1
- <footer>
2
- <div>
3
- <span>Powered By <b>Websurfx</b></span><span>-</span><span>a lightening fast, privacy respecting, secure meta
4
- search engine</span>
5
- </div>
6
- <div>
7
- <ul>
8
- <li><a href="https://github.com/neon-mmd/websurfx">Source Code</a></li>
9
- <li><a href="https://github.com/neon-mmd/websurfx/issues">Issues/Bugs</a></li>
10
- </ul>
11
- </div>
12
- </footer>
13
- <script src="static/settings.js"></script>
14
- </body>
15
-
16
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/templates/general_tab.html DELETED
@@ -1,13 +0,0 @@
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/header.html DELETED
@@ -1,16 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
-
4
- <head>
5
- <title>Websurfx</title>
6
- <meta charset="UTF-8" />
7
- <meta name="viewport" content="width=device-width, initial-scale=1" />
8
- <link href="static/colorschemes/{{colorscheme}}.css" rel="stylesheet" type="text/css" />
9
- <link href="static/themes/{{theme}}.css" rel="stylesheet" type="text/css" />
10
- </head>
11
-
12
- <body onload="getClientSettings()">
13
- <header>
14
- <h1><a href="/">Websurfx</a></h1>
15
- {{>navbar}}
16
- </header>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/templates/index.html DELETED
@@ -1,8 +0,0 @@
1
- {{>header this}}
2
- <main class="search-container">
3
- <img src="../images/websurfx_logo.png" alt="Websurfx meta-search engine logo" />
4
- {{>bar}}
5
- </div>
6
- </main>
7
- <script src="static/index.js"></script>
8
- {{>footer}}
 
 
 
 
 
 
 
 
 
public/templates/navbar.html DELETED
@@ -1,6 +0,0 @@
1
- <nav>
2
- <ul>
3
- <li><a href="about">about</a></li>
4
- <li><a href="settings">settings</a></li>
5
- </ul>
6
- </nav>
 
 
 
 
 
 
 
public/templates/search.html DELETED
@@ -1,86 +0,0 @@
1
- {{>header this.style}}
2
- <main class="results">
3
- {{>search_bar this}}
4
- <div class="results_aggregated">
5
- {{#if results}} {{#each results}}
6
- <div class="result">
7
- <h1><a href="{{{this.url}}}">{{{this.title}}}</a></h1>
8
- <small>{{{this.url}}}</small>
9
- <p>{{{this.description}}}</p>
10
- <div class="upstream_engines">
11
- {{#each engine}}
12
- <span>{{{this}}}</span>
13
- {{/each}}
14
- </div>
15
- </div>
16
- {{/each}} {{else}} {{#if disallowed}}
17
- <div class="result_disallowed">
18
- <div class="description">
19
- <p>
20
- Your search - <span class="user_query">{{{this.pageQuery}}}</span> -
21
- has been disallowed.
22
- </p>
23
- <p class="description_paragraph">Dear user,</p>
24
- <p class="description_paragraph">
25
- The query - <span class="user_query">{{{this.pageQuery}}}</span> - has
26
- been blacklisted via server configuration and hence disallowed by the
27
- server. Henceforth no results could be displayed for your query.
28
- </p>
29
- </div>
30
- <img src="./images/barricade.png" alt="Image of a Barricade" />
31
- </div>
32
- {{else}} {{#if filtered}}
33
- <div class="result_filtered">
34
- <div class="description">
35
- <p>
36
- Your search - <span class="user_query">{{{this.pageQuery}}}</span> -
37
- has been filtered.
38
- </p>
39
- <p class="description_paragraph">Dear user,</p>
40
- <p class="description_paragraph">
41
- All the search results contain results that has been configured to be
42
- filtered out via server configuration and henceforth has been
43
- completely filtered out.
44
- </p>
45
- </div>
46
- <img src="./images/filter.png" alt="Image of a paper inside a funnel" />
47
- </div>
48
- {{else}} {{#if noEnginesSelected}}
49
- <div class="result_engine_not_selected">
50
- <div class="description">
51
- <p>
52
- No results could be fetched for your search "<span class="user_query">{{{this.pageQuery}}}</span>" .
53
- </p>
54
- <p class="description_paragraph">Dear user,</p>
55
- <p class="description_paragraph">
56
- No results could be retrieved from the upstream search engines as no
57
- upstream search engines were selected from the settings page.
58
- </p>
59
- </div>
60
- <img src="./images/no_selection.png" alt="Image of a white cross inside a red circle" />
61
- </div>
62
- {{else}}
63
- <div class="result_not_found">
64
- <p>Your search - {{{this.pageQuery}}} - did not match any documents.</p>
65
- <p class="suggestions">Suggestions:</p>
66
- <ul>
67
- <li>Make sure that all words are spelled correctly.</li>
68
- <li>Try different keywords.</li>
69
- <li>Try more general keywords.</li>
70
- </ul>
71
- <img src="./images/no_results.gif" alt="Man fishing gif" />
72
- </div>
73
- {{/if}} {{/if}} {{/if}} {{/if}}
74
- </div>
75
- <div class="page_navigation">
76
- <button type="button" onclick="navigate_backward()">
77
- &#8592; previous
78
- </button>
79
- <button type="button" onclick="navigate_forward()">next &#8594;</button>
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 DELETED
@@ -1,36 +0,0 @@
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/settings.html DELETED
@@ -1,22 +0,0 @@
1
- {{>header this}}
2
- <main class="settings" >
3
- <h1>Settings</h1>
4
- <hr />
5
- <div class="settings_container">
6
- <div class="sidebar">
7
- <div class="btn active" onclick="setActiveTab(this)">general</div>
8
- <div class="btn" onclick="setActiveTab(this)">user interface</div>
9
- <div class="btn" onclick="setActiveTab(this)">engines</div>
10
- <div class="btn" onclick="setActiveTab(this)">cookies</div>
11
- </div>
12
- <div class="main_container">
13
- {{> general_tab}} {{> user_interface_tab}} {{> engines_tab}} {{>
14
- cookies_tab}}
15
- <p class="message"></p>
16
- <button type="submit" onclick="setClientSettings()">Save</button>
17
- </div>
18
- </div>
19
- </main>
20
- <script src="static/settings.js"></script>
21
- <script src="static/cookies.js"></script>
22
- {{>footer}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/templates/user_interface_tab.html DELETED
@@ -1,28 +0,0 @@
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
6
- </p>
7
- <select name="themes">
8
- <option value="simple">simple</option>
9
- </select>
10
- <h3>select color scheme</h3>
11
- <p class="description">
12
- Select the color scheme for your theme to be used in user interface
13
- </p>
14
- <select name="colorschemes">
15
- <option value="catppuccin-mocha">catppuccin mocha</option>
16
- <option value="dark-chocolate">dark chocolate</option>
17
- <option value="dracula">dracula</option>
18
- <option value="gruvbox-dark">gruvbox dark</option>
19
- <option value="monokai">monokai</option>
20
- <option value="nord">nord</option>
21
- <option value="oceanic-next">oceanic next</option>
22
- <option value="one-dark">one dark</option>
23
- <option value="solarized-dark">solarized dark</option>
24
- <option value="solarized-light">solarized light</option>
25
- <option value="tokyo-night">tokyo night</option>
26
- <option value="tomorrow-night">tomorrow night</option>
27
- </select>
28
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/config/parser.rs CHANGED
@@ -3,7 +3,6 @@
3
 
4
  use crate::handler::paths::{file_path, FileType};
5
 
6
- use crate::models::engine_models::{EngineError, EngineHandler};
7
  use crate::models::parser_models::{AggregatorConfig, RateLimiter, Style};
8
  use log::LevelFilter;
9
  use mlua::Lua;
@@ -29,7 +28,7 @@ pub struct Config {
29
  /// It stores the option to whether enable or disable debug mode.
30
  pub debug: bool,
31
  /// It stores all the engine names that were enabled by the user.
32
- pub upstream_search_engines: Vec<EngineHandler>,
33
  /// It stores the time (secs) which controls the server request timeout.
34
  pub request_timeout: u8,
35
  /// It stores the number of threads which controls the app will use to run.
@@ -109,11 +108,7 @@ impl Config {
109
  logging,
110
  debug,
111
  upstream_search_engines: globals
112
- .get::<_, HashMap<String, bool>>("upstream_search_engines")?
113
- .into_iter()
114
- .filter_map(|(key, value)| value.then_some(key))
115
- .map(|engine| EngineHandler::new(&engine))
116
- .collect::<Result<Vec<EngineHandler>, error_stack::Report<EngineError>>>()?,
117
  request_timeout: globals.get::<_, u8>("request_timeout")?,
118
  threads,
119
  rate_limiter: RateLimiter {
 
3
 
4
  use crate::handler::paths::{file_path, FileType};
5
 
 
6
  use crate::models::parser_models::{AggregatorConfig, RateLimiter, Style};
7
  use log::LevelFilter;
8
  use mlua::Lua;
 
28
  /// It stores the option to whether enable or disable debug mode.
29
  pub debug: bool,
30
  /// It stores all the engine names that were enabled by the user.
31
+ pub upstream_search_engines: HashMap<String, bool>,
32
  /// It stores the time (secs) which controls the server request timeout.
33
  pub request_timeout: u8,
34
  /// It stores the number of threads which controls the app will use to run.
 
108
  logging,
109
  debug,
110
  upstream_search_engines: globals
111
+ .get::<_, HashMap<String, bool>>("upstream_search_engines")?,
 
 
 
 
112
  request_timeout: globals.get::<_, u8>("request_timeout")?,
113
  threads,
114
  rate_limiter: RateLimiter {
src/lib.rs CHANGED
@@ -12,6 +12,7 @@ pub mod handler;
12
  pub mod models;
13
  pub mod results;
14
  pub mod server;
 
15
 
16
  use std::net::TcpListener;
17
 
@@ -23,7 +24,6 @@ use actix_governor::{Governor, GovernorConfigBuilder};
23
  use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer};
24
  use cache::cacher::{Cache, SharedCache};
25
  use config::parser::Config;
26
- use handlebars::Handlebars;
27
  use handler::paths::{file_path, FileType};
28
 
29
  /// Runs the web server on the provided TCP listener and returns a `Server` instance.
@@ -48,16 +48,8 @@ use handler::paths::{file_path, FileType};
48
  /// let server = run(listener,config,cache).expect("Failed to start server");
49
  /// ```
50
  pub fn run(listener: TcpListener, config: Config, cache: Cache) -> std::io::Result<Server> {
51
- let mut handlebars: Handlebars<'_> = Handlebars::new();
52
-
53
  let public_folder_path: &str = file_path(FileType::Theme)?;
54
 
55
- handlebars
56
- .register_templates_directory(".html", format!("{}/templates", public_folder_path))
57
- .unwrap();
58
-
59
- let handlebars_ref: web::Data<Handlebars<'_>> = web::Data::new(handlebars);
60
-
61
  let cloned_config_threads_opt: u8 = config.threads;
62
 
63
  let cache = web::Data::new(SharedCache::new(cache));
@@ -75,7 +67,6 @@ pub fn run(listener: TcpListener, config: Config, cache: Cache) -> std::io::Resu
75
 
76
  App::new()
77
  .wrap(Logger::default()) // added logging middleware for logging.
78
- .app_data(handlebars_ref.clone())
79
  .app_data(web::Data::new(config.clone()))
80
  .app_data(cache.clone())
81
  .wrap(cors)
 
12
  pub mod models;
13
  pub mod results;
14
  pub mod server;
15
+ pub mod templates;
16
 
17
  use std::net::TcpListener;
18
 
 
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.
 
48
  /// let server = run(listener,config,cache).expect("Failed to start server");
49
  /// ```
50
  pub fn run(listener: TcpListener, config: Config, cache: Cache) -> std::io::Result<Server> {
 
 
51
  let public_folder_path: &str = file_path(FileType::Theme)?;
52
 
 
 
 
 
 
 
53
  let cloned_config_threads_opt: u8 = config.threads;
54
 
55
  let cache = web::Data::new(SharedCache::new(cache));
 
67
 
68
  App::new()
69
  .wrap(Logger::default()) // added logging middleware for logging.
 
70
  .app_data(web::Data::new(config.clone()))
71
  .app_data(cache.clone())
72
  .wrap(cors)
src/models/aggregation_models.rs CHANGED
@@ -1,11 +1,10 @@
1
  //! This module provides public models for handling, storing and serializing of search results
2
  //! data scraped from the upstream search engines.
3
 
 
4
  use serde::{Deserialize, Serialize};
5
  use smallvec::SmallVec;
6
 
7
- use super::{engine_models::EngineError, parser_models::Style};
8
-
9
  /// A named struct to store the raw scraped search results scraped search results from the
10
  /// upstream search engines before aggregating it.It derives the Clone trait which is needed
11
  /// to write idiomatic rust using `Iterators`.
@@ -109,10 +108,6 @@ impl EngineErrorInfo {
109
  pub struct SearchResults {
110
  /// Stores the individual serializable `SearchResult` struct into a vector of
111
  pub results: Vec<SearchResult>,
112
- /// Stores the current pages search query `q` provided in the search url.
113
- pub page_query: String,
114
- /// Stores the theming options for the website.
115
- pub style: Style,
116
  /// Stores the information on which engines failed with their engine name
117
  /// and the type of error that caused it.
118
  pub engine_errors_info: Vec<EngineErrorInfo>,
@@ -142,15 +137,9 @@ impl SearchResults {
142
  /// the search url.
143
  /// * `engine_errors_info` - Takes an array of structs which contains information regarding
144
  /// which engines failed with their names, reason and their severity color name.
145
- pub fn new(
146
- results: Vec<SearchResult>,
147
- page_query: &str,
148
- engine_errors_info: &[EngineErrorInfo],
149
- ) -> Self {
150
  Self {
151
  results,
152
- page_query: page_query.to_owned(),
153
- style: Style::default(),
154
  engine_errors_info: engine_errors_info.to_owned(),
155
  disallowed: Default::default(),
156
  filtered: Default::default(),
@@ -159,21 +148,11 @@ impl SearchResults {
159
  }
160
  }
161
 
162
- /// A setter function to add website style to the return search results.
163
- pub fn add_style(&mut self, style: &Style) {
164
- self.style = style.clone();
165
- }
166
-
167
  /// A setter function that sets disallowed to true.
168
  pub fn set_disallowed(&mut self) {
169
  self.disallowed = true;
170
  }
171
 
172
- /// A setter function to set the current page search query.
173
- pub fn set_page_query(&mut self, page: &str) {
174
- self.page_query = page.to_owned();
175
- }
176
-
177
  /// A setter function that sets the filtered to true.
178
  pub fn set_filtered(&mut self) {
179
  self.filtered = true;
 
1
  //! This module provides public models for handling, storing and serializing of search results
2
  //! data scraped from the upstream search engines.
3
 
4
+ use super::engine_models::EngineError;
5
  use serde::{Deserialize, Serialize};
6
  use smallvec::SmallVec;
7
 
 
 
8
  /// A named struct to store the raw scraped search results scraped search results from the
9
  /// upstream search engines before aggregating it.It derives the Clone trait which is needed
10
  /// to write idiomatic rust using `Iterators`.
 
108
  pub struct SearchResults {
109
  /// Stores the individual serializable `SearchResult` struct into a vector of
110
  pub results: Vec<SearchResult>,
 
 
 
 
111
  /// Stores the information on which engines failed with their engine name
112
  /// and the type of error that caused it.
113
  pub engine_errors_info: Vec<EngineErrorInfo>,
 
137
  /// the search url.
138
  /// * `engine_errors_info` - Takes an array of structs which contains information regarding
139
  /// which engines failed with their names, reason and their severity color name.
140
+ pub fn new(results: Vec<SearchResult>, engine_errors_info: &[EngineErrorInfo]) -> Self {
 
 
 
 
141
  Self {
142
  results,
 
 
143
  engine_errors_info: engine_errors_info.to_owned(),
144
  disallowed: Default::default(),
145
  filtered: Default::default(),
 
148
  }
149
  }
150
 
 
 
 
 
 
151
  /// A setter function that sets disallowed to true.
152
  pub fn set_disallowed(&mut self) {
153
  self.disallowed = true;
154
  }
155
 
 
 
 
 
 
156
  /// A setter function that sets the filtered to true.
157
  pub fn set_filtered(&mut self) {
158
  self.filtered = true;
src/models/parser_models.rs CHANGED
@@ -1,8 +1,6 @@
1
  //! This module provides public models for handling, storing and serializing parsed config file
2
  //! options from config.lua by grouping them together.
3
 
4
- use serde::{Deserialize, Serialize};
5
-
6
  /// A named struct which stores,deserializes, serializes and groups the parsed config file options
7
  /// of theme and colorscheme names into the Style struct which derives the `Clone`, `Serialize`
8
  /// and Deserialize traits where the `Clone` trait is derived for allowing the struct to be
@@ -12,7 +10,7 @@ use serde::{Deserialize, Serialize};
12
  /// order to allow the deserializing the json back to struct in aggregate function in
13
  /// aggregator.rs and create a new struct out of it and then serialize it back to json and pass
14
  /// it to the template files.
15
- #[derive(Serialize, Deserialize, Clone, Default)]
16
  pub struct Style {
17
  /// It stores the parsed theme option used to set a theme for the website.
18
  pub theme: String,
 
1
  //! This module provides public models for handling, storing and serializing parsed config file
2
  //! options from config.lua by grouping them together.
3
 
 
 
4
  /// A named struct which stores,deserializes, serializes and groups the parsed config file options
5
  /// of theme and colorscheme names into the Style struct which derives the `Clone`, `Serialize`
6
  /// and Deserialize traits where the `Clone` trait is derived for allowing the struct to be
 
10
  /// order to allow the deserializing the json back to struct in aggregate function in
11
  /// aggregator.rs and create a new struct out of it and then serialize it back to json and pass
12
  /// it to the template files.
13
+ #[derive(Clone, Default)]
14
  pub struct Style {
15
  /// It stores the parsed theme option used to set a theme for the website.
16
  pub theme: String,
src/results/aggregator.rs CHANGED
@@ -166,7 +166,7 @@ pub async fn aggregate(
166
 
167
  let results: Vec<SearchResult> = result_map.into_values().collect();
168
 
169
- Ok(SearchResults::new(results, query, &engine_errors_info))
170
  }
171
 
172
  /// Filters a map of search results using a list of regex patterns.
 
166
 
167
  let results: Vec<SearchResult> = result_map.into_values().collect();
168
 
169
+ Ok(SearchResults::new(results, &engine_errors_info))
170
  }
171
 
172
  /// Filters a map of search results using a list of regex patterns.
src/server/router.rs CHANGED
@@ -7,30 +7,30 @@ use crate::{
7
  handler::paths::{file_path, FileType},
8
  };
9
  use actix_web::{get, web, HttpRequest, HttpResponse};
10
- use handlebars::Handlebars;
11
  use std::fs::read_to_string;
12
 
13
  /// Handles the route of index page or main page of the `websurfx` meta search engine website.
14
  #[get("/")]
15
- pub async fn index(
16
- hbs: web::Data<Handlebars<'_>>,
17
- config: web::Data<Config>,
18
- ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
19
- let page_content: String = hbs.render("index", &config.style).unwrap();
20
- Ok(HttpResponse::Ok().body(page_content))
21
  }
22
 
23
  /// Handles the route of any other accessed route/page which is not provided by the
24
  /// website essentially the 404 error page.
25
  pub async fn not_found(
26
- hbs: web::Data<Handlebars<'_>>,
27
  config: web::Data<Config>,
28
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
29
- let page_content: String = hbs.render("404", &config.style)?;
30
-
31
  Ok(HttpResponse::Ok()
32
  .content_type("text/html; charset=utf-8")
33
- .body(page_content))
 
 
 
 
 
 
34
  }
35
 
36
  /// Handles the route of robots.txt page of the `websurfx` meta search engine website.
@@ -45,20 +45,26 @@ pub async fn robots_data(_req: HttpRequest) -> Result<HttpResponse, Box<dyn std:
45
 
46
  /// Handles the route of about page of the `websurfx` meta search engine website.
47
  #[get("/about")]
48
- pub async fn about(
49
- hbs: web::Data<Handlebars<'_>>,
50
- config: web::Data<Config>,
51
- ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
52
- let page_content: String = hbs.render("about", &config.style)?;
53
- Ok(HttpResponse::Ok().body(page_content))
54
  }
55
 
56
  /// Handles the route of settings page of the `websurfx` meta search engine website.
57
  #[get("/settings")]
58
  pub async fn settings(
59
- hbs: web::Data<Handlebars<'_>>,
60
  config: web::Data<Config>,
61
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
62
- let page_content: String = hbs.render("settings", &config.style)?;
63
- Ok(HttpResponse::Ok().body(page_content))
 
 
 
 
 
 
 
 
 
64
  }
 
7
  handler::paths::{file_path, FileType},
8
  };
9
  use actix_web::{get, web, HttpRequest, HttpResponse};
 
10
  use std::fs::read_to_string;
11
 
12
  /// Handles the route of index page or main page of the `websurfx` meta search engine website.
13
  #[get("/")]
14
+ pub async fn index(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn std::error::Error>> {
15
+ Ok(HttpResponse::Ok().body(
16
+ crate::templates::views::index::index(&config.style.colorscheme, &config.style.theme).0,
17
+ ))
 
 
18
  }
19
 
20
  /// Handles the route of any other accessed route/page which is not provided by the
21
  /// website essentially the 404 error page.
22
  pub async fn not_found(
 
23
  config: web::Data<Config>,
24
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
 
 
25
  Ok(HttpResponse::Ok()
26
  .content_type("text/html; charset=utf-8")
27
+ .body(
28
+ crate::templates::views::not_found::not_found(
29
+ &config.style.colorscheme,
30
+ &config.style.theme,
31
+ )
32
+ .0,
33
+ ))
34
  }
35
 
36
  /// Handles the route of robots.txt page of the `websurfx` meta search engine website.
 
45
 
46
  /// Handles the route of about page of the `websurfx` meta search engine website.
47
  #[get("/about")]
48
+ pub async fn about(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn std::error::Error>> {
49
+ Ok(HttpResponse::Ok().body(
50
+ crate::templates::views::about::about(&config.style.colorscheme, &config.style.theme).0,
51
+ ))
 
 
52
  }
53
 
54
  /// Handles the route of settings page of the `websurfx` meta search engine website.
55
  #[get("/settings")]
56
  pub async fn settings(
 
57
  config: web::Data<Config>,
58
  ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
59
+ Ok(HttpResponse::Ok().body(
60
+ crate::templates::views::settings::settings(
61
+ &config.style.colorscheme,
62
+ &config.style.theme,
63
+ &config
64
+ .upstream_search_engines
65
+ .keys()
66
+ .collect::<Vec<&String>>(),
67
+ )?
68
+ .0,
69
+ ))
70
  }
src/server/routes/search.rs CHANGED
@@ -6,13 +6,12 @@ use crate::{
6
  handler::paths::{file_path, FileType},
7
  models::{
8
  aggregation_models::SearchResults,
9
- engine_models::EngineHandler,
10
  server_models::{Cookie, SearchParams},
11
  },
12
  results::aggregator::aggregate,
13
  };
14
  use actix_web::{get, web, HttpRequest, HttpResponse};
15
- use handlebars::Handlebars;
16
  use regex::Regex;
17
  use std::{
18
  fs::File,
@@ -20,19 +19,6 @@ use std::{
20
  };
21
  use tokio::join;
22
 
23
- /// Handles the route of any other accessed route/page which is not provided by the
24
- /// website essentially the 404 error page.
25
- pub async fn not_found(
26
- hbs: web::Data<Handlebars<'_>>,
27
- config: web::Data<Config>,
28
- ) -> Result<HttpResponse, Box<dyn std::error::Error>> {
29
- let page_content: String = hbs.render("404", &config.style)?;
30
-
31
- Ok(HttpResponse::Ok()
32
- .content_type("text/html; charset=utf-8")
33
- .body(page_content))
34
- }
35
-
36
  /// Handles the route of search page of the `websurfx` meta search engine website and it takes
37
  /// two search url parameters `q` and `page` where `page` parameter is optional.
38
  ///
@@ -49,7 +35,6 @@ pub async fn not_found(
49
  /// ```
50
  #[get("/search")]
51
  pub async fn search(
52
- hbs: web::Data<Handlebars<'_>>,
53
  req: HttpRequest,
54
  config: web::Data<Config>,
55
  cache: web::Data<SharedCache>,
@@ -58,7 +43,7 @@ pub async fn search(
58
  match &params.q {
59
  Some(query) => {
60
  if query.trim().is_empty() {
61
- return Ok(HttpResponse::Found()
62
  .insert_header(("location", "/"))
63
  .finish());
64
  }
@@ -112,10 +97,17 @@ pub async fn search(
112
  )
113
  );
114
 
115
- let page_content: String = hbs.render("search", &results?)?;
116
- Ok(HttpResponse::Ok().body(page_content))
 
 
 
 
 
 
 
117
  }
118
- None => Ok(HttpResponse::Found()
119
  .insert_header(("location", "/"))
120
  .finish()),
121
  }
@@ -171,8 +163,6 @@ async fn results(
171
 
172
  if _flag {
173
  results.set_disallowed();
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);
@@ -221,23 +211,27 @@ async fn results(
221
  true => {
222
  let mut search_results = SearchResults::default();
223
  search_results.set_no_engines_selected();
224
- search_results.set_page_query(query);
225
  search_results
226
  }
227
  }
228
  }
229
- None => {
230
- aggregate(
231
- query,
232
- page,
233
- config.aggregator.random_delay,
234
- config.debug,
235
- &config.upstream_search_engines,
236
- config.request_timeout,
237
- safe_search_level,
238
- )
239
- .await?
240
- }
 
 
 
 
 
241
  };
242
  if results.engine_errors_info().is_empty()
243
  && results.results().is_empty()
@@ -245,7 +239,6 @@ async fn results(
245
  {
246
  results.set_filtered();
247
  }
248
- results.add_style(&config.style);
249
  cache
250
  .cache_results(&results, &(format!("{url}{safe_search_level}")))
251
  .await?;
 
6
  handler::paths::{file_path, FileType},
7
  models::{
8
  aggregation_models::SearchResults,
9
+ engine_models::{EngineError, EngineHandler},
10
  server_models::{Cookie, SearchParams},
11
  },
12
  results::aggregator::aggregate,
13
  };
14
  use actix_web::{get, web, HttpRequest, HttpResponse};
 
15
  use regex::Regex;
16
  use std::{
17
  fs::File,
 
19
  };
20
  use tokio::join;
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  /// Handles the route of search page of the `websurfx` meta search engine website and it takes
23
  /// two search url parameters `q` and `page` where `page` parameter is optional.
24
  ///
 
35
  /// ```
36
  #[get("/search")]
37
  pub async fn search(
 
38
  req: HttpRequest,
39
  config: web::Data<Config>,
40
  cache: web::Data<SharedCache>,
 
43
  match &params.q {
44
  Some(query) => {
45
  if query.trim().is_empty() {
46
+ return Ok(HttpResponse::TemporaryRedirect()
47
  .insert_header(("location", "/"))
48
  .finish());
49
  }
 
97
  )
98
  );
99
 
100
+ Ok(HttpResponse::Ok().body(
101
+ crate::templates::views::search::search(
102
+ &config.style.colorscheme,
103
+ &config.style.theme,
104
+ query,
105
+ &results?,
106
+ )
107
+ .0,
108
+ ))
109
  }
110
+ None => Ok(HttpResponse::TemporaryRedirect()
111
  .insert_header(("location", "/"))
112
  .finish()),
113
  }
 
163
 
164
  if _flag {
165
  results.set_disallowed();
 
 
166
  cache.cache_results(&results, &url).await?;
167
  results.set_safe_search_level(safe_search_level);
168
  return Ok(results);
 
211
  true => {
212
  let mut search_results = SearchResults::default();
213
  search_results.set_no_engines_selected();
 
214
  search_results
215
  }
216
  }
217
  }
218
+ None => aggregate(
219
+ query,
220
+ page,
221
+ config.aggregator.random_delay,
222
+ config.debug,
223
+ &config
224
+ .upstream_search_engines
225
+ .clone()
226
+ .into_iter()
227
+ .filter_map(|(key, value)| value.then_some(key))
228
+ .map(|engine| EngineHandler::new(&engine))
229
+ .collect::<Result<Vec<EngineHandler>, error_stack::Report<EngineError>>>(
230
+ )?,
231
+ config.request_timeout,
232
+ safe_search_level,
233
+ )
234
+ .await?,
235
  };
236
  if results.engine_errors_info().is_empty()
237
  && results.results().is_empty()
 
239
  {
240
  results.set_filtered();
241
  }
 
242
  cache
243
  .cache_results(&results, &(format!("{url}{safe_search_level}")))
244
  .await?;
src/templates/mod.rs ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ //! This module provides other modules to handle both the view and its partials for the `websurfx`
2
+ //! search engine frontend.
3
+
4
+ mod partials;
5
+ pub mod views;
src/templates/partials/bar.rs ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles `bar` partial for the `search_bar` partial and the home/index/main page in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup, PreEscaped};
4
+
5
+ /// A functions that handles the html code for the bar for the `search_bar` partial and the
6
+ /// home/index/main page in the search engine frontend.
7
+ ///
8
+ /// # Arguments
9
+ ///
10
+ /// * `query` - It takes the current search query provided by user as an argument.
11
+ ///
12
+ /// # Returns
13
+ ///
14
+ /// It returns the compiled html code for the search bar as a result.
15
+ pub fn bar(query: &str) -> Markup {
16
+ html!(
17
+ (PreEscaped("<div class=\"search_bar\">"))
18
+ input type="search" name="search-box" value=(query) placeholder="Type to search";
19
+ button type="submit" onclick="searchWeb()"{"search"}
20
+ )
21
+ }
src/templates/partials/footer.rs ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the footer for all the pages in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup, PreEscaped};
4
+
5
+ /// A functions that handles the html code for the footer for all the pages in the search engine
6
+ /// frontend.
7
+ ///
8
+ /// # Returns
9
+ ///
10
+ /// It returns the compiled html code for the footer as a result.
11
+ pub fn footer() -> Markup {
12
+ html!(
13
+ footer{
14
+ div{
15
+ span{"Powered By "b{"Websurfx"}}span{"-"}span{"a lightening fast, privacy respecting, secure meta
16
+ search engine"}
17
+ }
18
+ div{
19
+ ul{
20
+ li{a href="https://github.com/neon-mmd/websurfx"{"Source Code"}}
21
+ li{a href="https://github.com/neon-mmd/websurfx/issues"{"Issues/Bugs"}}
22
+ }
23
+ }
24
+ }
25
+ script src="static/settings.js"{}
26
+ (PreEscaped("</body>"))
27
+ (PreEscaped("</html>"))
28
+ )
29
+ }
src/templates/partials/header.rs ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the header for all the pages in the `websurfx` frontend.
2
+
3
+ use crate::templates::partials::navbar::navbar;
4
+ use maud::{html, Markup, PreEscaped, DOCTYPE};
5
+
6
+ /// A function that handles the html code for the header for all the pages in the search engine frontend.
7
+ ///
8
+ /// # Arguments
9
+ ///
10
+ /// * `colorscheme` - It takes the colorscheme name as an argument.
11
+ /// * `theme` - It takes the theme name as an argument.
12
+ ///
13
+ /// # Returns
14
+ ///
15
+ /// It returns the compiled html markup code for the header as a result.
16
+ pub fn header(colorscheme: &str, theme: &str) -> Markup {
17
+ html!(
18
+ (DOCTYPE)
19
+ html lang="en"
20
+
21
+ head{
22
+ title{"Websurfx"}
23
+ meta charset="UTF-8";
24
+ meta name="viewport" content="width=device-width, initial-scale=1";
25
+ link href=(format!("static/colorschemes/{colorscheme}.css")) rel="stylesheet" type="text/css";
26
+ link href=(format!("static/themes/{theme}.css")) rel="stylesheet" type="text/css";
27
+ }
28
+
29
+ (PreEscaped("<body onload=\"getClientSettings()\">"))
30
+ header{
31
+ h1{a href="/"{"Websurfx"}}
32
+ (navbar())
33
+ }
34
+ )
35
+ }
src/templates/partials/mod.rs ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ //! This module provides other modules to handle the partials for the views in the `websurfx` frontend.
2
+
3
+ pub mod bar;
4
+ pub mod footer;
5
+ pub mod header;
6
+ pub mod navbar;
7
+ pub mod search_bar;
8
+ pub mod settings_tabs;
src/templates/partials/navbar.rs ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles `navbar` partial for the header partial in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup};
4
+
5
+ /// A functions that handles the html code for the header partial.
6
+ ///
7
+ /// # Returns
8
+ ///
9
+ /// It returns the compiled html code for the navbar as a result.
10
+ pub fn navbar() -> Markup {
11
+ html!(
12
+ nav{
13
+ ul{
14
+ li{a href="about"{"about"}}
15
+ li{a href="settings"{"settings"}}
16
+ }
17
+ }
18
+ )
19
+ }
src/templates/partials/search_bar.rs ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles `search bar` partial for the search page in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup, PreEscaped};
4
+
5
+ use crate::{models::aggregation_models::EngineErrorInfo, templates::partials::bar::bar};
6
+
7
+ /// A constant holding the named safe search level options for the corresponding values 0, 1 and 2.
8
+ const SAFE_SEARCH_LEVELS_NAME: [&str; 3] = ["None", "Low", "Moderate"];
9
+
10
+ /// A functions that handles the html code for the search bar for the search page.
11
+ ///
12
+ /// # Arguments
13
+ ///
14
+ /// * `engine_errors_info` - It takes the engine errors list containing errors for each upstream
15
+ /// search engine which failed to provide results as an argument.
16
+ /// * `safe_search_level` - It takes the safe search level with values from 0-2 as an argument.
17
+ /// * `query` - It takes the current search query provided by user as an argument.
18
+ ///
19
+ /// # Returns
20
+ ///
21
+ /// It returns the compiled html code for the search bar as a result.
22
+ pub fn search_bar(
23
+ engine_errors_info: &[EngineErrorInfo],
24
+ safe_search_level: u8,
25
+ query: &str,
26
+ ) -> Markup {
27
+ html!(
28
+ .search_area{
29
+ (bar(query))
30
+ .error_box {
31
+ @if !engine_errors_info.is_empty(){
32
+ button onclick="toggleErrorBox()" class="error_box_toggle_button"{
33
+ img src="./images/warning.svg" alt="Info icon for error box";
34
+ }
35
+ .dropdown_error_box{
36
+ @for errors in engine_errors_info{
37
+ .error_item{
38
+ span class="engine_name"{(errors.engine)}
39
+ span class="engine_name"{(errors.error)}
40
+ span class="severity_color" style="background: {{{this.severity_color}}};"{}
41
+ }
42
+ }
43
+ }
44
+ }
45
+ @else {
46
+ button onclick="toggleErrorBox()" class="error_box_toggle_button"{
47
+ img src="./images/info.svg" alt="Warning icon for error box";
48
+ }
49
+ .dropdown_error_box {
50
+ .no_errors{
51
+ "Everything looks good 🙂!!"
52
+ }
53
+ }
54
+ }
55
+ }
56
+ (PreEscaped("</div>"))
57
+ .search_options {
58
+ @if safe_search_level >= 3 {
59
+ (PreEscaped("<select name=\"safe_search_levels\" disabled>"))
60
+ }
61
+ @else{
62
+ (PreEscaped("<select name=\"safe_search_levels\">"))
63
+ }
64
+ @for (idx, name) in SAFE_SEARCH_LEVELS_NAME.iter().enumerate() {
65
+ @if (safe_search_level as usize) == idx {
66
+ option value=(idx) selected {(format!("SafeSearch: {name}"))}
67
+ }
68
+ @else{
69
+ option value=(idx) {(format!("SafeSearch: {name}"))}
70
+ }
71
+ }
72
+ (PreEscaped("</select>"))
73
+ }
74
+ }
75
+ )
76
+ }
src/templates/partials/settings_tabs/cookies.rs ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the engines tab for setting page view in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup};
4
+
5
+ /// A functions that handles the html code for the cookies tab for the settings page for the search page.
6
+ ///
7
+ /// # Returns
8
+ ///
9
+ /// It returns the compiled html markup code for the cookies tab.
10
+ pub fn cookies() -> Markup {
11
+ html!(
12
+ div class="cookies tab"{
13
+ h1{"Cookies"}
14
+ p class="description"{
15
+ "This is the cookies are saved on your system and it contains the preferences
16
+ you chose in the settings page"
17
+ }
18
+ input type="text" name="cookie_field" value="" readonly;
19
+ p class="description"{
20
+ "The cookies stored are not used by us for any malicious intend or for
21
+ tracking you in any way."
22
+ }
23
+ }
24
+ )
25
+ }
src/templates/partials/settings_tabs/engines.rs ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the engines tab for setting page view in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup};
4
+
5
+ /// A functions that handles the html code for the engines tab for the settings page for the search page.
6
+ ///
7
+ /// # Arguments
8
+ ///
9
+ /// * `engine_names` - It takes the list of all available engine names as an argument.
10
+ ///
11
+ /// # Returns
12
+ ///
13
+ /// It returns the compiled html markup code for the engines tab.
14
+ pub fn engines(engine_names: &[&String]) -> Markup {
15
+ html!(
16
+ div class="engines tab"{
17
+ h1{"Engines"}
18
+ h3{"select search engines"}
19
+ p class="description"{
20
+ "Select the search engines from the list of engines that you want results from"
21
+ }
22
+ .engine_selection{
23
+ .toggle_btn{
24
+ label class="switch"{
25
+ input type="checkbox" class="select_all" onchange="toggleAllSelection()";
26
+ span class="slider round"{}
27
+ }
28
+ "Select All"
29
+ }
30
+ hr;
31
+ @for engine_name in engine_names{
32
+ .toggle_btn{
33
+ label class="switch"{
34
+ input type="checkbox" class="engine";
35
+ span class="slider round"{}
36
+ }
37
+ (format!("{}{}",engine_name[..1].to_uppercase().to_owned(), engine_name[1..].to_owned()))
38
+ }
39
+ }
40
+ }
41
+ }
42
+ )
43
+ }
src/templates/partials/settings_tabs/general.rs ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the general tab for setting page view in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup};
4
+
5
+ /// A constant holding the named safe search level options for the corresponding values 0, 1 and 2.
6
+ const SAFE_SEARCH_LEVELS: [(u8, &str); 3] = [(0, "None"), (1, "Low"), (2, "Moderate")];
7
+
8
+ /// A functions that handles the html code for the general tab for the settings page for the search page.
9
+ ///
10
+ /// # Returns
11
+ ///
12
+ /// It returns the compiled html markup code for the general tab.
13
+ pub fn general() -> Markup {
14
+ html!(
15
+ div class="general tab active"{
16
+ h1{"General"}
17
+ h3{"Select a safe search level"}
18
+ p class="description"{
19
+ "Select a safe search level from the menu below to filter content based on the level."
20
+ }
21
+ select name="safe_search_levels"{
22
+ @for (k,v) in SAFE_SEARCH_LEVELS{
23
+ option value=(k){(v)}
24
+ }
25
+ }
26
+ }
27
+ )
28
+ }
src/templates/partials/settings_tabs/mod.rs ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ //! This module provides other modules to handle the partials for the tabs for the settings page
2
+ //! view in the `websurfx` frontend.
3
+
4
+ pub mod cookies;
5
+ pub mod engines;
6
+ pub mod general;
7
+ pub mod user_interface;
src/templates/partials/settings_tabs/user_interface.rs ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
7
+ /// A helper function that helps in building the list of all available colorscheme/theme names
8
+ /// present in the colorschemes and themes folder respectively.
9
+ ///
10
+ /// # Arguments
11
+ ///
12
+ /// * `style_type` - It takes the style type of the values `theme` and `colorscheme` as an
13
+ /// argument.
14
+ ///
15
+ /// # Error
16
+ ///
17
+ /// Returns a list of colorscheme/theme names as a vector of tuple strings on success otherwise
18
+ /// returns a standard error message.
19
+ fn style_option_list(
20
+ style_type: &str,
21
+ ) -> Result<Vec<(String, String)>, Box<dyn std::error::Error + '_>> {
22
+ let mut style_option_names: Vec<(String, String)> = Vec::new();
23
+ for file in read_dir(format!(
24
+ "{}static/{}/",
25
+ file_path(FileType::Theme)?,
26
+ style_type,
27
+ ))? {
28
+ let style_name = file?.file_name().to_str().unwrap().replace(".css", "");
29
+ style_option_names.push((style_name.clone(), style_name.replace('-', " ")));
30
+ }
31
+
32
+ Ok(style_option_names)
33
+ }
34
+
35
+ /// A functions that handles the html code for the user interface tab for the settings page for the search page.
36
+ ///
37
+ /// # Error
38
+ ///
39
+ /// It returns the compiled html markup code for the user interface tab on success otherwise
40
+ /// returns a standard error message.
41
+ pub fn user_interface() -> Result<Markup, Box<dyn std::error::Error>> {
42
+ Ok(html!(
43
+ div class="user_interface tab"{
44
+ h1{"User Interface"}
45
+ h3{"select theme"}
46
+ p class="description"{
47
+ "Select the theme from the available themes to be used in user interface"
48
+ }
49
+ select name="themes"{
50
+ @for (k,v) in style_option_list("themes")?{
51
+ option value=(k){(v)}
52
+ }
53
+ }
54
+ h3{"select color scheme"}
55
+ p class="description"{
56
+ "Select the color scheme for your theme to be used in user interface"
57
+ }
58
+ select name="colorschemes"{
59
+ @for (k,v) in style_option_list("colorschemes")?{
60
+ option value=(k){(v)}
61
+ }
62
+ }
63
+ }
64
+ ))
65
+ }
src/templates/views/about.rs ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the view for the about page in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup};
4
+
5
+ use crate::templates::partials::{footer::footer, header::header};
6
+
7
+ /// A function that handles the html code for the about page view in the search engine frontend.
8
+ ///
9
+ /// # Arguments
10
+ ///
11
+ /// * `colorscheme` - It takes the colorscheme name as an argument.
12
+ /// * `theme` - It takes the theme name as an argument.
13
+ ///
14
+ /// # Returns
15
+ ///
16
+ /// It returns the compiled html markup code as a result.
17
+ pub fn about(colorscheme: &str, theme: &str) -> Markup {
18
+ html!(
19
+ (header(colorscheme, theme))
20
+ main class="about-container"{
21
+ article {
22
+ div{
23
+ h1{"Websurfx"}
24
+ hr size="4" width="100%" color="#a6e3a1"{}
25
+ }
26
+ p{"A modern-looking, lightning-fast, privacy-respecting, secure meta search engine written in Rust. It provides a fast and secure search experience while respecting user privacy."br{}" It aggregates results from multiple search engines and presents them in an unbiased manner, filtering out trackers and ads."
27
+ }
28
+
29
+ h2{"Some of the Top Features:"}
30
+
31
+ ul{strong{"Lightning fast "}"- Results load within milliseconds for an instant search experience."}
32
+
33
+ ul{strong{"Secure search"}" - All searches are performed over an encrypted connection to prevent snooping."}
34
+
35
+ ul{strong{"Ad free results"}" - All search results are ad free and clutter free for a clean search experience."}
36
+
37
+ ul{strong{"Privacy focused"}" - Websurfx does not track, store or sell your search data. Your privacy is our priority."}
38
+
39
+ ul{strong{"Free and Open source"}" - The entire project's code is open source and available for free on "{a href="https://github.com/neon-mmd/websurfx"{"GitHub"}}" under an GNU Affero General Public License."}
40
+
41
+ ul{strong{"Highly customizable"}" - Websurfx comes with 9 built-in color themes and supports creating custom themes effortlessly."}
42
+ }
43
+
44
+ h3{"Devoloped by: "{a href="https://github.com/neon-mmd/websurfx"{"Websurfx team"}}}
45
+ }
46
+ (footer())
47
+ )
48
+ }
src/templates/views/index.rs ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the view for the index/home/main page in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup, PreEscaped};
4
+
5
+ use crate::templates::partials::{bar::bar, footer::footer, header::header};
6
+
7
+ /// A function that handles the html code for the index/html/main page view in the search engine frontend.
8
+ ///
9
+ /// # Arguments
10
+ ///
11
+ /// * `colorscheme` - It takes the colorscheme name as an argument.
12
+ /// * `theme` - It takes the theme name as an argument.
13
+ ///
14
+ /// # Returns
15
+ ///
16
+ /// It returns the compiled html markup code as a result.
17
+ pub fn index(colorscheme: &str, theme: &str) -> Markup {
18
+ html!(
19
+ (header(colorscheme, theme))
20
+ main class="search-container"{
21
+ img src="../images/websurfx_logo.png" alt="Websurfx meta-search engine logo";
22
+ (bar(&String::default()))
23
+ (PreEscaped("</div>"))
24
+ }
25
+ script src="static/index.js"{}
26
+ (footer())
27
+ )
28
+ }
src/templates/views/mod.rs ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ //! This module provides other modules to handle view for each individual page in the
2
+ //! `websurfx` frontend.
3
+
4
+ pub mod about;
5
+ pub mod index;
6
+ pub mod not_found;
7
+ pub mod search;
8
+ pub mod settings;
src/templates/views/not_found.rs ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the view for the 404 page in the `websurfx` frontend.
2
+
3
+ use crate::templates::partials::{footer::footer, header::header};
4
+ use maud::{html, Markup};
5
+
6
+ /// A function that handles the html code for the 404 page view in the search engine frontend.
7
+ ///
8
+ /// # Arguments
9
+ ///
10
+ /// * `colorscheme` - It takes the colorscheme name as an argument.
11
+ /// * `theme` - It takes the theme name as an argument.
12
+ ///
13
+ /// # Returns
14
+ ///
15
+ /// It returns the compiled html markup code as a result.
16
+ pub fn not_found(colorscheme: &str, theme: &str) -> Markup {
17
+ html!(
18
+ (header(colorscheme, theme))
19
+ main class="error_container"{
20
+ img src="images/robot-404.svg" alt="Image of broken robot.";
21
+ .error_content{
22
+ h1{"Aw! snap"}
23
+ h2{"404 Page Not Found!"}
24
+ p{"Go to "{a href="/"{"search page"}}}
25
+ }
26
+ }
27
+ (footer())
28
+ )
29
+ }
src/templates/views/search.rs ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the view for the search page in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup, PreEscaped};
4
+
5
+ use crate::{
6
+ models::aggregation_models::SearchResults,
7
+ templates::partials::{footer::footer, header::header, search_bar::search_bar},
8
+ };
9
+
10
+ /// A function that handles the html code for the search page view in the search engine frontend.
11
+ ///
12
+ /// # Arguments
13
+ ///
14
+ /// * `colorscheme` - It takes the colorscheme name as an argument.
15
+ /// * `theme` - It takes the theme name as an argument.
16
+ /// * `query` - It takes the current search query provided by the user as an argument.
17
+ /// * `search_results` - It takes the aggregated search results as an argument.
18
+ ///
19
+ /// # Returns
20
+ ///
21
+ /// It returns the compiled html markup code as a result.
22
+ pub fn search(
23
+ colorscheme: &str,
24
+ theme: &str,
25
+ query: &str,
26
+ search_results: &SearchResults,
27
+ ) -> Markup {
28
+ html!(
29
+ (header(colorscheme, theme))
30
+ main class="results"{
31
+ (search_bar(&search_results.engine_errors_info, search_results.safe_search_level, query))
32
+ .results_aggregated{
33
+ @if !search_results.results.is_empty() {
34
+ @for result in search_results.results.iter(){
35
+ .result {
36
+ h1{a href=(result.url){(PreEscaped(&result.title))}}
37
+ small{(result.url)}
38
+ p{(PreEscaped(&result.description))}
39
+ .upstream_engines{
40
+ @for name in result.clone().engine{
41
+ span{(name)}
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ @else if search_results.disallowed{
48
+ .result_disallowed{
49
+ .description{
50
+ p{
51
+ "Your search - "{span class="user_query"{(query)}}" -
52
+ has been disallowed."
53
+ }
54
+ p class="description_paragraph"{"Dear user,"}
55
+ p class="description_paragraph"{
56
+ "The query - "{span class="user_query"{(query)}}" - has
57
+ been blacklisted via server configuration and hence disallowed by the
58
+ server. Henceforth no results could be displayed for your query."
59
+ }
60
+ }
61
+ img src="./images/barricade.png" alt="Image of a Barricade";
62
+ }
63
+ }
64
+ @else if search_results.filtered {
65
+ .result_filtered{
66
+ .description{
67
+ p{
68
+ "Your search - "{span class="user_query"{(query)}}" -
69
+ has been filtered."
70
+ }
71
+ p class="description_paragraph"{"Dear user,"}
72
+ p class="description_paragraph"{
73
+ "All the search results contain results that has been configured to be
74
+ filtered out via server configuration and henceforth has been
75
+ completely filtered out."
76
+ }
77
+ }
78
+ img src="./images/filter.png" alt="Image of a paper inside a funnel";
79
+ }
80
+ }
81
+ @else if search_results.no_engines_selected {
82
+ .result_engine_not_selected{
83
+ .description{
84
+ p{
85
+ "No results could be fetched for your search '{span class="user_query"{(query)}}'."
86
+ }
87
+ p class="description_paragraph"{"Dear user,"}
88
+ p class="description_paragraph"{
89
+ "No results could be retrieved from the upstream search engines as no
90
+ upstream search engines were selected from the settings page."
91
+ }
92
+ }
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:"}
100
+ ul{
101
+ li{"Make sure that all words are spelled correctly."}
102
+ li{"Try different keywords."}
103
+ li{"Try more general keywords."}
104
+ }
105
+ img src="./images/no_results.gif" alt="Man fishing gif";
106
+ }
107
+ }
108
+ }
109
+ .page_navigation {
110
+ button type="button" onclick="navigate_backward()"{
111
+ (PreEscaped("&#8592;")) "previous"
112
+ }
113
+ button type="button" onclick="navigate_forward()"{"next" (PreEscaped("&#8594;"))}
114
+ }
115
+ }
116
+ script src="static/index.js"{}
117
+ script src="static/search_area_options.js"{}
118
+ script src="static/pagination.js"{}
119
+ script src="static/error_box.js"{}
120
+ (footer())
121
+ )
122
+ }
src/templates/views/settings.rs ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! A module that handles the view for the settings page in the `websurfx` frontend.
2
+
3
+ use maud::{html, Markup};
4
+
5
+ use crate::templates::partials::{
6
+ footer::footer,
7
+ header::header,
8
+ settings_tabs::{
9
+ cookies::cookies, engines::engines, general::general, user_interface::user_interface,
10
+ },
11
+ };
12
+
13
+ /// A function that handles the html code for the settings page view in the search engine frontend.
14
+ ///
15
+ /// # Arguments
16
+ ///
17
+ /// * `colorscheme` - It takes the colorscheme name as an argument.
18
+ /// * `theme` - It takes the theme name as an argument.
19
+ /// * `engine_names` - It takes a list of engine names as an argument.
20
+ ///
21
+ /// # Error
22
+ ///
23
+ /// This function returns a compiled html markup code on success otherwise returns a standard error
24
+ /// message.
25
+ pub fn settings(
26
+ colorscheme: &str,
27
+ theme: &str,
28
+ engine_names: &[&String],
29
+ ) -> Result<Markup, Box<dyn std::error::Error>> {
30
+ Ok(html!(
31
+ (header(colorscheme, theme))
32
+ main class="settings"{
33
+ h1{"Settings"}
34
+ hr;
35
+ .settings_container{
36
+ .sidebar{
37
+ div class="btn active" onclick="setActiveTab(this)"{"general"}
38
+ .btn onclick="setActiveTab(this)"{"user interface"}
39
+ .btn onclick="setActiveTab(this)"{"engines"}
40
+ .btn onclick="setActiveTab(this)"{"cookies"}
41
+ }
42
+ .main_container{
43
+ (general())
44
+ (user_interface()?)
45
+ (engines(engine_names))
46
+ (cookies())
47
+ p class="message"{}
48
+ button type="submit" onclick="setClientSettings()"{"Save"}
49
+ }
50
+ }
51
+ }
52
+ script src="static/settings.js"{}
53
+ script src="static/cookies.js"{}
54
+ (footer())
55
+ ))
56
+ }
tests/index.rs CHANGED
@@ -1,7 +1,6 @@
1
  use std::net::TcpListener;
2
 
3
- use handlebars::Handlebars;
4
- use websurfx::{config::parser::Config, run};
5
 
6
  // Starts a new instance of the HTTP server, bound to a random available port
7
  fn spawn_app() -> String {
@@ -21,18 +20,6 @@ fn spawn_app() -> String {
21
  format!("http://127.0.0.1:{}/", port)
22
  }
23
 
24
- // Creates a new instance of Handlebars and registers the templates directory.
25
- // This is used to compare the rendered template with the response body.
26
- fn handlebars() -> Handlebars<'static> {
27
- let mut handlebars = Handlebars::new();
28
-
29
- handlebars
30
- .register_templates_directory(".html", "./public/templates")
31
- .unwrap();
32
-
33
- handlebars
34
- }
35
-
36
  #[tokio::test]
37
  async fn test_index() {
38
  let address = spawn_app();
@@ -41,9 +28,8 @@ async fn test_index() {
41
  let res = client.get(address).send().await.unwrap();
42
  assert_eq!(res.status(), 200);
43
 
44
- let handlebars = handlebars();
45
  let config = Config::parse(true).unwrap();
46
- let template = handlebars.render("index", &config.style).unwrap();
47
  assert_eq!(res.text().await.unwrap(), template);
48
  }
49
 
 
1
  use std::net::TcpListener;
2
 
3
+ use websurfx::{config::parser::Config, run, templates::views};
 
4
 
5
  // Starts a new instance of the HTTP server, bound to a random available port
6
  fn spawn_app() -> String {
 
20
  format!("http://127.0.0.1:{}/", port)
21
  }
22
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  #[tokio::test]
24
  async fn test_index() {
25
  let address = spawn_app();
 
28
  let res = client.get(address).send().await.unwrap();
29
  assert_eq!(res.status(), 200);
30
 
 
31
  let config = Config::parse(true).unwrap();
32
+ let template = views::index::index(&config.style.colorscheme, &config.style.theme).0;
33
  assert_eq!(res.text().await.unwrap(), template);
34
  }
35