Spaces:
Runtime error
Runtime error
Merge branch 'rolling' into feat-error-box-for-engine-errors
Browse files- .cspell.json +5 -1
- Cargo.lock +125 -116
- Cargo.toml +15 -15
- public/templates/search.html +1 -1
- src/bin/websurfx.rs +1 -1
- src/config/parser.rs +28 -18
- src/engines/duckduckgo.rs +4 -4
- src/engines/engine_models.rs +37 -5
- src/engines/searx.rs +4 -4
- src/results/aggregation_models.rs +9 -62
- src/results/aggregator.rs +65 -115
- src/server/routes.rs +50 -7
- tests/index.rs +2 -2
.cspell.json
CHANGED
@@ -11,6 +11,10 @@
|
|
11 |
],
|
12 |
"language": "en",
|
13 |
"noConfigSearch": true,
|
14 |
-
"words": [
|
|
|
|
|
|
|
|
|
15 |
"version": "0.2"
|
16 |
}
|
|
|
11 |
],
|
12 |
"language": "en",
|
13 |
"noConfigSearch": true,
|
14 |
+
"words": [
|
15 |
+
"megalinter",
|
16 |
+
"oxsecurity",
|
17 |
+
"websurfx"
|
18 |
+
],
|
19 |
"version": "0.2"
|
20 |
}
|
Cargo.lock
CHANGED
@@ -14,7 +14,7 @@ dependencies = [
|
|
14 |
"futures-sink",
|
15 |
"memchr",
|
16 |
"pin-project-lite",
|
17 |
-
"tokio 1.
|
18 |
"tokio-util",
|
19 |
"tracing",
|
20 |
]
|
@@ -90,7 +90,7 @@ dependencies = [
|
|
90 |
"rand 0.8.5",
|
91 |
"sha1",
|
92 |
"smallvec 1.11.0",
|
93 |
-
"tokio 1.
|
94 |
"tokio-util",
|
95 |
"tracing",
|
96 |
"zstd",
|
@@ -102,8 +102,8 @@ version = "0.2.4"
|
|
102 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
103 |
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
104 |
dependencies = [
|
105 |
-
"quote 1.0.
|
106 |
-
"syn 2.0.
|
107 |
]
|
108 |
|
109 |
[[package]]
|
@@ -126,7 +126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
126 |
checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e"
|
127 |
dependencies = [
|
128 |
"futures-core",
|
129 |
-
"tokio 1.
|
130 |
]
|
131 |
|
132 |
[[package]]
|
@@ -142,8 +142,8 @@ dependencies = [
|
|
142 |
"futures-util",
|
143 |
"mio 0.8.8",
|
144 |
"num_cpus",
|
145 |
-
"socket2",
|
146 |
-
"tokio 1.
|
147 |
"tracing",
|
148 |
]
|
149 |
|
@@ -204,7 +204,7 @@ dependencies = [
|
|
204 |
"serde_json",
|
205 |
"serde_urlencoded 0.7.1",
|
206 |
"smallvec 1.11.0",
|
207 |
-
"socket2",
|
208 |
"time 0.3.25",
|
209 |
"url 2.4.0",
|
210 |
]
|
@@ -217,7 +217,7 @@ checksum = "2262160a7ae29e3415554a3f1fc04c764b1540c116aa524683208078b7a75bc9"
|
|
217 |
dependencies = [
|
218 |
"actix-router",
|
219 |
"proc-macro2 1.0.66",
|
220 |
-
"quote 1.0.
|
221 |
"syn 1.0.109",
|
222 |
]
|
223 |
|
@@ -261,9 +261,9 @@ dependencies = [
|
|
261 |
|
262 |
[[package]]
|
263 |
name = "aho-corasick"
|
264 |
-
version = "1.0.
|
265 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
266 |
-
checksum = "
|
267 |
dependencies = [
|
268 |
"memchr",
|
269 |
]
|
@@ -297,9 +297,9 @@ checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd"
|
|
297 |
|
298 |
[[package]]
|
299 |
name = "anyhow"
|
300 |
-
version = "1.0.
|
301 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
302 |
-
checksum = "
|
303 |
|
304 |
[[package]]
|
305 |
name = "askama_escape"
|
@@ -309,13 +309,13 @@ checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
|
309 |
|
310 |
[[package]]
|
311 |
name = "async-trait"
|
312 |
-
version = "0.1.
|
313 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
314 |
-
checksum = "
|
315 |
dependencies = [
|
316 |
"proc-macro2 1.0.66",
|
317 |
-
"quote 1.0.
|
318 |
-
"syn 2.0.
|
319 |
]
|
320 |
|
321 |
[[package]]
|
@@ -386,9 +386,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|
386 |
|
387 |
[[package]]
|
388 |
name = "bitflags"
|
389 |
-
version = "2.
|
390 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
391 |
-
checksum = "
|
392 |
|
393 |
[[package]]
|
394 |
name = "block-buffer"
|
@@ -475,9 +475,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
|
475 |
|
476 |
[[package]]
|
477 |
name = "cc"
|
478 |
-
version = "1.0.
|
479 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
480 |
-
checksum = "
|
481 |
dependencies = [
|
482 |
"jobserver",
|
483 |
"libc",
|
@@ -533,18 +533,18 @@ dependencies = [
|
|
533 |
|
534 |
[[package]]
|
535 |
name = "clap"
|
536 |
-
version = "4.3.
|
537 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
538 |
-
checksum = "
|
539 |
dependencies = [
|
540 |
"clap_builder",
|
541 |
]
|
542 |
|
543 |
[[package]]
|
544 |
name = "clap_builder"
|
545 |
-
version = "4.3.
|
546 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
547 |
-
checksum = "
|
548 |
dependencies = [
|
549 |
"anstyle",
|
550 |
"clap_lex",
|
@@ -810,8 +810,8 @@ version = "0.6.1"
|
|
810 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
811 |
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
812 |
dependencies = [
|
813 |
-
"quote 1.0.
|
814 |
-
"syn 2.0.
|
815 |
]
|
816 |
|
817 |
[[package]]
|
@@ -828,7 +828,7 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
|
828 |
dependencies = [
|
829 |
"convert_case",
|
830 |
"proc-macro2 1.0.66",
|
831 |
-
"quote 1.0.
|
832 |
"rustc_version 0.4.0",
|
833 |
"syn 1.0.109",
|
834 |
]
|
@@ -956,7 +956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
956 |
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
957 |
dependencies = [
|
958 |
"proc-macro2 1.0.66",
|
959 |
-
"quote 1.0.
|
960 |
"syn 1.0.109",
|
961 |
"synstructure",
|
962 |
]
|
@@ -980,9 +980,9 @@ checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
|
980 |
|
981 |
[[package]]
|
982 |
name = "flate2"
|
983 |
-
version = "1.0.
|
984 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
985 |
-
checksum = "
|
986 |
dependencies = [
|
987 |
"crc32fast",
|
988 |
"miniz_oxide",
|
@@ -1188,7 +1188,7 @@ dependencies = [
|
|
1188 |
"http 0.2.9",
|
1189 |
"indexmap",
|
1190 |
"slab",
|
1191 |
-
"tokio 1.
|
1192 |
"tokio-util",
|
1193 |
"tracing",
|
1194 |
]
|
@@ -1250,7 +1250,7 @@ dependencies = [
|
|
1250 |
"mac",
|
1251 |
"markup5ever 0.11.0",
|
1252 |
"proc-macro2 1.0.66",
|
1253 |
-
"quote 1.0.
|
1254 |
"syn 1.0.109",
|
1255 |
]
|
1256 |
|
@@ -1313,9 +1313,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
|
1313 |
|
1314 |
[[package]]
|
1315 |
name = "httpdate"
|
1316 |
-
version = "1.0.
|
1317 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1318 |
-
checksum = "
|
1319 |
|
1320 |
[[package]]
|
1321 |
name = "humantime"
|
@@ -1370,8 +1370,8 @@ dependencies = [
|
|
1370 |
"httpdate",
|
1371 |
"itoa 1.0.9",
|
1372 |
"pin-project-lite",
|
1373 |
-
"socket2",
|
1374 |
-
"tokio 1.
|
1375 |
"tower-service",
|
1376 |
"tracing",
|
1377 |
"want 0.3.1",
|
@@ -1399,7 +1399,7 @@ dependencies = [
|
|
1399 |
"bytes 1.4.0",
|
1400 |
"hyper 0.14.27",
|
1401 |
"native-tls",
|
1402 |
-
"tokio 1.
|
1403 |
"tokio-native-tls",
|
1404 |
]
|
1405 |
|
@@ -1583,9 +1583,9 @@ dependencies = [
|
|
1583 |
|
1584 |
[[package]]
|
1585 |
name = "log"
|
1586 |
-
version = "0.4.
|
1587 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1588 |
-
checksum = "
|
1589 |
|
1590 |
[[package]]
|
1591 |
name = "mac"
|
@@ -1817,9 +1817,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
|
1817 |
|
1818 |
[[package]]
|
1819 |
name = "openssl"
|
1820 |
-
version = "0.10.
|
1821 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1822 |
-
checksum = "
|
1823 |
dependencies = [
|
1824 |
"bitflags 1.3.2",
|
1825 |
"cfg-if 1.0.0",
|
@@ -1837,8 +1837,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1837 |
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
1838 |
dependencies = [
|
1839 |
"proc-macro2 1.0.66",
|
1840 |
-
"quote 1.0.
|
1841 |
-
"syn 2.0.
|
1842 |
]
|
1843 |
|
1844 |
[[package]]
|
@@ -1849,9 +1849,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
|
1849 |
|
1850 |
[[package]]
|
1851 |
name = "openssl-sys"
|
1852 |
-
version = "0.9.
|
1853 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1854 |
-
checksum = "
|
1855 |
dependencies = [
|
1856 |
"cc",
|
1857 |
"libc",
|
@@ -1955,8 +1955,8 @@ dependencies = [
|
|
1955 |
"pest",
|
1956 |
"pest_meta",
|
1957 |
"proc-macro2 1.0.66",
|
1958 |
-
"quote 1.0.
|
1959 |
-
"syn 2.0.
|
1960 |
]
|
1961 |
|
1962 |
[[package]]
|
@@ -2057,8 +2057,8 @@ dependencies = [
|
|
2057 |
"phf_generator 0.11.2",
|
2058 |
"phf_shared 0.11.2",
|
2059 |
"proc-macro2 1.0.66",
|
2060 |
-
"quote 1.0.
|
2061 |
-
"syn 2.0.
|
2062 |
]
|
2063 |
|
2064 |
[[package]]
|
@@ -2090,9 +2090,9 @@ dependencies = [
|
|
2090 |
|
2091 |
[[package]]
|
2092 |
name = "pin-project-lite"
|
2093 |
-
version = "0.2.
|
2094 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2095 |
-
checksum = "
|
2096 |
|
2097 |
[[package]]
|
2098 |
name = "pin-utils"
|
@@ -2185,9 +2185,9 @@ dependencies = [
|
|
2185 |
|
2186 |
[[package]]
|
2187 |
name = "quote"
|
2188 |
-
version = "1.0.
|
2189 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2190 |
-
checksum = "
|
2191 |
dependencies = [
|
2192 |
"proc-macro2 1.0.66",
|
2193 |
]
|
@@ -2361,16 +2361,16 @@ dependencies = [
|
|
2361 |
|
2362 |
[[package]]
|
2363 |
name = "redis"
|
2364 |
-
version = "0.23.
|
2365 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2366 |
-
checksum = "
|
2367 |
dependencies = [
|
2368 |
"combine",
|
2369 |
"itoa 1.0.9",
|
2370 |
"percent-encoding 2.3.0",
|
2371 |
"ryu",
|
2372 |
"sha1_smol",
|
2373 |
-
"socket2",
|
2374 |
"url 2.4.0",
|
2375 |
]
|
2376 |
|
@@ -2479,7 +2479,7 @@ dependencies = [
|
|
2479 |
"serde",
|
2480 |
"serde_json",
|
2481 |
"serde_urlencoded 0.7.1",
|
2482 |
-
"tokio 1.
|
2483 |
"tokio-native-tls",
|
2484 |
"tower-service",
|
2485 |
"url 2.4.0",
|
@@ -2539,11 +2539,11 @@ dependencies = [
|
|
2539 |
|
2540 |
[[package]]
|
2541 |
name = "rustix"
|
2542 |
-
version = "0.38.
|
2543 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2544 |
-
checksum = "
|
2545 |
dependencies = [
|
2546 |
-
"bitflags 2.
|
2547 |
"errno",
|
2548 |
"libc",
|
2549 |
"linux-raw-sys",
|
@@ -2648,7 +2648,7 @@ version = "0.25.0"
|
|
2648 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2649 |
checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06"
|
2650 |
dependencies = [
|
2651 |
-
"bitflags 2.
|
2652 |
"cssparser",
|
2653 |
"derive_more",
|
2654 |
"fxhash",
|
@@ -2684,29 +2684,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|
2684 |
|
2685 |
[[package]]
|
2686 |
name = "serde"
|
2687 |
-
version = "1.0.
|
2688 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2689 |
-
checksum = "
|
2690 |
dependencies = [
|
2691 |
"serde_derive",
|
2692 |
]
|
2693 |
|
2694 |
[[package]]
|
2695 |
name = "serde_derive"
|
2696 |
-
version = "1.0.
|
2697 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2698 |
-
checksum = "
|
2699 |
dependencies = [
|
2700 |
"proc-macro2 1.0.66",
|
2701 |
-
"quote 1.0.
|
2702 |
-
"syn 2.0.
|
2703 |
]
|
2704 |
|
2705 |
[[package]]
|
2706 |
name = "serde_json"
|
2707 |
-
version = "1.0.
|
2708 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2709 |
-
checksum = "
|
2710 |
dependencies = [
|
2711 |
"itoa 1.0.9",
|
2712 |
"ryu",
|
@@ -2829,6 +2829,16 @@ dependencies = [
|
|
2829 |
"winapi 0.3.9",
|
2830 |
]
|
2831 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2832 |
[[package]]
|
2833 |
name = "stable_deref_trait"
|
2834 |
version = "1.2.0"
|
@@ -2882,7 +2892,7 @@ dependencies = [
|
|
2882 |
"phf_generator 0.7.24",
|
2883 |
"phf_shared 0.7.24",
|
2884 |
"proc-macro2 1.0.66",
|
2885 |
-
"quote 1.0.
|
2886 |
"string_cache_shared",
|
2887 |
]
|
2888 |
|
@@ -2895,7 +2905,7 @@ dependencies = [
|
|
2895 |
"phf_generator 0.10.0",
|
2896 |
"phf_shared 0.10.0",
|
2897 |
"proc-macro2 1.0.66",
|
2898 |
-
"quote 1.0.
|
2899 |
]
|
2900 |
|
2901 |
[[package]]
|
@@ -2922,18 +2932,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2922 |
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
2923 |
dependencies = [
|
2924 |
"proc-macro2 1.0.66",
|
2925 |
-
"quote 1.0.
|
2926 |
"unicode-ident",
|
2927 |
]
|
2928 |
|
2929 |
[[package]]
|
2930 |
name = "syn"
|
2931 |
-
version = "2.0.
|
2932 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2933 |
-
checksum = "
|
2934 |
dependencies = [
|
2935 |
"proc-macro2 1.0.66",
|
2936 |
-
"quote 1.0.
|
2937 |
"unicode-ident",
|
2938 |
]
|
2939 |
|
@@ -2944,16 +2954,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2944 |
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
2945 |
dependencies = [
|
2946 |
"proc-macro2 1.0.66",
|
2947 |
-
"quote 1.0.
|
2948 |
"syn 1.0.109",
|
2949 |
"unicode-xid 0.2.4",
|
2950 |
]
|
2951 |
|
2952 |
[[package]]
|
2953 |
name = "tempfile"
|
2954 |
-
version = "3.
|
2955 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2956 |
-
checksum = "
|
2957 |
dependencies = [
|
2958 |
"cfg-if 1.0.0",
|
2959 |
"fastrand",
|
@@ -2984,22 +2994,22 @@ dependencies = [
|
|
2984 |
|
2985 |
[[package]]
|
2986 |
name = "thiserror"
|
2987 |
-
version = "1.0.
|
2988 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2989 |
-
checksum = "
|
2990 |
dependencies = [
|
2991 |
"thiserror-impl",
|
2992 |
]
|
2993 |
|
2994 |
[[package]]
|
2995 |
name = "thiserror-impl"
|
2996 |
-
version = "1.0.
|
2997 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2998 |
-
checksum = "
|
2999 |
dependencies = [
|
3000 |
"proc-macro2 1.0.66",
|
3001 |
-
"quote 1.0.
|
3002 |
-
"syn 2.0.
|
3003 |
]
|
3004 |
|
3005 |
[[package]]
|
@@ -3087,11 +3097,10 @@ dependencies = [
|
|
3087 |
|
3088 |
[[package]]
|
3089 |
name = "tokio"
|
3090 |
-
version = "1.
|
3091 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3092 |
-
checksum = "
|
3093 |
dependencies = [
|
3094 |
-
"autocfg 1.1.0",
|
3095 |
"backtrace",
|
3096 |
"bytes 1.4.0",
|
3097 |
"libc",
|
@@ -3100,7 +3109,7 @@ dependencies = [
|
|
3100 |
"parking_lot 0.12.1",
|
3101 |
"pin-project-lite",
|
3102 |
"signal-hook-registry",
|
3103 |
-
"socket2",
|
3104 |
"tokio-macros",
|
3105 |
"windows-sys",
|
3106 |
]
|
@@ -3154,8 +3163,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3154 |
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
3155 |
dependencies = [
|
3156 |
"proc-macro2 1.0.66",
|
3157 |
-
"quote 1.0.
|
3158 |
-
"syn 2.0.
|
3159 |
]
|
3160 |
|
3161 |
[[package]]
|
@@ -3165,7 +3174,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3165 |
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
3166 |
dependencies = [
|
3167 |
"native-tls",
|
3168 |
-
"tokio 1.
|
3169 |
]
|
3170 |
|
3171 |
[[package]]
|
@@ -3250,7 +3259,7 @@ dependencies = [
|
|
3250 |
"futures-core",
|
3251 |
"futures-sink",
|
3252 |
"pin-project-lite",
|
3253 |
-
"tokio 1.
|
3254 |
"tracing",
|
3255 |
]
|
3256 |
|
@@ -3476,8 +3485,8 @@ dependencies = [
|
|
3476 |
"log",
|
3477 |
"once_cell",
|
3478 |
"proc-macro2 1.0.66",
|
3479 |
-
"quote 1.0.
|
3480 |
-
"syn 2.0.
|
3481 |
"wasm-bindgen-shared",
|
3482 |
]
|
3483 |
|
@@ -3499,7 +3508,7 @@ version = "0.2.87"
|
|
3499 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3500 |
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
3501 |
dependencies = [
|
3502 |
-
"quote 1.0.
|
3503 |
"wasm-bindgen-macro-support",
|
3504 |
]
|
3505 |
|
@@ -3510,8 +3519,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3510 |
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
3511 |
dependencies = [
|
3512 |
"proc-macro2 1.0.66",
|
3513 |
-
"quote 1.0.
|
3514 |
-
"syn 2.0.
|
3515 |
"wasm-bindgen-backend",
|
3516 |
"wasm-bindgen-shared",
|
3517 |
]
|
@@ -3534,7 +3543,7 @@ dependencies = [
|
|
3534 |
|
3535 |
[[package]]
|
3536 |
name = "websurfx"
|
3537 |
-
version = "0.
|
3538 |
dependencies = [
|
3539 |
"actix-cors",
|
3540 |
"actix-files",
|
@@ -3556,7 +3565,7 @@ dependencies = [
|
|
3556 |
"scraper",
|
3557 |
"serde",
|
3558 |
"serde_json",
|
3559 |
-
"tokio 1.
|
3560 |
]
|
3561 |
|
3562 |
[[package]]
|
@@ -3613,9 +3622,9 @@ dependencies = [
|
|
3613 |
|
3614 |
[[package]]
|
3615 |
name = "windows-targets"
|
3616 |
-
version = "0.48.
|
3617 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3618 |
-
checksum = "
|
3619 |
dependencies = [
|
3620 |
"windows_aarch64_gnullvm",
|
3621 |
"windows_aarch64_msvc",
|
@@ -3628,45 +3637,45 @@ dependencies = [
|
|
3628 |
|
3629 |
[[package]]
|
3630 |
name = "windows_aarch64_gnullvm"
|
3631 |
-
version = "0.48.
|
3632 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3633 |
-
checksum = "
|
3634 |
|
3635 |
[[package]]
|
3636 |
name = "windows_aarch64_msvc"
|
3637 |
-
version = "0.48.
|
3638 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3639 |
-
checksum = "
|
3640 |
|
3641 |
[[package]]
|
3642 |
name = "windows_i686_gnu"
|
3643 |
-
version = "0.48.
|
3644 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3645 |
-
checksum = "
|
3646 |
|
3647 |
[[package]]
|
3648 |
name = "windows_i686_msvc"
|
3649 |
-
version = "0.48.
|
3650 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3651 |
-
checksum = "
|
3652 |
|
3653 |
[[package]]
|
3654 |
name = "windows_x86_64_gnu"
|
3655 |
-
version = "0.48.
|
3656 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3657 |
-
checksum = "
|
3658 |
|
3659 |
[[package]]
|
3660 |
name = "windows_x86_64_gnullvm"
|
3661 |
-
version = "0.48.
|
3662 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3663 |
-
checksum = "
|
3664 |
|
3665 |
[[package]]
|
3666 |
name = "windows_x86_64_msvc"
|
3667 |
-
version = "0.48.
|
3668 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3669 |
-
checksum = "
|
3670 |
|
3671 |
[[package]]
|
3672 |
name = "winreg"
|
|
|
14 |
"futures-sink",
|
15 |
"memchr",
|
16 |
"pin-project-lite",
|
17 |
+
"tokio 1.32.0",
|
18 |
"tokio-util",
|
19 |
"tracing",
|
20 |
]
|
|
|
90 |
"rand 0.8.5",
|
91 |
"sha1",
|
92 |
"smallvec 1.11.0",
|
93 |
+
"tokio 1.32.0",
|
94 |
"tokio-util",
|
95 |
"tracing",
|
96 |
"zstd",
|
|
|
102 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
103 |
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
104 |
dependencies = [
|
105 |
+
"quote 1.0.33",
|
106 |
+
"syn 2.0.29",
|
107 |
]
|
108 |
|
109 |
[[package]]
|
|
|
126 |
checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e"
|
127 |
dependencies = [
|
128 |
"futures-core",
|
129 |
+
"tokio 1.32.0",
|
130 |
]
|
131 |
|
132 |
[[package]]
|
|
|
142 |
"futures-util",
|
143 |
"mio 0.8.8",
|
144 |
"num_cpus",
|
145 |
+
"socket2 0.4.9",
|
146 |
+
"tokio 1.32.0",
|
147 |
"tracing",
|
148 |
]
|
149 |
|
|
|
204 |
"serde_json",
|
205 |
"serde_urlencoded 0.7.1",
|
206 |
"smallvec 1.11.0",
|
207 |
+
"socket2 0.4.9",
|
208 |
"time 0.3.25",
|
209 |
"url 2.4.0",
|
210 |
]
|
|
|
217 |
dependencies = [
|
218 |
"actix-router",
|
219 |
"proc-macro2 1.0.66",
|
220 |
+
"quote 1.0.33",
|
221 |
"syn 1.0.109",
|
222 |
]
|
223 |
|
|
|
261 |
|
262 |
[[package]]
|
263 |
name = "aho-corasick"
|
264 |
+
version = "1.0.4"
|
265 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
266 |
+
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
|
267 |
dependencies = [
|
268 |
"memchr",
|
269 |
]
|
|
|
297 |
|
298 |
[[package]]
|
299 |
name = "anyhow"
|
300 |
+
version = "1.0.75"
|
301 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
302 |
+
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
303 |
|
304 |
[[package]]
|
305 |
name = "askama_escape"
|
|
|
309 |
|
310 |
[[package]]
|
311 |
name = "async-trait"
|
312 |
+
version = "0.1.73"
|
313 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
314 |
+
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
|
315 |
dependencies = [
|
316 |
"proc-macro2 1.0.66",
|
317 |
+
"quote 1.0.33",
|
318 |
+
"syn 2.0.29",
|
319 |
]
|
320 |
|
321 |
[[package]]
|
|
|
386 |
|
387 |
[[package]]
|
388 |
name = "bitflags"
|
389 |
+
version = "2.4.0"
|
390 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
391 |
+
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
392 |
|
393 |
[[package]]
|
394 |
name = "block-buffer"
|
|
|
475 |
|
476 |
[[package]]
|
477 |
name = "cc"
|
478 |
+
version = "1.0.82"
|
479 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
480 |
+
checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01"
|
481 |
dependencies = [
|
482 |
"jobserver",
|
483 |
"libc",
|
|
|
533 |
|
534 |
[[package]]
|
535 |
name = "clap"
|
536 |
+
version = "4.3.23"
|
537 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
538 |
+
checksum = "03aef18ddf7d879c15ce20f04826ef8418101c7e528014c3eeea13321047dca3"
|
539 |
dependencies = [
|
540 |
"clap_builder",
|
541 |
]
|
542 |
|
543 |
[[package]]
|
544 |
name = "clap_builder"
|
545 |
+
version = "4.3.23"
|
546 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
547 |
+
checksum = "f8ce6fffb678c9b80a70b6b6de0aad31df727623a70fd9a842c30cd573e2fa98"
|
548 |
dependencies = [
|
549 |
"anstyle",
|
550 |
"clap_lex",
|
|
|
810 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
811 |
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
812 |
dependencies = [
|
813 |
+
"quote 1.0.33",
|
814 |
+
"syn 2.0.29",
|
815 |
]
|
816 |
|
817 |
[[package]]
|
|
|
828 |
dependencies = [
|
829 |
"convert_case",
|
830 |
"proc-macro2 1.0.66",
|
831 |
+
"quote 1.0.33",
|
832 |
"rustc_version 0.4.0",
|
833 |
"syn 1.0.109",
|
834 |
]
|
|
|
956 |
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
957 |
dependencies = [
|
958 |
"proc-macro2 1.0.66",
|
959 |
+
"quote 1.0.33",
|
960 |
"syn 1.0.109",
|
961 |
"synstructure",
|
962 |
]
|
|
|
980 |
|
981 |
[[package]]
|
982 |
name = "flate2"
|
983 |
+
version = "1.0.27"
|
984 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
985 |
+
checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
|
986 |
dependencies = [
|
987 |
"crc32fast",
|
988 |
"miniz_oxide",
|
|
|
1188 |
"http 0.2.9",
|
1189 |
"indexmap",
|
1190 |
"slab",
|
1191 |
+
"tokio 1.32.0",
|
1192 |
"tokio-util",
|
1193 |
"tracing",
|
1194 |
]
|
|
|
1250 |
"mac",
|
1251 |
"markup5ever 0.11.0",
|
1252 |
"proc-macro2 1.0.66",
|
1253 |
+
"quote 1.0.33",
|
1254 |
"syn 1.0.109",
|
1255 |
]
|
1256 |
|
|
|
1313 |
|
1314 |
[[package]]
|
1315 |
name = "httpdate"
|
1316 |
+
version = "1.0.3"
|
1317 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1318 |
+
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
1319 |
|
1320 |
[[package]]
|
1321 |
name = "humantime"
|
|
|
1370 |
"httpdate",
|
1371 |
"itoa 1.0.9",
|
1372 |
"pin-project-lite",
|
1373 |
+
"socket2 0.4.9",
|
1374 |
+
"tokio 1.32.0",
|
1375 |
"tower-service",
|
1376 |
"tracing",
|
1377 |
"want 0.3.1",
|
|
|
1399 |
"bytes 1.4.0",
|
1400 |
"hyper 0.14.27",
|
1401 |
"native-tls",
|
1402 |
+
"tokio 1.32.0",
|
1403 |
"tokio-native-tls",
|
1404 |
]
|
1405 |
|
|
|
1583 |
|
1584 |
[[package]]
|
1585 |
name = "log"
|
1586 |
+
version = "0.4.20"
|
1587 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1588 |
+
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
1589 |
|
1590 |
[[package]]
|
1591 |
name = "mac"
|
|
|
1817 |
|
1818 |
[[package]]
|
1819 |
name = "openssl"
|
1820 |
+
version = "0.10.56"
|
1821 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1822 |
+
checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e"
|
1823 |
dependencies = [
|
1824 |
"bitflags 1.3.2",
|
1825 |
"cfg-if 1.0.0",
|
|
|
1837 |
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
1838 |
dependencies = [
|
1839 |
"proc-macro2 1.0.66",
|
1840 |
+
"quote 1.0.33",
|
1841 |
+
"syn 2.0.29",
|
1842 |
]
|
1843 |
|
1844 |
[[package]]
|
|
|
1849 |
|
1850 |
[[package]]
|
1851 |
name = "openssl-sys"
|
1852 |
+
version = "0.9.91"
|
1853 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
1854 |
+
checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac"
|
1855 |
dependencies = [
|
1856 |
"cc",
|
1857 |
"libc",
|
|
|
1955 |
"pest",
|
1956 |
"pest_meta",
|
1957 |
"proc-macro2 1.0.66",
|
1958 |
+
"quote 1.0.33",
|
1959 |
+
"syn 2.0.29",
|
1960 |
]
|
1961 |
|
1962 |
[[package]]
|
|
|
2057 |
"phf_generator 0.11.2",
|
2058 |
"phf_shared 0.11.2",
|
2059 |
"proc-macro2 1.0.66",
|
2060 |
+
"quote 1.0.33",
|
2061 |
+
"syn 2.0.29",
|
2062 |
]
|
2063 |
|
2064 |
[[package]]
|
|
|
2090 |
|
2091 |
[[package]]
|
2092 |
name = "pin-project-lite"
|
2093 |
+
version = "0.2.12"
|
2094 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2095 |
+
checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05"
|
2096 |
|
2097 |
[[package]]
|
2098 |
name = "pin-utils"
|
|
|
2185 |
|
2186 |
[[package]]
|
2187 |
name = "quote"
|
2188 |
+
version = "1.0.33"
|
2189 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2190 |
+
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
2191 |
dependencies = [
|
2192 |
"proc-macro2 1.0.66",
|
2193 |
]
|
|
|
2361 |
|
2362 |
[[package]]
|
2363 |
name = "redis"
|
2364 |
+
version = "0.23.2"
|
2365 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2366 |
+
checksum = "ffd6543a7bc6428396845f6854ccf3d1ae8823816592e2cbe74f20f50f209d02"
|
2367 |
dependencies = [
|
2368 |
"combine",
|
2369 |
"itoa 1.0.9",
|
2370 |
"percent-encoding 2.3.0",
|
2371 |
"ryu",
|
2372 |
"sha1_smol",
|
2373 |
+
"socket2 0.4.9",
|
2374 |
"url 2.4.0",
|
2375 |
]
|
2376 |
|
|
|
2479 |
"serde",
|
2480 |
"serde_json",
|
2481 |
"serde_urlencoded 0.7.1",
|
2482 |
+
"tokio 1.32.0",
|
2483 |
"tokio-native-tls",
|
2484 |
"tower-service",
|
2485 |
"url 2.4.0",
|
|
|
2539 |
|
2540 |
[[package]]
|
2541 |
name = "rustix"
|
2542 |
+
version = "0.38.8"
|
2543 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2544 |
+
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
|
2545 |
dependencies = [
|
2546 |
+
"bitflags 2.4.0",
|
2547 |
"errno",
|
2548 |
"libc",
|
2549 |
"linux-raw-sys",
|
|
|
2648 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2649 |
checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06"
|
2650 |
dependencies = [
|
2651 |
+
"bitflags 2.4.0",
|
2652 |
"cssparser",
|
2653 |
"derive_more",
|
2654 |
"fxhash",
|
|
|
2684 |
|
2685 |
[[package]]
|
2686 |
name = "serde"
|
2687 |
+
version = "1.0.183"
|
2688 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2689 |
+
checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c"
|
2690 |
dependencies = [
|
2691 |
"serde_derive",
|
2692 |
]
|
2693 |
|
2694 |
[[package]]
|
2695 |
name = "serde_derive"
|
2696 |
+
version = "1.0.183"
|
2697 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2698 |
+
checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816"
|
2699 |
dependencies = [
|
2700 |
"proc-macro2 1.0.66",
|
2701 |
+
"quote 1.0.33",
|
2702 |
+
"syn 2.0.29",
|
2703 |
]
|
2704 |
|
2705 |
[[package]]
|
2706 |
name = "serde_json"
|
2707 |
+
version = "1.0.105"
|
2708 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2709 |
+
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
|
2710 |
dependencies = [
|
2711 |
"itoa 1.0.9",
|
2712 |
"ryu",
|
|
|
2829 |
"winapi 0.3.9",
|
2830 |
]
|
2831 |
|
2832 |
+
[[package]]
|
2833 |
+
name = "socket2"
|
2834 |
+
version = "0.5.3"
|
2835 |
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2836 |
+
checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
|
2837 |
+
dependencies = [
|
2838 |
+
"libc",
|
2839 |
+
"windows-sys",
|
2840 |
+
]
|
2841 |
+
|
2842 |
[[package]]
|
2843 |
name = "stable_deref_trait"
|
2844 |
version = "1.2.0"
|
|
|
2892 |
"phf_generator 0.7.24",
|
2893 |
"phf_shared 0.7.24",
|
2894 |
"proc-macro2 1.0.66",
|
2895 |
+
"quote 1.0.33",
|
2896 |
"string_cache_shared",
|
2897 |
]
|
2898 |
|
|
|
2905 |
"phf_generator 0.10.0",
|
2906 |
"phf_shared 0.10.0",
|
2907 |
"proc-macro2 1.0.66",
|
2908 |
+
"quote 1.0.33",
|
2909 |
]
|
2910 |
|
2911 |
[[package]]
|
|
|
2932 |
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
2933 |
dependencies = [
|
2934 |
"proc-macro2 1.0.66",
|
2935 |
+
"quote 1.0.33",
|
2936 |
"unicode-ident",
|
2937 |
]
|
2938 |
|
2939 |
[[package]]
|
2940 |
name = "syn"
|
2941 |
+
version = "2.0.29"
|
2942 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2943 |
+
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
|
2944 |
dependencies = [
|
2945 |
"proc-macro2 1.0.66",
|
2946 |
+
"quote 1.0.33",
|
2947 |
"unicode-ident",
|
2948 |
]
|
2949 |
|
|
|
2954 |
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
2955 |
dependencies = [
|
2956 |
"proc-macro2 1.0.66",
|
2957 |
+
"quote 1.0.33",
|
2958 |
"syn 1.0.109",
|
2959 |
"unicode-xid 0.2.4",
|
2960 |
]
|
2961 |
|
2962 |
[[package]]
|
2963 |
name = "tempfile"
|
2964 |
+
version = "3.8.0"
|
2965 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2966 |
+
checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
|
2967 |
dependencies = [
|
2968 |
"cfg-if 1.0.0",
|
2969 |
"fastrand",
|
|
|
2994 |
|
2995 |
[[package]]
|
2996 |
name = "thiserror"
|
2997 |
+
version = "1.0.47"
|
2998 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
2999 |
+
checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
|
3000 |
dependencies = [
|
3001 |
"thiserror-impl",
|
3002 |
]
|
3003 |
|
3004 |
[[package]]
|
3005 |
name = "thiserror-impl"
|
3006 |
+
version = "1.0.47"
|
3007 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3008 |
+
checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
|
3009 |
dependencies = [
|
3010 |
"proc-macro2 1.0.66",
|
3011 |
+
"quote 1.0.33",
|
3012 |
+
"syn 2.0.29",
|
3013 |
]
|
3014 |
|
3015 |
[[package]]
|
|
|
3097 |
|
3098 |
[[package]]
|
3099 |
name = "tokio"
|
3100 |
+
version = "1.32.0"
|
3101 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3102 |
+
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
|
3103 |
dependencies = [
|
|
|
3104 |
"backtrace",
|
3105 |
"bytes 1.4.0",
|
3106 |
"libc",
|
|
|
3109 |
"parking_lot 0.12.1",
|
3110 |
"pin-project-lite",
|
3111 |
"signal-hook-registry",
|
3112 |
+
"socket2 0.5.3",
|
3113 |
"tokio-macros",
|
3114 |
"windows-sys",
|
3115 |
]
|
|
|
3163 |
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
3164 |
dependencies = [
|
3165 |
"proc-macro2 1.0.66",
|
3166 |
+
"quote 1.0.33",
|
3167 |
+
"syn 2.0.29",
|
3168 |
]
|
3169 |
|
3170 |
[[package]]
|
|
|
3174 |
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
3175 |
dependencies = [
|
3176 |
"native-tls",
|
3177 |
+
"tokio 1.32.0",
|
3178 |
]
|
3179 |
|
3180 |
[[package]]
|
|
|
3259 |
"futures-core",
|
3260 |
"futures-sink",
|
3261 |
"pin-project-lite",
|
3262 |
+
"tokio 1.32.0",
|
3263 |
"tracing",
|
3264 |
]
|
3265 |
|
|
|
3485 |
"log",
|
3486 |
"once_cell",
|
3487 |
"proc-macro2 1.0.66",
|
3488 |
+
"quote 1.0.33",
|
3489 |
+
"syn 2.0.29",
|
3490 |
"wasm-bindgen-shared",
|
3491 |
]
|
3492 |
|
|
|
3508 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3509 |
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
3510 |
dependencies = [
|
3511 |
+
"quote 1.0.33",
|
3512 |
"wasm-bindgen-macro-support",
|
3513 |
]
|
3514 |
|
|
|
3519 |
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
3520 |
dependencies = [
|
3521 |
"proc-macro2 1.0.66",
|
3522 |
+
"quote 1.0.33",
|
3523 |
+
"syn 2.0.29",
|
3524 |
"wasm-bindgen-backend",
|
3525 |
"wasm-bindgen-shared",
|
3526 |
]
|
|
|
3543 |
|
3544 |
[[package]]
|
3545 |
name = "websurfx"
|
3546 |
+
version = "0.17.0"
|
3547 |
dependencies = [
|
3548 |
"actix-cors",
|
3549 |
"actix-files",
|
|
|
3565 |
"scraper",
|
3566 |
"serde",
|
3567 |
"serde_json",
|
3568 |
+
"tokio 1.32.0",
|
3569 |
]
|
3570 |
|
3571 |
[[package]]
|
|
|
3622 |
|
3623 |
[[package]]
|
3624 |
name = "windows-targets"
|
3625 |
+
version = "0.48.5"
|
3626 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3627 |
+
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
3628 |
dependencies = [
|
3629 |
"windows_aarch64_gnullvm",
|
3630 |
"windows_aarch64_msvc",
|
|
|
3637 |
|
3638 |
[[package]]
|
3639 |
name = "windows_aarch64_gnullvm"
|
3640 |
+
version = "0.48.5"
|
3641 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3642 |
+
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
3643 |
|
3644 |
[[package]]
|
3645 |
name = "windows_aarch64_msvc"
|
3646 |
+
version = "0.48.5"
|
3647 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3648 |
+
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
3649 |
|
3650 |
[[package]]
|
3651 |
name = "windows_i686_gnu"
|
3652 |
+
version = "0.48.5"
|
3653 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3654 |
+
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
3655 |
|
3656 |
[[package]]
|
3657 |
name = "windows_i686_msvc"
|
3658 |
+
version = "0.48.5"
|
3659 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3660 |
+
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
3661 |
|
3662 |
[[package]]
|
3663 |
name = "windows_x86_64_gnu"
|
3664 |
+
version = "0.48.5"
|
3665 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3666 |
+
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
3667 |
|
3668 |
[[package]]
|
3669 |
name = "windows_x86_64_gnullvm"
|
3670 |
+
version = "0.48.5"
|
3671 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3672 |
+
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
3673 |
|
3674 |
[[package]]
|
3675 |
name = "windows_x86_64_msvc"
|
3676 |
+
version = "0.48.5"
|
3677 |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
3678 |
+
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
3679 |
|
3680 |
[[package]]
|
3681 |
name = "winreg"
|
Cargo.toml
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
[package]
|
2 |
name = "websurfx"
|
3 |
-
version = "0.
|
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"
|
7 |
license = "AGPL-3.0"
|
8 |
|
9 |
[dependencies]
|
10 |
-
reqwest = {version="
|
11 |
-
tokio = {version="
|
12 |
-
serde = {version="
|
13 |
-
handlebars = { version = "4.3.
|
14 |
-
scraper = {version="
|
15 |
actix-web = {version="4.3.1", features = ["cookies"]}
|
16 |
actix-files = {version="0.6.2"}
|
17 |
actix-cors = {version="0.6.4"}
|
18 |
-
serde_json = {version="
|
19 |
-
fake-useragent = {version="
|
20 |
env_logger = {version="0.10.0"}
|
21 |
-
log = {version="0.4.
|
22 |
-
rlua = {version="
|
23 |
-
redis = {version="
|
24 |
-
md5 = {version="
|
25 |
-
rand={version="
|
26 |
-
once_cell = {version="
|
27 |
error-stack = {version="0.3.1"}
|
28 |
-
async-trait = {version="
|
29 |
|
30 |
[dev-dependencies]
|
31 |
rusty-hook = "^0.11.2"
|
|
|
1 |
[package]
|
2 |
name = "websurfx"
|
3 |
+
version = "0.17.0"
|
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"
|
7 |
license = "AGPL-3.0"
|
8 |
|
9 |
[dependencies]
|
10 |
+
reqwest = {version="0.11.18",features=["json"]}
|
11 |
+
tokio = {version="1.32.0",features=["full"]}
|
12 |
+
serde = {version="1.0.183",features=["derive"]}
|
13 |
+
handlebars = { version = "4.3.7", features = ["dir_source"] }
|
14 |
+
scraper = {version="0.17.1"}
|
15 |
actix-web = {version="4.3.1", features = ["cookies"]}
|
16 |
actix-files = {version="0.6.2"}
|
17 |
actix-cors = {version="0.6.4"}
|
18 |
+
serde_json = {version="1.0.105"}
|
19 |
+
fake-useragent = {version="0.1.3"}
|
20 |
env_logger = {version="0.10.0"}
|
21 |
+
log = {version="0.4.20"}
|
22 |
+
rlua = {version="0.19.7"}
|
23 |
+
redis = {version="0.23.2"}
|
24 |
+
md5 = {version="0.7.0"}
|
25 |
+
rand={version="0.8.5"}
|
26 |
+
once_cell = {version="1.18.0"}
|
27 |
error-stack = {version="0.3.1"}
|
28 |
+
async-trait = {version="0.1.73"}
|
29 |
|
30 |
[dev-dependencies]
|
31 |
rusty-hook = "^0.11.2"
|
public/templates/search.html
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
<div class="results_aggregated">
|
5 |
{{#if results}} {{#each results}}
|
6 |
<div class="result">
|
7 |
-
<h1><a href="{{{this.
|
8 |
<small>{{{this.url}}}</small>
|
9 |
<p>{{{this.description}}}</p>
|
10 |
<div class="upstream_engines">
|
|
|
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">
|
src/bin/websurfx.rs
CHANGED
@@ -15,7 +15,7 @@ use websurfx::{config::parser::Config, run};
|
|
15 |
#[actix_web::main]
|
16 |
async fn main() -> std::io::Result<()> {
|
17 |
// Initialize the parsed config file.
|
18 |
-
let config = Config::parse(
|
19 |
|
20 |
log::info!(
|
21 |
"started server on port {} and IP {}",
|
|
|
15 |
#[actix_web::main]
|
16 |
async fn main() -> std::io::Result<()> {
|
17 |
// Initialize the parsed config file.
|
18 |
+
let config = Config::parse(false).unwrap();
|
19 |
|
20 |
log::info!(
|
21 |
"started server on port {} and IP {}",
|
src/config/parser.rs
CHANGED
@@ -34,7 +34,7 @@ pub struct Config {
|
|
34 |
pub aggregator: AggregatorConfig,
|
35 |
pub logging: bool,
|
36 |
pub debug: bool,
|
37 |
-
pub upstream_search_engines: Vec<
|
38 |
pub request_timeout: u8,
|
39 |
pub threads: u8,
|
40 |
}
|
@@ -57,7 +57,7 @@ impl Config {
|
|
57 |
/// # Arguments
|
58 |
///
|
59 |
/// * `logging_initialized` - It takes a boolean which ensures that the logging doesn't get
|
60 |
-
/// initialized twice.
|
61 |
///
|
62 |
/// # Error
|
63 |
///
|
@@ -77,22 +77,8 @@ impl Config {
|
|
77 |
let debug: bool = globals.get::<_, bool>("debug")?;
|
78 |
let logging:bool= globals.get::<_, bool>("logging")?;
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
if let Ok(pkg_env_var) = std::env::var("PKG_ENV"){
|
83 |
-
if pkg_env_var.to_lowercase() == "dev" {
|
84 |
-
env_logger::Builder::new().filter(None, LevelFilter::Trace).init();
|
85 |
-
}
|
86 |
-
} else {
|
87 |
-
// Initializing logging middleware with level set to default or info.
|
88 |
-
let mut log_level: LevelFilter = LevelFilter::Error;
|
89 |
-
if logging && debug == false {
|
90 |
-
log_level = LevelFilter::Info;
|
91 |
-
} else if debug {
|
92 |
-
log_level = LevelFilter::Debug;
|
93 |
-
};
|
94 |
-
env_logger::Builder::new().filter(None, log_level).init();
|
95 |
-
}
|
96 |
}
|
97 |
|
98 |
let threads: u8 = if parsed_threads == 0 {
|
@@ -121,12 +107,14 @@ impl Config {
|
|
121 |
.get::<_, HashMap<String, bool>>("upstream_search_engines")?
|
122 |
.into_iter()
|
123 |
.filter_map(|(key, value)| value.then_some(key))
|
|
|
124 |
.collect(),
|
125 |
request_timeout: globals.get::<_, u8>("request_timeout")?,
|
126 |
threads,
|
127 |
})
|
128 |
})
|
129 |
}
|
|
|
130 |
/// A helper function which returns an appropriate config file path checking if the config
|
131 |
/// file exists on that path.
|
132 |
///
|
@@ -173,3 +161,25 @@ impl Config {
|
|
173 |
Err("Config file not found!!".to_string().into())
|
174 |
}
|
175 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
pub aggregator: AggregatorConfig,
|
35 |
pub logging: bool,
|
36 |
pub debug: bool,
|
37 |
+
pub upstream_search_engines: Vec<crate::engines::engine_models::EngineHandler>,
|
38 |
pub request_timeout: u8,
|
39 |
pub threads: u8,
|
40 |
}
|
|
|
57 |
/// # Arguments
|
58 |
///
|
59 |
/// * `logging_initialized` - It takes a boolean which ensures that the logging doesn't get
|
60 |
+
/// initialized twice. Pass false if the logger has not yet been initialized.
|
61 |
///
|
62 |
/// # Error
|
63 |
///
|
|
|
77 |
let debug: bool = globals.get::<_, bool>("debug")?;
|
78 |
let logging:bool= globals.get::<_, bool>("logging")?;
|
79 |
|
80 |
+
if !logging_initialized {
|
81 |
+
set_logging_level(debug, logging);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
83 |
|
84 |
let threads: u8 = if parsed_threads == 0 {
|
|
|
107 |
.get::<_, HashMap<String, bool>>("upstream_search_engines")?
|
108 |
.into_iter()
|
109 |
.filter_map(|(key, value)| value.then_some(key))
|
110 |
+
.filter_map(|engine| crate::engines::engine_models::EngineHandler::new(&engine))
|
111 |
.collect(),
|
112 |
request_timeout: globals.get::<_, u8>("request_timeout")?,
|
113 |
threads,
|
114 |
})
|
115 |
})
|
116 |
}
|
117 |
+
|
118 |
/// A helper function which returns an appropriate config file path checking if the config
|
119 |
/// file exists on that path.
|
120 |
///
|
|
|
161 |
Err("Config file not found!!".to_string().into())
|
162 |
}
|
163 |
}
|
164 |
+
|
165 |
+
/// a helper function that sets the proper logging level
|
166 |
+
fn set_logging_level(debug: bool, logging: bool) {
|
167 |
+
if let Ok(pkg_env_var) = std::env::var("PKG_ENV") {
|
168 |
+
if pkg_env_var.to_lowercase() == "dev" {
|
169 |
+
env_logger::Builder::new()
|
170 |
+
.filter(None, LevelFilter::Trace)
|
171 |
+
.init();
|
172 |
+
return;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
// Initializing logging middleware with level set to default or info.
|
177 |
+
let log_level = match (debug, logging) {
|
178 |
+
(true, true) => LevelFilter::Debug,
|
179 |
+
(true, false) => LevelFilter::Debug,
|
180 |
+
(false, true) => LevelFilter::Info,
|
181 |
+
(false, false) => LevelFilter::Error,
|
182 |
+
};
|
183 |
+
|
184 |
+
env_logger::Builder::new().filter(None, log_level).init();
|
185 |
+
}
|
src/engines/duckduckgo.rs
CHANGED
@@ -7,7 +7,7 @@ use std::collections::HashMap;
|
|
7 |
use reqwest::header::{HeaderMap, CONTENT_TYPE, COOKIE, REFERER, USER_AGENT};
|
8 |
use scraper::{Html, Selector};
|
9 |
|
10 |
-
use crate::results::aggregation_models::
|
11 |
|
12 |
use super::engine_models::{EngineError, SearchEngine};
|
13 |
|
@@ -43,7 +43,7 @@ impl SearchEngine for DuckDuckGo {
|
|
43 |
page: u32,
|
44 |
user_agent: String,
|
45 |
request_timeout: u8,
|
46 |
-
) -> Result<HashMap<String,
|
47 |
// Page number can be missing or empty string and so appropriate handling is required
|
48 |
// so that upstream server recieves valid page number.
|
49 |
let url: String = match page {
|
@@ -120,7 +120,7 @@ impl SearchEngine for DuckDuckGo {
|
|
120 |
Ok(document
|
121 |
.select(&results)
|
122 |
.map(|result| {
|
123 |
-
|
124 |
result
|
125 |
.select(&result_title)
|
126 |
.next()
|
@@ -147,7 +147,7 @@ impl SearchEngine for DuckDuckGo {
|
|
147 |
vec!["duckduckgo".to_string()],
|
148 |
)
|
149 |
})
|
150 |
-
.map(|search_result| (search_result.
|
151 |
.collect())
|
152 |
}
|
153 |
}
|
|
|
7 |
use reqwest::header::{HeaderMap, CONTENT_TYPE, COOKIE, REFERER, USER_AGENT};
|
8 |
use scraper::{Html, Selector};
|
9 |
|
10 |
+
use crate::results::aggregation_models::SearchResult;
|
11 |
|
12 |
use super::engine_models::{EngineError, SearchEngine};
|
13 |
|
|
|
43 |
page: u32,
|
44 |
user_agent: String,
|
45 |
request_timeout: u8,
|
46 |
+
) -> Result<HashMap<String, SearchResult>, EngineError> {
|
47 |
// Page number can be missing or empty string and so appropriate handling is required
|
48 |
// so that upstream server recieves valid page number.
|
49 |
let url: String = match page {
|
|
|
120 |
Ok(document
|
121 |
.select(&results)
|
122 |
.map(|result| {
|
123 |
+
SearchResult::new(
|
124 |
result
|
125 |
.select(&result_title)
|
126 |
.next()
|
|
|
147 |
vec!["duckduckgo".to_string()],
|
148 |
)
|
149 |
})
|
150 |
+
.map(|search_result| (search_result.url.clone(), search_result))
|
151 |
.collect())
|
152 |
}
|
153 |
}
|
src/engines/engine_models.rs
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
//! This module provides the error enum to handle different errors associated while requesting data from
|
2 |
//! the upstream search engines with the search query provided by the user.
|
3 |
|
4 |
-
use crate::results::aggregation_models::
|
5 |
use error_stack::{IntoReport, Result, ResultExt};
|
6 |
use std::{collections::HashMap, fmt, time::Duration};
|
7 |
|
@@ -43,9 +43,9 @@ impl fmt::Display for EngineError {
|
|
43 |
|
44 |
impl error_stack::Context for EngineError {}
|
45 |
|
46 |
-
/// A trait to define common
|
47 |
#[async_trait::async_trait]
|
48 |
-
pub trait SearchEngine {
|
49 |
async fn fetch_html_from_upstream(
|
50 |
&self,
|
51 |
url: String,
|
@@ -56,7 +56,7 @@ pub trait SearchEngine {
|
|
56 |
Ok(reqwest::Client::new()
|
57 |
.get(url)
|
58 |
.timeout(Duration::from_secs(request_timeout as u64)) // Add timeout to request to avoid DDOSing the server
|
59 |
-
.headers(header_map) // add spoofed headers to emulate human
|
60 |
.send()
|
61 |
.await
|
62 |
.into_report()
|
@@ -73,5 +73,37 @@ pub trait SearchEngine {
|
|
73 |
page: u32,
|
74 |
user_agent: String,
|
75 |
request_timeout: u8,
|
76 |
-
) -> Result<HashMap<String,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
|
|
1 |
//! This module provides the error enum to handle different errors associated while requesting data from
|
2 |
//! the upstream search engines with the search query provided by the user.
|
3 |
|
4 |
+
use crate::results::aggregation_models::SearchResult;
|
5 |
use error_stack::{IntoReport, Result, ResultExt};
|
6 |
use std::{collections::HashMap, fmt, time::Duration};
|
7 |
|
|
|
43 |
|
44 |
impl error_stack::Context for EngineError {}
|
45 |
|
46 |
+
/// A trait to define common behavior for all search engines.
|
47 |
#[async_trait::async_trait]
|
48 |
+
pub trait SearchEngine: Sync + Send {
|
49 |
async fn fetch_html_from_upstream(
|
50 |
&self,
|
51 |
url: String,
|
|
|
56 |
Ok(reqwest::Client::new()
|
57 |
.get(url)
|
58 |
.timeout(Duration::from_secs(request_timeout as u64)) // Add timeout to request to avoid DDOSing the server
|
59 |
+
.headers(header_map) // add spoofed headers to emulate human behavior
|
60 |
.send()
|
61 |
.await
|
62 |
.into_report()
|
|
|
73 |
page: u32,
|
74 |
user_agent: String,
|
75 |
request_timeout: u8,
|
76 |
+
) -> Result<HashMap<String, SearchResult>, EngineError>;
|
77 |
+
}
|
78 |
+
|
79 |
+
pub struct EngineHandler {
|
80 |
+
engine: Box<dyn SearchEngine>,
|
81 |
+
name: &'static str,
|
82 |
+
}
|
83 |
+
|
84 |
+
impl Clone for EngineHandler {
|
85 |
+
fn clone(&self) -> Self {
|
86 |
+
Self::new(self.name).unwrap()
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
impl EngineHandler {
|
91 |
+
/// parses an engine name into an engine handler, returns none if the engine is unknown
|
92 |
+
pub fn new(engine_name: &str) -> Option<Self> {
|
93 |
+
let engine: (&'static str, Box<dyn SearchEngine>) =
|
94 |
+
match engine_name.to_lowercase().as_str() {
|
95 |
+
"duckduckgo" => ("duckduckgo", Box::new(super::duckduckgo::DuckDuckGo)),
|
96 |
+
"searx" => ("searx", Box::new(super::searx::Searx)),
|
97 |
+
_ => return None,
|
98 |
+
};
|
99 |
+
|
100 |
+
Some(Self {
|
101 |
+
engine: engine.1,
|
102 |
+
name: engine.0,
|
103 |
+
})
|
104 |
+
}
|
105 |
+
|
106 |
+
pub fn into_name_engine(self) -> (&'static str, Box<dyn SearchEngine>) {
|
107 |
+
(self.name, self.engine)
|
108 |
+
}
|
109 |
}
|
src/engines/searx.rs
CHANGED
@@ -6,7 +6,7 @@ use reqwest::header::{HeaderMap, CONTENT_TYPE, COOKIE, REFERER, USER_AGENT};
|
|
6 |
use scraper::{Html, Selector};
|
7 |
use std::collections::HashMap;
|
8 |
|
9 |
-
use crate::results::aggregation_models::
|
10 |
|
11 |
use super::engine_models::{EngineError, SearchEngine};
|
12 |
use error_stack::{IntoReport, Report, Result, ResultExt};
|
@@ -42,7 +42,7 @@ impl SearchEngine for Searx {
|
|
42 |
page: u32,
|
43 |
user_agent: String,
|
44 |
request_timeout: u8,
|
45 |
-
) -> Result<HashMap<String,
|
46 |
// Page number can be missing or empty string and so appropriate handling is required
|
47 |
// so that upstream server recieves valid page number.
|
48 |
let url: String = match page {
|
@@ -111,7 +111,7 @@ impl SearchEngine for Searx {
|
|
111 |
Ok(document
|
112 |
.select(&results)
|
113 |
.map(|result| {
|
114 |
-
|
115 |
result
|
116 |
.select(&result_title)
|
117 |
.next()
|
@@ -137,7 +137,7 @@ impl SearchEngine for Searx {
|
|
137 |
vec!["searx".to_string()],
|
138 |
)
|
139 |
})
|
140 |
-
.map(|search_result| (search_result.
|
141 |
.collect())
|
142 |
}
|
143 |
}
|
|
|
6 |
use scraper::{Html, Selector};
|
7 |
use std::collections::HashMap;
|
8 |
|
9 |
+
use crate::results::aggregation_models::SearchResult;
|
10 |
|
11 |
use super::engine_models::{EngineError, SearchEngine};
|
12 |
use error_stack::{IntoReport, Report, Result, ResultExt};
|
|
|
42 |
page: u32,
|
43 |
user_agent: String,
|
44 |
request_timeout: u8,
|
45 |
+
) -> Result<HashMap<String, SearchResult>, EngineError> {
|
46 |
// Page number can be missing or empty string and so appropriate handling is required
|
47 |
// so that upstream server recieves valid page number.
|
48 |
let url: String = match page {
|
|
|
111 |
Ok(document
|
112 |
.select(&results)
|
113 |
.map(|result| {
|
114 |
+
SearchResult::new(
|
115 |
result
|
116 |
.select(&result_title)
|
117 |
.next()
|
|
|
137 |
vec!["searx".to_string()],
|
138 |
)
|
139 |
})
|
140 |
+
.map(|search_result| (search_result.url.clone(), search_result))
|
141 |
.collect())
|
142 |
}
|
143 |
}
|
src/results/aggregation_models.rs
CHANGED
@@ -5,97 +5,44 @@ use serde::{Deserialize, Serialize};
|
|
5 |
|
6 |
use crate::{config::parser_models::Style, engines::engine_models::EngineError};
|
7 |
|
8 |
-
/// A named struct to store
|
9 |
-
///
|
|
|
10 |
///
|
11 |
/// # Fields
|
12 |
///
|
13 |
/// * `title` - The title of the search result.
|
14 |
-
/// * `
|
15 |
-
/// words).
|
16 |
-
/// * `url` - The url to be displayed below the search result title in html.
|
17 |
/// * `description` - The description of the search result.
|
18 |
/// * `engine` - The names of the upstream engines from which this results were provided.
|
19 |
-
#[derive(Serialize, Deserialize)]
|
20 |
#[serde(rename_all = "camelCase")]
|
21 |
pub struct SearchResult {
|
22 |
pub title: String,
|
23 |
-
pub visiting_url: String,
|
24 |
pub url: String,
|
25 |
pub description: String,
|
26 |
pub engine: Vec<String>,
|
27 |
}
|
28 |
|
29 |
impl SearchResult {
|
30 |
-
/// Constructs a new `
|
31 |
///
|
32 |
/// # Arguments
|
33 |
///
|
34 |
/// * `title` - The title of the search result.
|
35 |
-
/// * `
|
36 |
/// (href url in html in simple words).
|
37 |
-
/// * `url` - The url to be displayed below the search result title in html.
|
38 |
/// * `description` - The description of the search result.
|
39 |
/// * `engine` - The names of the upstream engines from which this results were provided.
|
40 |
-
pub fn new(
|
41 |
-
title: String,
|
42 |
-
visiting_url: String,
|
43 |
-
url: String,
|
44 |
-
description: String,
|
45 |
-
engine: Vec<String>,
|
46 |
-
) -> Self {
|
47 |
SearchResult {
|
48 |
title,
|
49 |
-
visiting_url,
|
50 |
url,
|
51 |
description,
|
52 |
engine,
|
53 |
}
|
54 |
}
|
55 |
-
}
|
56 |
-
|
57 |
-
/// A named struct to store the raw scraped search results scraped search results from the
|
58 |
-
/// upstream search engines before aggregating it.It derives the Clone trait which is needed
|
59 |
-
/// to write idiomatic rust using `Iterators`.
|
60 |
-
///
|
61 |
-
/// # Fields
|
62 |
-
///
|
63 |
-
/// * `title` - The title of the search result.
|
64 |
-
/// * `visiting_url` - The url which is accessed when clicked on it
|
65 |
-
/// (href url in html in simple words).
|
66 |
-
/// * `description` - The description of the search result.
|
67 |
-
/// * `engine` - The names of the upstream engines from which this results were provided.
|
68 |
-
#[derive(Clone)]
|
69 |
-
pub struct RawSearchResult {
|
70 |
-
pub title: String,
|
71 |
-
pub visiting_url: String,
|
72 |
-
pub description: String,
|
73 |
-
pub engine: Vec<String>,
|
74 |
-
}
|
75 |
-
|
76 |
-
impl RawSearchResult {
|
77 |
-
/// Constructs a new `RawSearchResult` with the given arguments needed for the struct.
|
78 |
-
///
|
79 |
-
/// # Arguments
|
80 |
-
///
|
81 |
-
/// * `title` - The title of the search result.
|
82 |
-
/// * `visiting_url` - The url which is accessed when clicked on it
|
83 |
-
/// (href url in html in simple words).
|
84 |
-
/// * `description` - The description of the search result.
|
85 |
-
/// * `engine` - The names of the upstream engines from which this results were provided.
|
86 |
-
pub fn new(
|
87 |
-
title: String,
|
88 |
-
visiting_url: String,
|
89 |
-
description: String,
|
90 |
-
engine: Vec<String>,
|
91 |
-
) -> Self {
|
92 |
-
RawSearchResult {
|
93 |
-
title,
|
94 |
-
visiting_url,
|
95 |
-
description,
|
96 |
-
engine,
|
97 |
-
}
|
98 |
-
}
|
99 |
|
100 |
/// A function which adds the engine name provided as a string into a vector of strings.
|
101 |
///
|
|
|
5 |
|
6 |
use crate::{config::parser_models::Style, engines::engine_models::EngineError};
|
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`.
|
11 |
///
|
12 |
/// # Fields
|
13 |
///
|
14 |
/// * `title` - The title of the search result.
|
15 |
+
/// * `url` - The url which is accessed when clicked on it
|
16 |
+
/// (href url in html in simple words).
|
|
|
17 |
/// * `description` - The description of the search result.
|
18 |
/// * `engine` - The names of the upstream engines from which this results were provided.
|
19 |
+
#[derive(Clone, Serialize, Deserialize)]
|
20 |
#[serde(rename_all = "camelCase")]
|
21 |
pub struct SearchResult {
|
22 |
pub title: String,
|
|
|
23 |
pub url: String,
|
24 |
pub description: String,
|
25 |
pub engine: Vec<String>,
|
26 |
}
|
27 |
|
28 |
impl SearchResult {
|
29 |
+
/// Constructs a new `RawSearchResult` with the given arguments needed for the struct.
|
30 |
///
|
31 |
/// # Arguments
|
32 |
///
|
33 |
/// * `title` - The title of the search result.
|
34 |
+
/// * `url` - The url which is accessed when clicked on it
|
35 |
/// (href url in html in simple words).
|
|
|
36 |
/// * `description` - The description of the search result.
|
37 |
/// * `engine` - The names of the upstream engines from which this results were provided.
|
38 |
+
pub fn new(title: String, url: String, description: String, engine: Vec<String>) -> Self {
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
SearchResult {
|
40 |
title,
|
|
|
41 |
url,
|
42 |
description,
|
43 |
engine,
|
44 |
}
|
45 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
/// A function which adds the engine name provided as a string into a vector of strings.
|
48 |
///
|
src/results/aggregator.rs
CHANGED
@@ -8,18 +8,14 @@ use rand::Rng;
|
|
8 |
use tokio::task::JoinHandle;
|
9 |
|
10 |
use super::{
|
11 |
-
aggregation_models::{EngineErrorInfo,
|
12 |
user_agent::random_user_agent,
|
13 |
};
|
14 |
|
15 |
-
use crate::engines::{
|
16 |
-
duckduckgo,
|
17 |
-
engine_models::{EngineError, SearchEngine},
|
18 |
-
searx,
|
19 |
-
};
|
20 |
|
21 |
/// Aliases for long type annotations
|
22 |
-
type FutureVec = Vec<JoinHandle<Result<HashMap<String,
|
23 |
|
24 |
/// The function aggregates the scraped results from the user-selected upstream search engines.
|
25 |
/// These engines can be chosen either from the user interface (UI) or from the configuration file.
|
@@ -64,139 +60,93 @@ pub async fn aggregate(
|
|
64 |
page: u32,
|
65 |
random_delay: bool,
|
66 |
debug: bool,
|
67 |
-
upstream_search_engines: Vec<
|
68 |
request_timeout: u8,
|
69 |
) -> Result<SearchResults, Box<dyn std::error::Error>> {
|
70 |
let user_agent: String = random_user_agent();
|
71 |
-
let mut result_map: HashMap<String, RawSearchResult> = HashMap::new();
|
72 |
|
73 |
// Add a random delay before making the request.
|
74 |
if random_delay || !debug {
|
75 |
let mut rng = rand::thread_rng();
|
76 |
let delay_secs = rng.gen_range(1..10);
|
77 |
-
|
78 |
}
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
.
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
.results(query, page, user_agent.clone(), request_timeout)
|
100 |
-
.await
|
101 |
-
})
|
102 |
-
})
|
103 |
-
.collect();
|
104 |
-
|
105 |
-
let mut outputs = Vec::with_capacity(task_capacity);
|
106 |
|
107 |
for task in tasks {
|
108 |
if let Ok(result) = task.await {
|
109 |
-
|
110 |
}
|
111 |
}
|
112 |
|
|
|
|
|
113 |
let mut engine_errors_info: Vec<EngineErrorInfo> = Vec::new();
|
114 |
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
// the `EngineErrorInfo` structure.
|
132 |
-
//
|
133 |
-
// In summary, this code block manages the selection of engines, handling of duplicate results, and tracking
|
134 |
-
// of errors in order to populate the `result_map` and provide informative feedback to the user through the
|
135 |
-
// `SearchResults` structure.
|
136 |
-
let mut initial: bool = true;
|
137 |
-
let mut counter: usize = 0;
|
138 |
-
outputs.iter().for_each(|results| {
|
139 |
-
if initial {
|
140 |
-
match results {
|
141 |
-
Ok(result) => {
|
142 |
-
result_map.extend(result.clone());
|
143 |
-
counter += 1;
|
144 |
-
initial = false
|
145 |
}
|
146 |
-
Err(
|
147 |
-
|
148 |
-
engine_errors_info.push(EngineErrorInfo::new(
|
149 |
-
error_type.downcast_ref::<EngineError>().unwrap(),
|
150 |
-
upstream_search_engines[counter].clone(),
|
151 |
-
));
|
152 |
-
counter += 1
|
153 |
}
|
154 |
}
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
.
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
});
|
172 |
-
});
|
173 |
-
counter += 1
|
174 |
-
}
|
175 |
-
Err(error_type) => {
|
176 |
-
log::error!("Engine Error: {:?}", error_type);
|
177 |
-
engine_errors_info.push(EngineErrorInfo::new(
|
178 |
-
error_type.downcast_ref::<EngineError>().unwrap(),
|
179 |
-
upstream_search_engines[counter].clone(),
|
180 |
-
));
|
181 |
-
counter += 1
|
182 |
-
}
|
183 |
}
|
184 |
}
|
185 |
-
}
|
|
|
|
|
186 |
|
187 |
Ok(SearchResults::new(
|
188 |
-
|
189 |
-
.into_iter()
|
190 |
-
.map(|(key, value)| {
|
191 |
-
SearchResult::new(
|
192 |
-
value.title,
|
193 |
-
value.visiting_url,
|
194 |
-
key,
|
195 |
-
value.description,
|
196 |
-
value.engine,
|
197 |
-
)
|
198 |
-
})
|
199 |
-
.collect(),
|
200 |
query.to_string(),
|
201 |
engine_errors_info,
|
202 |
))
|
|
|
8 |
use tokio::task::JoinHandle;
|
9 |
|
10 |
use super::{
|
11 |
+
aggregation_models::{EngineErrorInfo, SearchResult, SearchResults},
|
12 |
user_agent::random_user_agent,
|
13 |
};
|
14 |
|
15 |
+
use crate::engines::engine_models::{EngineError, EngineHandler};
|
|
|
|
|
|
|
|
|
16 |
|
17 |
/// Aliases for long type annotations
|
18 |
+
type FutureVec = Vec<JoinHandle<Result<HashMap<String, SearchResult>, Report<EngineError>>>>;
|
19 |
|
20 |
/// The function aggregates the scraped results from the user-selected upstream search engines.
|
21 |
/// These engines can be chosen either from the user interface (UI) or from the configuration file.
|
|
|
60 |
page: u32,
|
61 |
random_delay: bool,
|
62 |
debug: bool,
|
63 |
+
upstream_search_engines: Vec<EngineHandler>,
|
64 |
request_timeout: u8,
|
65 |
) -> Result<SearchResults, Box<dyn std::error::Error>> {
|
66 |
let user_agent: String = random_user_agent();
|
|
|
67 |
|
68 |
// Add a random delay before making the request.
|
69 |
if random_delay || !debug {
|
70 |
let mut rng = rand::thread_rng();
|
71 |
let delay_secs = rng.gen_range(1..10);
|
72 |
+
tokio::time::sleep(Duration::from_secs(delay_secs)).await;
|
73 |
}
|
74 |
|
75 |
+
let mut names: Vec<&str> = vec![];
|
76 |
+
|
77 |
+
// create tasks for upstream result fetching
|
78 |
+
let mut tasks: FutureVec = FutureVec::new();
|
79 |
+
|
80 |
+
for engine_handler in upstream_search_engines {
|
81 |
+
let (name, search_engine) = engine_handler.into_name_engine();
|
82 |
+
names.push(name);
|
83 |
+
let query: String = query.clone();
|
84 |
+
let user_agent: String = user_agent.clone();
|
85 |
+
tasks.push(tokio::spawn(async move {
|
86 |
+
search_engine
|
87 |
+
.results(query, page, user_agent.clone(), request_timeout)
|
88 |
+
.await
|
89 |
+
}));
|
90 |
+
}
|
91 |
+
|
92 |
+
// get upstream responses
|
93 |
+
let mut responses = Vec::with_capacity(tasks.len());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
|
95 |
for task in tasks {
|
96 |
if let Ok(result) = task.await {
|
97 |
+
responses.push(result)
|
98 |
}
|
99 |
}
|
100 |
|
101 |
+
// aggregate search results, removing duplicates and handling errors the upstream engines returned
|
102 |
+
let mut result_map: HashMap<String, SearchResult> = HashMap::new();
|
103 |
let mut engine_errors_info: Vec<EngineErrorInfo> = Vec::new();
|
104 |
|
105 |
+
let mut handle_error = |error: Report<EngineError>, engine_name: String| {
|
106 |
+
log::error!("Engine Error: {:?}", error);
|
107 |
+
engine_errors_info.push(EngineErrorInfo::new(
|
108 |
+
error.downcast_ref::<EngineError>().unwrap(),
|
109 |
+
engine_name.to_string(),
|
110 |
+
));
|
111 |
+
};
|
112 |
+
|
113 |
+
for _ in 0..responses.len() {
|
114 |
+
let response = responses.pop().unwrap();
|
115 |
+
let engine = names.pop().unwrap().to_string();
|
116 |
+
|
117 |
+
if result_map.is_empty() {
|
118 |
+
match response {
|
119 |
+
Ok(results) => {
|
120 |
+
result_map = results.clone();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
122 |
+
Err(error) => {
|
123 |
+
handle_error(error, engine);
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
}
|
126 |
+
continue;
|
127 |
+
}
|
128 |
+
|
129 |
+
match response {
|
130 |
+
Ok(result) => {
|
131 |
+
result.into_iter().for_each(|(key, value)| {
|
132 |
+
result_map
|
133 |
+
.entry(key)
|
134 |
+
.and_modify(|result| {
|
135 |
+
result.add_engines(engine.clone());
|
136 |
+
})
|
137 |
+
.or_insert_with(|| -> SearchResult { value });
|
138 |
+
});
|
139 |
+
}
|
140 |
+
Err(error) => {
|
141 |
+
handle_error(error, engine);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
}
|
143 |
}
|
144 |
+
}
|
145 |
+
|
146 |
+
let results = result_map.into_values().collect();
|
147 |
|
148 |
Ok(SearchResults::new(
|
149 |
+
results,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
query.to_string(),
|
151 |
engine_errors_info,
|
152 |
))
|
src/server/routes.rs
CHANGED
@@ -7,12 +7,14 @@ use std::fs::read_to_string;
|
|
7 |
use crate::{
|
8 |
cache::cacher::RedisCache,
|
9 |
config::parser::Config,
|
|
|
10 |
handler::public_paths::public_path,
|
11 |
results::{aggregation_models::SearchResults, aggregator::aggregate},
|
12 |
};
|
13 |
use actix_web::{get, web, HttpRequest, HttpResponse};
|
14 |
use handlebars::Handlebars;
|
15 |
use serde::Deserialize;
|
|
|
16 |
|
17 |
/// A named struct which deserializes all the user provided search parameters and stores them.
|
18 |
///
|
@@ -96,15 +98,49 @@ pub async fn search(
|
|
96 |
}
|
97 |
let page = match ¶ms.page {
|
98 |
Some(page) => *page,
|
99 |
-
None =>
|
100 |
};
|
101 |
|
102 |
-
let
|
103 |
-
|
104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
);
|
106 |
-
|
107 |
-
let page_content: String = hbs.render("search", &
|
108 |
Ok(HttpResponse::Ok().body(page_content))
|
109 |
}
|
110 |
None => Ok(HttpResponse::Found()
|
@@ -140,12 +176,19 @@ async fn results(
|
|
140 |
{
|
141 |
Some(cookie_value) => {
|
142 |
let cookie_value: Cookie = serde_json::from_str(cookie_value.name_value().1)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
aggregate(
|
144 |
query,
|
145 |
page,
|
146 |
config.aggregator.random_delay,
|
147 |
config.debug,
|
148 |
-
|
149 |
config.request_timeout,
|
150 |
)
|
151 |
.await?
|
|
|
7 |
use crate::{
|
8 |
cache::cacher::RedisCache,
|
9 |
config::parser::Config,
|
10 |
+
engines::engine_models::EngineHandler,
|
11 |
handler::public_paths::public_path,
|
12 |
results::{aggregation_models::SearchResults, aggregator::aggregate},
|
13 |
};
|
14 |
use actix_web::{get, web, HttpRequest, HttpResponse};
|
15 |
use handlebars::Handlebars;
|
16 |
use serde::Deserialize;
|
17 |
+
use tokio::join;
|
18 |
|
19 |
/// A named struct which deserializes all the user provided search parameters and stores them.
|
20 |
///
|
|
|
98 |
}
|
99 |
let page = match ¶ms.page {
|
100 |
Some(page) => *page,
|
101 |
+
None => 1,
|
102 |
};
|
103 |
|
104 |
+
let (_, results, _) = join!(
|
105 |
+
results(
|
106 |
+
format!(
|
107 |
+
"http://{}:{}/search?q={}&page={}",
|
108 |
+
config.binding_ip,
|
109 |
+
config.port,
|
110 |
+
query,
|
111 |
+
page - 1
|
112 |
+
),
|
113 |
+
&config,
|
114 |
+
query.to_string(),
|
115 |
+
page - 1,
|
116 |
+
req.clone(),
|
117 |
+
),
|
118 |
+
results(
|
119 |
+
format!(
|
120 |
+
"http://{}:{}/search?q={}&page={}",
|
121 |
+
config.binding_ip, config.port, query, page
|
122 |
+
),
|
123 |
+
&config,
|
124 |
+
query.to_string(),
|
125 |
+
page,
|
126 |
+
req.clone(),
|
127 |
+
),
|
128 |
+
results(
|
129 |
+
format!(
|
130 |
+
"http://{}:{}/search?q={}&page={}",
|
131 |
+
config.binding_ip,
|
132 |
+
config.port,
|
133 |
+
query,
|
134 |
+
page + 1
|
135 |
+
),
|
136 |
+
&config,
|
137 |
+
query.to_string(),
|
138 |
+
page + 1,
|
139 |
+
req.clone(),
|
140 |
+
)
|
141 |
);
|
142 |
+
|
143 |
+
let page_content: String = hbs.render("search", &results?)?;
|
144 |
Ok(HttpResponse::Ok().body(page_content))
|
145 |
}
|
146 |
None => Ok(HttpResponse::Found()
|
|
|
176 |
{
|
177 |
Some(cookie_value) => {
|
178 |
let cookie_value: Cookie = serde_json::from_str(cookie_value.name_value().1)?;
|
179 |
+
|
180 |
+
let engines = cookie_value
|
181 |
+
.engines
|
182 |
+
.iter()
|
183 |
+
.filter_map(|name| EngineHandler::new(name))
|
184 |
+
.collect();
|
185 |
+
|
186 |
aggregate(
|
187 |
query,
|
188 |
page,
|
189 |
config.aggregator.random_delay,
|
190 |
config.debug,
|
191 |
+
engines,
|
192 |
config.request_timeout,
|
193 |
)
|
194 |
.await?
|
tests/index.rs
CHANGED
@@ -8,7 +8,7 @@ fn spawn_app() -> String {
|
|
8 |
// Binding to port 0 will trigger the OS to assign a port for us.
|
9 |
let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
|
10 |
let port = listener.local_addr().unwrap().port();
|
11 |
-
let config = Config::parse(
|
12 |
let server = run(listener, config).expect("Failed to bind address");
|
13 |
|
14 |
tokio::spawn(server);
|
@@ -36,7 +36,7 @@ async fn test_index() {
|
|
36 |
assert_eq!(res.status(), 200);
|
37 |
|
38 |
let handlebars = handlebars();
|
39 |
-
let config = Config::parse(
|
40 |
let template = handlebars.render("index", &config.style).unwrap();
|
41 |
assert_eq!(res.text().await.unwrap(), template);
|
42 |
}
|
|
|
8 |
// Binding to port 0 will trigger the OS to assign a port for us.
|
9 |
let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
|
10 |
let port = listener.local_addr().unwrap().port();
|
11 |
+
let config = Config::parse(false).unwrap();
|
12 |
let server = run(listener, config).expect("Failed to bind address");
|
13 |
|
14 |
tokio::spawn(server);
|
|
|
36 |
assert_eq!(res.status(), 200);
|
37 |
|
38 |
let handlebars = handlebars();
|
39 |
+
let config = Config::parse(true).unwrap();
|
40 |
let template = handlebars.render("index", &config.style).unwrap();
|
41 |
assert_eq!(res.text().await.unwrap(), template);
|
42 |
}
|