diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml index 75aecf3..d665006 100644 --- a/.github/workflows/contributors.yml +++ b/.github/workflows/contributors.yml @@ -32,7 +32,7 @@ jobs: noCommit: true - name: Commit & PR - uses: peter-evans/create-pull-request@38e0b6e68b4c852a5500a94740f0e535e0d7ba54 # v4.2.4 + uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5.0.2 with: token: ${{ secrets.GITHUB_TOKEN }} add-paths: .github/assets/CONTRIBUTORS.svg diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index e014b39..5a617e5 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '14' - uses: EddieHubCommunity/gh-action-open-source-labels@main diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index 02bdaac..3927832 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -63,7 +63,7 @@ jobs: - name: Create Pull Request with applied fixes id: cpr if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v5.0.2 with: token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} commit-message: "[MegaLinter] Apply linters automatic fixes" @@ -81,7 +81,7 @@ jobs: run: sudo chown -Rc $UID .git/ - name: Commit and push applied linter fixes if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }} commit_message: "[MegaLinter] Apply linters fixes" diff --git a/.stylelintrc.json b/.stylelintrc.json index 05ffdd4..cf4df56 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,9 +1,12 @@ -{ +{ "extends": "stylelint-config-standard", "rules": { "alpha-value-notation": "number", - "selector-class-pattern": null + "selector-class-pattern": null, + "no-descending-specificity": null }, + "fix": true, + "cache": true, "overrides": [ { "files": ["*.js"], diff --git a/Cargo.lock b/Cargo.lock index 190501c..d66fb93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,9 +59,9 @@ dependencies = [ [[package]] name = "actix-governor" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46ff2d40f2bc627b8054c5e20fa6b0b0cf9428699b54bd41634e9ae3098ad555" +checksum = "a2e7b88f3804e01bd4191fdb08650430bbfcb43d3d9b2890064df3551ec7d25b" dependencies = [ "actix-http", "actix-web", @@ -82,14 +82,11 @@ dependencies = [ "ahash 0.8.6", "base64 0.21.5", "bitflags 2.4.1", - "brotli", "bytes 1.5.0", "bytestring", "derive_more", "encoding_rs", - "flate2", "futures-core", - "h2 0.3.21", "http 0.2.9", "httparse", "httpdate", @@ -105,7 +102,6 @@ dependencies = [ "tokio 1.33.0", "tokio-util", "tracing", - "zstd", ] [[package]] @@ -115,7 +111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -228,7 +224,7 @@ dependencies = [ "actix-router", "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -327,12 +323,38 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "askama_escape" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" +[[package]] +name = "async-compression" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc2d0cfb2a7388d34f590e76686704c494ed7aaceed62ee1ba35cbf363abc2a5" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio 1.34.0", +] + [[package]] name = "async-once-cell" version = "0.5.3" @@ -347,7 +369,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -395,15 +417,6 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" -[[package]] -name = "base64-simd" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" -dependencies = [ - "simd-abstraction", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -432,15 +445,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] -name = "bitvec" -version = "1.0.1" +name = "blake3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" dependencies = [ - "funty", - "radium", - "tap", - "wyz", + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.0", + "constant_time_eq", ] [[package]] @@ -489,28 +503,6 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" -[[package]] -name = "bytecheck" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" -dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 1.0.109", -] - [[package]] name = "bytecount" version = "0.6.7" @@ -560,9 +552,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" dependencies = [ "serde", ] @@ -592,7 +584,6 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ - "jobserver", "libc", ] @@ -712,6 +703,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "convert_case" version = "0.4.0" @@ -724,7 +721,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" dependencies = [ - "time 0.1.43", + "time 0.1.45", "url 1.7.2", ] @@ -752,7 +749,7 @@ dependencies = [ "publicsuffix", "serde", "serde_json", - "time 0.1.43", + "time 0.1.45", "try_from", "url 1.7.2", ] @@ -807,8 +804,6 @@ dependencies = [ "num-traits", "once_cell", "oorandom", - "plotters", - "rayon", "regex", "serde", "serde_derive", @@ -843,22 +838,11 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" dependencies = [ - "crossbeam-epoch 0.8.2", + "crossbeam-epoch", "crossbeam-utils 0.7.2", "maybe-uninit", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch 0.9.15", - "crossbeam-utils 0.8.16", -] - [[package]] name = "crossbeam-epoch" version = "0.8.2" @@ -870,20 +854,7 @@ dependencies = [ "crossbeam-utils 0.7.2", "lazy_static", "maybe-uninit", - "memoffset 0.5.6", - "scopeguard", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg 1.1.0", - "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", - "memoffset 0.9.0", + "memoffset", "scopeguard", ] @@ -970,7 +941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -992,15 +963,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" -[[package]] -name = "data-url" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193" -dependencies = [ - "matches", -] - [[package]] name = "deranged" version = "0.3.9" @@ -1097,11 +1059,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -1116,9 +1074,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" dependencies = [ "libc", "windows-sys", @@ -1250,12 +1208,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "futf" version = "0.1.5" @@ -1338,7 +1290,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1407,9 +1359,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if 1.0.0", "libc", @@ -1430,9 +1382,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "governor" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c390a940a5d157878dd057c78680a33ce3415bcd05b4799509ea44210914b4d5" +checksum = "821239e5672ff23e2a7060901fa622950bbd80b649cdaadd78d1c1767ed14eb4" dependencies = [ "cfg-if 1.0.0", "dashmap", @@ -1509,9 +1461,6 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.7", -] [[package]] name = "hashbrown" @@ -1635,12 +1584,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "0.12.36" @@ -1659,7 +1602,7 @@ dependencies = [ "log", "net2", "rustc_version 0.2.3", - "time 0.1.43", + "time 0.1.45", "tokio 0.1.22", "tokio-buf", "tokio-executor", @@ -1811,20 +1754,11 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" -[[package]] -name = "jobserver" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -1853,9 +1787,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libmimalloc-sys" @@ -1869,33 +1803,29 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.50" +version = "1.0.0-alpha.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2999490cc10a59ad8a87d731791a5d438d2d025e3f137aa7d4c23e1827985b0" +checksum = "99d6ad516c08b24c246b339159dc2ee2144c012e8ebdf4db4bddefb8734b2b69" dependencies = [ "ahash 0.7.7", "bitflags 2.4.1", "const-str", "cssparser 0.33.0", "cssparser-color", - "dashmap", "data-encoding", "itertools", "lazy_static", "parcel_selectors", - "parcel_sourcemap", "paste", "pathdiff", - "rayon", - "serde", "smallvec 1.11.1", ] [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "local-channel" @@ -1965,10 +1895,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] -name = "mach" -version = "0.3.2" +name = "mach2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" dependencies = [ "libc", ] @@ -2016,12 +1946,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - [[package]] name = "memchr" version = "2.6.4" @@ -2037,15 +1961,6 @@ dependencies = [ "autocfg 1.1.0", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "mimalloc" version = "0.1.39" @@ -2279,9 +2194,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ "bitflags 2.4.1", "cfg-if 1.0.0", @@ -2300,7 +2215,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2311,9 +2226,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" dependencies = [ "cc", "libc", @@ -2321,12 +2236,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "outref" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" - [[package]] name = "parcel_selectors" version = "0.26.4" @@ -2343,20 +2252,6 @@ dependencies = [ "smallvec 1.11.1", ] -[[package]] -name = "parcel_sourcemap" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "485b74d7218068b2b7c0e3ff12fbc61ae11d57cb5d8224f525bd304c6be05bbb" -dependencies = [ - "base64-simd", - "data-url", - "rkyv", - "serde", - "serde_json", - "vlq", -] - [[package]] name = "parking_lot" version = "0.9.0" @@ -2474,7 +2369,7 @@ dependencies = [ "pest_meta", "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2576,7 +2471,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2623,7 +2518,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2644,34 +2539,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -2708,26 +2575,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 1.0.109", -] - [[package]] name = "publicsuffix" version = "1.5.6" @@ -2751,16 +2598,16 @@ dependencies = [ [[package]] name = "quanta" -version = "0.9.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" dependencies = [ "crossbeam-utils 0.8.16", "libc", - "mach", + "mach2", "once_cell", "raw-cpuid", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", "web-sys", "winapi 0.3.9", ] @@ -2783,12 +2630,6 @@ dependencies = [ "proc-macro2 1.0.69", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.6.5" @@ -2934,26 +2775,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "rayon" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" -dependencies = [ - "crossbeam-deque 0.8.3", - "crossbeam-utils 0.8.16", -] - [[package]] name = "rdrand" version = "0.4.0" @@ -2979,8 +2800,6 @@ dependencies = [ "percent-encoding 2.3.0", "pin-project-lite", "ryu", - "sha1_smol", - "socket2 0.4.10", "tokio 1.33.0", "tokio-retry", "tokio-util", @@ -3031,15 +2850,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "rend" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" -dependencies = [ - "bytecheck", -] - [[package]] name = "reqwest" version = "0.9.24" @@ -3063,14 +2873,14 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded 0.5.5", - "time 0.1.43", + "time 0.1.45", "tokio 0.1.22", "tokio-executor", "tokio-io", "tokio-threadpool", "tokio-timer", "url 1.7.2", - "uuid 0.7.4", + "uuid", "winreg 0.6.2", ] @@ -3080,6 +2890,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ + "async-compression", "base64 0.21.5", "bytes 1.5.0", "encoding_rs", @@ -3105,6 +2916,7 @@ dependencies = [ "system-configuration", "tokio 1.33.0", "tokio-rustls", + "tokio-util", "tower-service", "url 2.4.1", "wasm-bindgen", @@ -3128,34 +2940,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "rkyv" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" -dependencies = [ - "bitvec", - "bytecheck", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid 1.5.0", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" -dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 1.0.109", -] - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -3188,9 +2972,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.1", "errno", @@ -3274,18 +3058,16 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scraper" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a930e03325234c18c7071fd2b60118307e025d6fff3e12745ffbf63a3d29c" +checksum = "585480e3719b311b78a573db1c9d9c4c1f8010c2dee4cc59c2efe58ea4dbc3e1" dependencies = [ "ahash 0.8.6", "cssparser 0.31.2", "ego-tree", - "getopts", "html5ever 0.26.0", "once_cell", "selectors", - "smallvec 1.11.1", "tendril", ] @@ -3299,12 +3081,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - [[package]] name = "security-framework" version = "2.9.2" @@ -3383,22 +3159,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -3456,12 +3232,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - [[package]] name = "sha2" version = "0.10.8" @@ -3482,21 +3252,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-abstraction" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" -dependencies = [ - "outref", -] - -[[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" - [[package]] name = "siphasher" version = "0.2.3" @@ -3676,9 +3431,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", @@ -3734,12 +3489,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tempfile" version = "3.8.1" @@ -3764,15 +3513,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "termcolor" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.50" @@ -3790,7 +3530,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -3801,11 +3541,12 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" [[package]] name = "time" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi 0.3.9", ] @@ -3951,7 +3692,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -4024,7 +3765,7 @@ version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" dependencies = [ - "crossbeam-deque 0.7.4", + "crossbeam-deque", "crossbeam-queue", "crossbeam-utils 0.7.2", "futures 0.1.31", @@ -4220,12 +3961,6 @@ dependencies = [ "rand 0.6.5", ] -[[package]] -name = "uuid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" - [[package]] name = "vcpkg" version = "0.2.15" @@ -4238,12 +3973,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "vlq" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" - [[package]] name = "walkdir" version = "2.4.0" @@ -4276,9 +4005,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasi" @@ -4288,9 +4017,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -4298,24 +4027,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -4325,9 +4054,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote 1.0.33", "wasm-bindgen-macro-support", @@ -4335,28 +4064,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", @@ -4370,7 +4099,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "websurfx" -version = "1.2.15" +version = "1.2.28" dependencies = [ "actix-cors", "actix-files", @@ -4378,6 +4107,7 @@ dependencies = [ "actix-web", "async-once-cell", "async-trait", + "blake3", "criterion", "dhat", "env_logger", @@ -4387,12 +4117,10 @@ dependencies = [ "handlebars", "lightningcss", "log", - "md5", "mimalloc", "mini-moka", "minify-js", "mlua", - "rand 0.8.5", "redis", "regex", "reqwest 0.11.22", @@ -4555,60 +4283,22 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "zerocopy" -version = "0.7.20" +version = "0.7.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd66a62464e3ffd4e37bd09950c2b9dd6c4f8767380fabba0d523f9a775bc85a" +checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.20" +version = "0.7.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255c4596d41e6916ced49cfafea18727b24d67878fa180ddfd69b9df34fd1726" +checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" dependencies = [ "proc-macro2 1.0.69", "quote 1.0.33", - "syn 2.0.38", -] - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", + "syn 2.0.39", ] diff --git a/Cargo.toml b/Cargo.toml index f1b5300..e247241 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "websurfx" -version = "1.2.15" +version = "1.2.28" edition = "2021" 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." repository = "https://github.com/neon-mmd/websurfx" @@ -13,46 +13,45 @@ bench = false path = "src/bin/websurfx.rs" [dependencies] -reqwest = {version="0.11.21",default-features = false,features = ["json", "rustls-tls"]} -tokio = {version="1.32.0",features=["rt-multi-thread","macros"]} -serde = {version="1.0.188",features=["derive"]} -handlebars = { version = "4.4.0", features = ["dir_source"] } -scraper = {version="0.17.1"} -actix-web = {version="4.4.0", features = ["cookies"]} -actix-files = {version="0.6.2"} -actix-cors = {version="0.6.4"} -serde_json = {version="1.0.105"} -fake-useragent = {version="0.1.3"} -env_logger = {version="0.10.0"} -log = {version="0.4.20"} -mlua = {version="0.9.1", features=["luajit", "vendored"]} -redis = {version="0.23.3", features=["tokio-comp","connection-manager"], optional = true} -md5 = {version="0.7.0"} -rand={version="0.8.5"} -error-stack = {version="0.4.0"} -async-trait = {version="0.1.73"} -regex = {version="1.9.4", features=["perf"]} -smallvec = {version="1.11.0", features=["union", "serde"]} -futures = {version="0.3.28"} -dhat = {version="0.3.2", optional = true} +reqwest = {version="0.11.22", default-features=false, features=["rustls-tls","brotli", "gzip"]} +tokio = {version="1.32.0",features=["rt-multi-thread","macros"], default-features = false} +serde = {version="1.0.190", default-features=false, features=["derive"]} +serde_json = {version="1.0.108", default-features=false} +maud = {version="0.25.0", default-features=false, features=["actix-web"]} +scraper = {version="0.18.1", default-features = false} +actix-web = {version="4.4.0", features = ["cookies", "macros"], default-features=false} +actix-files = {version="0.6.2", default-features=false} +actix-cors = {version="0.6.4", default-features=false} +fake-useragent = {version="0.1.3", default-features=false} +env_logger = {version="0.10.0", default-features=false} +log = {version="0.4.20", default-features=false} +mlua = {version="0.9.1", features=["luajit", "vendored"], default-features=false} +redis = {version="0.23.3", features=["tokio-comp","connection-manager"], default-features = false, optional = true} +blake3 = {version="1.5.0", default-features=false} +error-stack = {version="0.4.0", default-features=false, features=["std"]} +async-trait = {version="0.1.73", default-features=false} +regex = {version="1.9.4", features=["perf"], default-features = false} +smallvec = {version="1.11.0", features=["union", "serde"], default-features=false} +futures = {version="0.3.28", default-features=false} +dhat = {version="0.3.2", optional = true, default-features=false} mimalloc = { version = "0.1.38", default-features = false } -async-once-cell = {version="0.5.3"} -actix-governor = {version="0.4.1"} -mini-moka = { version="0.10", optional = true} +async-once-cell = {version="0.5.3", default-features=false} +actix-governor = {version="0.5.0", default-features=false} +mini-moka = { version="0.10", optional = true, default-features=false, features=["sync"]} [dev-dependencies] -rusty-hook = "^0.11.2" -criterion = "0.5.1" -tempfile = "3.8.0" +rusty-hook = {version="^0.11.2", default-features=false} +criterion = {version="0.5.1", default-features=false} +tempfile = {version="3.8.0", default-features=false} [build-dependencies] -lightningcss = "1.0.0-alpha.50" -minify-js = "0.5.6" +lightningcss = {version="1.0.0-alpha.50", default-features=false, features=["grid"]} +minify-js = {version="0.5.6", default-features=false} [profile.dev] opt-level = 0 debug = true -split-debuginfo = '...' +split-debuginfo = 'unpacked' debug-assertions = true overflow-checks = true lto = false diff --git a/docs/configuration.md b/docs/configuration.md index 7bfdfc9..cae0dfc 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2,14 +2,14 @@ ## Installed From Source -If you have built `websurfx` from source then the configuration file will be located under project directory (codebase) at `websurfx/` +If you have built `websurfx` from the source then the configuration file will be located under the project directory (codebase) at `websurfx/` > **Note** -> If you have built websurfx with unstable/rolling/edge branch then you can copy the configuration file from `websurfx/config.lua` located under project directory (codebase) to `~/.config/websurfx/` and make the changes there and rerun the websurfx server. _This is only available from unstable/rolling/edge version_. +> If you have built websurfx with an unstable/rolling/edge branch then you can copy the configuration file from `websurfx/config.lua` located under the project directory (codebase) to `~/.config/websurfx/` and make the changes there and rerun the websurfx server. _This is only available from unstable/rolling/edge version_. ## Installed From Package -If you have installed `websurfx` using the package manager of your Linux distro then the default configuration file will be located at `/etc/xdg/websurfx/`. You can copy the default config to `~/.config/websurfx/` and make the changes there and rerun the websurfx server. +If you have installed `websurfx` using the package manager of your Linux distro then the default configuration file will be located at `/etc/xdg/websurfx/`. You can copy the default config to `~/.config/websurfx/` make the changes there and rerun the websurfx server. Some of the configuration options provided in the file are stated below. These are subdivided into the following categories: @@ -42,13 +42,13 @@ Some of the configuration options provided in the file are stated below. These a > > - Level 0 - With this level no search filtering occurs. > - Level 1 - With this level some search filtering occurs. -> - Level 2 - With this level the upstream search engines are restricted to send sensitive contents like NSFW search results, etc. -> - Level 3 - With this level the regex based filter lists is used alongside level 2 to filter more search results that have slipped in or custom results that needs to be filtered using the filter lists. -> - Level 4 - This level is similar to level 3 except in this level the regex based filter lists are used to disallow users to search sensitive or disallowed content. This level could be useful if you are parent or someone who wants to completely disallow their kids or yourself from watching sensitive content. +> - Level 2 - With this level the upstream search engines are restricted to sending sensitive content like NSFW search results, etc. +> - Level 3 - With this level the regex-based filter lists are used alongside level 2 to filter more search results that have slipped in or custom results that need to be filtered using the filter lists. +> - Level 4 - This level is similar to level 3 except in this level the regex-based filter lists are used to disallow users to search sensitive or disallowed content. This level could be useful if you are a parent or someone who wants to completely disallow their kids or yourself from watching sensitive content. ## Website -- **colorscheme:** The colorscheme name which should be used for the website theme (the name should be in accordance to the colorscheme file name present in `public/static/colorschemes` folder). +- **colorscheme:** The colorscheme name which should be used for the website theme (the name should be by the colorscheme file name present in the `public/static/colorschemes` folder). > By Default we provide 12 colorschemes to choose from these are: > @@ -65,7 +65,7 @@ Some of the configuration options provided in the file are stated below. These a > 11. tokyo-night > 12. tomorrow-night -- **theme:** The theme name which should be used for the website (again, the name should be in accordance to the theme file name present in `public/static/themes` folder). +- **theme:** The theme name that should be used for the website (again, the name should be by the theme file name present in the `public/static/themes` folder). > By Default we provide 1 theme to choose from these are: > @@ -73,7 +73,7 @@ Some of the configuration options provided in the file are stated below. These a ## Cache -- **redis_url:** Redis connection url address on which the client should connect on. +- **redis_url:** Redis connection URL address on which the client should connect. > **Note** > This option can be commented out if you have compiled the app without the `redis-cache` feature. For more information, See [**building**](./building.md). diff --git a/docs/developing.md b/docs/developing.md index 831809d..c8752e6 100644 --- a/docs/developing.md +++ b/docs/developing.md @@ -50,10 +50,11 @@ Before you start working on the project. You will need the following packages in - The latest version of `cargo` installed on your system which is required to manage building and running the project. The installation instructions for this can be found [here](https://doc.rust-lang.org/cargo/getting-started/installation.html). - The latest version of `npm` installed on your system which is required to allow the installation of other tools necessary for the project. The installation for this can be found [here](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm). - The latest version of `redis` installed on your system which will be used to avoid introducing unexpected issues when working on the project. The installation for this can be found [here](https://redis.io/docs/getting-started/installation/). -- The latest version of `stylelint` should be installed on your system which will be used by the pre-commit checks to lint the code before a commit can be made to ensure better code quality. Before you install `stylelint` on your system, make sure you have `npm` installed on your system. To install `stylelint` run the following command: +- The latest version of `stylelint` should be installed on your system which will be used by the pre-commit checks to lint the code before a commit can be made to ensure better code quality. Before you install `stylelint` on your system, make sure you have `npm` installed on your system. To install `stylelint` and plugins run the following command: ```shell $ npm i -g stylelint +$ npm i -g stylelint stylelint-config-standard postcss-lit ``` > **Note** diff --git a/docs/introduction.md b/docs/introduction.md index 7b540fb..690413c 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -4,10 +4,10 @@ A modern-looking, lightning-fast, privacy-respecting, secure [meta search engine # Motivation -Most meta search engines tend to be slow, lack high level of customization and missing many features and all of them like security as they are written in unsafe languages like python, javascript, etc which tend to open a wide variety of vulnerabilities which can also sometimes pose a threat to privacy as sometimes this can be exploited and can be used to leveraged to leak out sensitive information which is never good. +Most meta search engines tend to be slow, lack a high level of customization, and miss many features, and all of them lack security as they are written in unsafe languages like Python, JavaScript, etc., which tend to open a wide variety of vulnerabilities, which can also sometimes pose a threat to privacy as sometimes this can be exploited and can be used to leak out sensitive information, which is never good. # Solution -Websurfx is a project which seeks to provide privacy, security, speed and all the features which the user wants. +Websurfx is a project that seeks to provide privacy, security, speed, and all the features that the user wants. [⬅️ Go back to Home](./README.md) diff --git a/public/templates/404.html b/public/templates/404.html deleted file mode 100644 index a8a9ac7..0000000 --- a/public/templates/404.html +++ /dev/null @@ -1,10 +0,0 @@ -{{>header this}} -
- Image of broken robot. -
-

Aw! snap

-

404 Page Not Found!

-

Go to search page

-
-
-{{>footer}} diff --git a/public/templates/about.html b/public/templates/about.html deleted file mode 100644 index 9c4cbb0..0000000 --- a/public/templates/about.html +++ /dev/null @@ -1,29 +0,0 @@ -{{>header this}} -
-
-
-

Websurfx

-
-
-

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.
It aggregates results from multiple search engines and presents them in an unbiased manner, filtering out trackers and ads. -

- -

Some of the Top Features:

- - - - - - - - - - - - -
- -

Devoloped by: Websurfx team

-
-{{>footer}} - diff --git a/public/templates/bar.html b/public/templates/bar.html deleted file mode 100644 index 489b075..0000000 --- a/public/templates/bar.html +++ /dev/null @@ -1,3 +0,0 @@ - - - -{{>footer}} diff --git a/public/templates/navbar.html b/public/templates/navbar.html deleted file mode 100644 index c369739..0000000 --- a/public/templates/navbar.html +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/public/templates/search.html b/public/templates/search.html deleted file mode 100644 index c6c9d6a..0000000 --- a/public/templates/search.html +++ /dev/null @@ -1,86 +0,0 @@ -{{>header this.style}} -
- {{>search_bar this}} -
- {{#if results}} {{#each results}} -
-

{{{this.title}}}

- {{{this.url}}} -

{{{this.description}}}

-
- {{#each engine}} - {{{this}}} - {{/each}} -
-
- {{/each}} {{else}} {{#if disallowed}} -
-
-

- Your search - {{{this.pageQuery}}} - - has been disallowed. -

-

Dear user,

-

- The query - {{{this.pageQuery}}} - has - been blacklisted via server configuration and hence disallowed by the - server. Henceforth no results could be displayed for your query. -

-
- Image of a Barricade -
- {{else}} {{#if filtered}} -
-
-

- Your search - {{{this.pageQuery}}} - - has been filtered. -

-

Dear user,

-

- All the search results contain results that has been configured to be - filtered out via server configuration and henceforth has been - completely filtered out. -

-
- Image of a paper inside a funnel -
- {{else}} {{#if noEnginesSelected}} -
-
-

- No results could be fetched for your search "{{{this.pageQuery}}}" . -

-

Dear user,

-

- No results could be retrieved from the upstream search engines as no - upstream search engines were selected from the settings page. -

-
- Image of a white cross inside a red circle -
- {{else}} -
-

Your search - {{{this.pageQuery}}} - did not match any documents.

-

Suggestions:

-
    -
  • Make sure that all words are spelled correctly.
  • -
  • Try different keywords.
  • -
  • Try more general keywords.
  • -
- Man fishing gif -
- {{/if}} {{/if}} {{/if}} {{/if}} -
- -
- - - - -{{>footer}} diff --git a/public/templates/search_bar.html b/public/templates/search_bar.html deleted file mode 100644 index a006d89..0000000 --- a/public/templates/search_bar.html +++ /dev/null @@ -1,36 +0,0 @@ -
- {{>bar this}} -
- {{#if engineErrorsInfo}} - - - {{else}} - - - {{/if}} -
-
-
- -
- diff --git a/public/templates/settings.html b/public/templates/settings.html deleted file mode 100644 index 3c97213..0000000 --- a/public/templates/settings.html +++ /dev/null @@ -1,22 +0,0 @@ -{{>header this}} -
-

Settings

-
-
- -
- {{> general_tab}} {{> user_interface_tab}} {{> engines_tab}} {{> - cookies_tab}} -

- -
-
-
- - -{{>footer}} diff --git a/public/templates/user_interface_tab.html b/public/templates/user_interface_tab.html deleted file mode 100644 index 7de0f06..0000000 --- a/public/templates/user_interface_tab.html +++ /dev/null @@ -1,28 +0,0 @@ -
-

User Interface

-

select theme

-

- Select the theme from the available themes to be used in user interface -

- -

select color scheme

-

- Select the color scheme for your theme to be used in user interface -

- -
diff --git a/src/cache/redis_cacher.rs b/src/cache/redis_cacher.rs index e90344f..0e8ec38 100644 --- a/src/cache/redis_cacher.rs +++ b/src/cache/redis_cacher.rs @@ -1,9 +1,9 @@ //! This module provides the functionality to cache the aggregated results fetched and aggregated //! from the upstream search engines in a json format. +use blake3::hash; use error_stack::Report; use futures::future::try_join_all; -use md5::compute; use redis::{aio::ConnectionManager, AsyncCommands, Client, RedisError}; use super::error::CacheError; @@ -59,7 +59,7 @@ impl RedisCache { /// /// * `url` - It takes an url as string. fn hash_url(&self, url: &str) -> String { - format!("{:?}", compute(url)) + format!("{:?}", blake3::hash(url.as_bytes())) } /// A function which fetches the cached json results as json string from the redis server. diff --git a/src/config/parser.rs b/src/config/parser.rs index 0acdd25..1b8ba16 100644 --- a/src/config/parser.rs +++ b/src/config/parser.rs @@ -3,7 +3,6 @@ use crate::handler::paths::{file_path, FileType}; -use crate::models::engine_models::{EngineError, EngineHandler}; use crate::models::parser_models::{AggregatorConfig, RateLimiter, Style}; use log::LevelFilter; use mlua::Lua; @@ -29,7 +28,7 @@ pub struct Config { /// It stores the option to whether enable or disable debug mode. pub debug: bool, /// It stores all the engine names that were enabled by the user. - pub upstream_search_engines: Vec, + pub upstream_search_engines: HashMap, /// It stores the time (secs) which controls the server request timeout. pub request_timeout: u8, /// It stores the number of threads which controls the app will use to run. @@ -109,11 +108,7 @@ impl Config { logging, debug, upstream_search_engines: globals - .get::<_, HashMap>("upstream_search_engines")? - .into_iter() - .filter_map(|(key, value)| value.then_some(key)) - .map(|engine| EngineHandler::new(&engine)) - .collect::, error_stack::Report>>()?, + .get::<_, HashMap>("upstream_search_engines")?, request_timeout: globals.get::<_, u8>("request_timeout")?, threads, rate_limiter: RateLimiter { diff --git a/src/engines/brave.rs b/src/engines/brave.rs index 5c7c126..49626e3 100644 --- a/src/engines/brave.rs +++ b/src/engines/brave.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; -use reqwest::header::HeaderMap; +use reqwest::{header::HeaderMap, Client}; use scraper::Html; use crate::models::aggregation_models::SearchResult; @@ -42,7 +42,7 @@ impl SearchEngine for Brave { query: &str, page: u32, user_agent: &str, - request_timeout: u8, + client: &Client, safe_search: u8, ) -> Result, EngineError> { let url = format!("https://search.brave.com/search?q={query}&offset={page}"); @@ -68,7 +68,7 @@ impl SearchEngine for Brave { .change_context(EngineError::UnexpectedError)?; let document: Html = Html::parse_document( - &Brave::fetch_html_from_upstream(self, &url, header_map, request_timeout).await?, + &Brave::fetch_html_from_upstream(self, &url, header_map, client).await?, ); if let Some(no_result_msg) = self.parser.parse_for_no_results(&document).nth(0) { diff --git a/src/engines/duckduckgo.rs b/src/engines/duckduckgo.rs index 352a33b..fadddb6 100644 --- a/src/engines/duckduckgo.rs +++ b/src/engines/duckduckgo.rs @@ -5,6 +5,7 @@ use std::collections::HashMap; use reqwest::header::HeaderMap; +use reqwest::Client; use scraper::Html; use crate::models::aggregation_models::SearchResult; @@ -44,7 +45,7 @@ impl SearchEngine for DuckDuckGo { query: &str, page: u32, user_agent: &str, - request_timeout: u8, + client: &Client, _safe_search: u8, ) -> Result, EngineError> { // Page number can be missing or empty string and so appropriate handling is required @@ -76,7 +77,7 @@ impl SearchEngine for DuckDuckGo { .change_context(EngineError::UnexpectedError)?; let document: Html = Html::parse_document( - &DuckDuckGo::fetch_html_from_upstream(self, &url, header_map, request_timeout).await?, + &DuckDuckGo::fetch_html_from_upstream(self, &url, header_map, client).await?, ); if self.parser.parse_for_no_results(&document).next().is_some() { diff --git a/src/engines/searx.rs b/src/engines/searx.rs index 79c1e95..7bf0431 100644 --- a/src/engines/searx.rs +++ b/src/engines/searx.rs @@ -3,6 +3,7 @@ //! number if provided. use reqwest::header::HeaderMap; +use reqwest::Client; use scraper::Html; use std::collections::HashMap; @@ -40,7 +41,7 @@ impl SearchEngine for Searx { query: &str, page: u32, user_agent: &str, - request_timeout: u8, + client: &Client, mut safe_search: u8, ) -> Result, EngineError> { // Page number can be missing or empty string and so appropriate handling is required @@ -68,7 +69,7 @@ impl SearchEngine for Searx { .change_context(EngineError::UnexpectedError)?; let document: Html = Html::parse_document( - &Searx::fetch_html_from_upstream(self, &url, header_map, request_timeout).await?, + &Searx::fetch_html_from_upstream(self, &url, header_map, client).await?, ); if let Some(no_result_msg) = self.parser.parse_for_no_results(&document).nth(1) { diff --git a/src/lib.rs b/src/lib.rs index 73e9364..1d245fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ pub mod handler; pub mod models; pub mod results; pub mod server; +pub mod templates; use std::net::TcpListener; @@ -23,7 +24,6 @@ use actix_governor::{Governor, GovernorConfigBuilder}; use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer}; use cache::cacher::{Cache, SharedCache}; use config::parser::Config; -use handlebars::Handlebars; use handler::paths::{file_path, FileType}; /// Runs the web server on the provided TCP listener and returns a `Server` instance. @@ -48,16 +48,8 @@ use handler::paths::{file_path, FileType}; /// let server = run(listener,config,cache).expect("Failed to start server"); /// ``` pub fn run(listener: TcpListener, config: Config, cache: Cache) -> std::io::Result { - let mut handlebars: Handlebars<'_> = Handlebars::new(); - let public_folder_path: &str = file_path(FileType::Theme)?; - handlebars - .register_templates_directory(".html", format!("{}/templates", public_folder_path)) - .unwrap(); - - let handlebars_ref: web::Data> = web::Data::new(handlebars); - let cloned_config_threads_opt: u8 = config.threads; let cache = web::Data::new(SharedCache::new(cache)); @@ -75,7 +67,6 @@ pub fn run(listener: TcpListener, config: Config, cache: Cache) -> std::io::Resu App::new() .wrap(Logger::default()) // added logging middleware for logging. - .app_data(handlebars_ref.clone()) .app_data(web::Data::new(config.clone())) .app_data(cache.clone()) .wrap(cors) diff --git a/src/models/aggregation_models.rs b/src/models/aggregation_models.rs index 660804e..680d222 100644 --- a/src/models/aggregation_models.rs +++ b/src/models/aggregation_models.rs @@ -1,11 +1,10 @@ //! This module provides public models for handling, storing and serializing of search results //! data scraped from the upstream search engines. +use super::engine_models::EngineError; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; -use super::{engine_models::EngineError, parser_models::Style}; - /// A named struct to store the raw scraped search results scraped search results from the /// upstream search engines before aggregating it.It derives the Clone trait which is needed /// to write idiomatic rust using `Iterators`. @@ -109,10 +108,6 @@ impl EngineErrorInfo { pub struct SearchResults { /// Stores the individual serializable `SearchResult` struct into a vector of pub results: Vec, - /// Stores the current pages search query `q` provided in the search url. - pub page_query: String, - /// Stores the theming options for the website. - pub style: Style, /// Stores the information on which engines failed with their engine name /// and the type of error that caused it. pub engine_errors_info: Vec, @@ -142,15 +137,9 @@ impl SearchResults { /// the search url. /// * `engine_errors_info` - Takes an array of structs which contains information regarding /// which engines failed with their names, reason and their severity color name. - pub fn new( - results: Vec, - page_query: &str, - engine_errors_info: &[EngineErrorInfo], - ) -> Self { + pub fn new(results: Vec, engine_errors_info: &[EngineErrorInfo]) -> Self { Self { results, - page_query: page_query.to_owned(), - style: Style::default(), engine_errors_info: engine_errors_info.to_owned(), disallowed: Default::default(), filtered: Default::default(), @@ -159,21 +148,11 @@ impl SearchResults { } } - /// A setter function to add website style to the return search results. - pub fn add_style(&mut self, style: &Style) { - self.style = style.clone(); - } - /// A setter function that sets disallowed to true. pub fn set_disallowed(&mut self) { self.disallowed = true; } - /// A setter function to set the current page search query. - pub fn set_page_query(&mut self, page: &str) { - self.page_query = page.to_owned(); - } - /// A setter function that sets the filtered to true. pub fn set_filtered(&mut self) { self.filtered = true; diff --git a/src/models/engine_models.rs b/src/models/engine_models.rs index 98367e8..f8e966e 100644 --- a/src/models/engine_models.rs +++ b/src/models/engine_models.rs @@ -3,7 +3,8 @@ use super::aggregation_models::SearchResult; use error_stack::{Report, Result, ResultExt}; -use std::{collections::HashMap, fmt, time::Duration}; +use reqwest::Client; +use std::{collections::HashMap, fmt}; /// A custom error type used for handle engine associated errors. #[derive(Debug)] @@ -71,12 +72,11 @@ pub trait SearchEngine: Sync + Send { &self, url: &str, header_map: reqwest::header::HeaderMap, - request_timeout: u8, + client: &Client, ) -> Result { // fetch the html from upstream search engine - Ok(reqwest::Client::new() + Ok(client .get(url) - .timeout(Duration::from_secs(request_timeout as u64)) // Add timeout to request to avoid DDOSing the server .headers(header_map) // add spoofed headers to emulate human behavior .send() .await @@ -109,7 +109,7 @@ pub trait SearchEngine: Sync + Send { query: &str, page: u32, user_agent: &str, - request_timeout: u8, + client: &Client, safe_search: u8, ) -> Result, EngineError>; } diff --git a/src/models/parser_models.rs b/src/models/parser_models.rs index 9dad348..a669bd6 100644 --- a/src/models/parser_models.rs +++ b/src/models/parser_models.rs @@ -1,8 +1,6 @@ //! This module provides public models for handling, storing and serializing parsed config file //! options from config.lua by grouping them together. -use serde::{Deserialize, Serialize}; - /// A named struct which stores,deserializes, serializes and groups the parsed config file options /// of theme and colorscheme names into the Style struct which derives the `Clone`, `Serialize` /// and Deserialize traits where the `Clone` trait is derived for allowing the struct to be @@ -12,7 +10,7 @@ use serde::{Deserialize, Serialize}; /// order to allow the deserializing the json back to struct in aggregate function in /// aggregator.rs and create a new struct out of it and then serialize it back to json and pass /// it to the template files. -#[derive(Serialize, Deserialize, Clone, Default)] +#[derive(Clone, Default)] pub struct Style { /// It stores the parsed theme option used to set a theme for the website. pub theme: String, diff --git a/src/results/aggregator.rs b/src/results/aggregator.rs index 18fdb92..5c53864 100644 --- a/src/results/aggregator.rs +++ b/src/results/aggregator.rs @@ -8,8 +8,9 @@ use crate::models::{ engine_models::{EngineError, EngineHandler}, }; use error_stack::Report; -use rand::Rng; use regex::Regex; +use reqwest::{Client, ClientBuilder}; +use std::time::{SystemTime, UNIX_EPOCH}; use std::{ collections::HashMap, io::{BufReader, Read}, @@ -18,6 +19,9 @@ use std::{ use std::{fs::File, io::BufRead}; use tokio::task::JoinHandle; +/// A constant for holding the prebuilt Client globally in the app. +static CLIENT: std::sync::OnceLock = std::sync::OnceLock::new(); + /// Aliases for long type annotations type FutureVec = Vec, Report>>>; @@ -68,13 +72,23 @@ pub async fn aggregate( request_timeout: u8, safe_search: u8, ) -> Result> { + let client = CLIENT.get_or_init(|| { + ClientBuilder::new() + .timeout(Duration::from_secs(request_timeout as u64)) // Add timeout to request to avoid DDOSing the server + .https_only(true) + .gzip(true) + .brotli(true) + .build() + .unwrap() + }); + let user_agent: &str = random_user_agent(); // Add a random delay before making the request. if random_delay || !debug { - let mut rng = rand::thread_rng(); - let delay_secs = rng.gen_range(1..10); - tokio::time::sleep(Duration::from_secs(delay_secs)).await; + let nanos = SystemTime::now().duration_since(UNIX_EPOCH)?.subsec_nanos() as f32; + let delay = ((nanos / 1_0000_0000 as f32).floor() as u64) + 1; + tokio::time::sleep(Duration::from_secs(delay)).await; } let mut names: Vec<&str> = Vec::with_capacity(0); @@ -88,7 +102,7 @@ pub async fn aggregate( let query: String = query.to_owned(); tasks.push(tokio::spawn(async move { search_engine - .results(&query, page, user_agent, request_timeout, safe_search) + .results(&query, page, user_agent, client, safe_search) .await })); } @@ -166,7 +180,7 @@ pub async fn aggregate( let results: Vec = result_map.into_values().collect(); - Ok(SearchResults::new(results, query, &engine_errors_info)) + Ok(SearchResults::new(results, &engine_errors_info)) } /// Filters a map of search results using a list of regex patterns. diff --git a/src/server/router.rs b/src/server/router.rs index 69a3ede..31b7e6a 100644 --- a/src/server/router.rs +++ b/src/server/router.rs @@ -7,30 +7,30 @@ use crate::{ handler::paths::{file_path, FileType}, }; use actix_web::{get, web, HttpRequest, HttpResponse}; -use handlebars::Handlebars; use std::fs::read_to_string; /// Handles the route of index page or main page of the `websurfx` meta search engine website. #[get("/")] -pub async fn index( - hbs: web::Data>, - config: web::Data, -) -> Result> { - let page_content: String = hbs.render("index", &config.style).unwrap(); - Ok(HttpResponse::Ok().body(page_content)) +pub async fn index(config: web::Data) -> Result> { + Ok(HttpResponse::Ok().body( + crate::templates::views::index::index(&config.style.colorscheme, &config.style.theme).0, + )) } /// Handles the route of any other accessed route/page which is not provided by the /// website essentially the 404 error page. pub async fn not_found( - hbs: web::Data>, config: web::Data, ) -> Result> { - let page_content: String = hbs.render("404", &config.style)?; - Ok(HttpResponse::Ok() .content_type("text/html; charset=utf-8") - .body(page_content)) + .body( + crate::templates::views::not_found::not_found( + &config.style.colorscheme, + &config.style.theme, + ) + .0, + )) } /// 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>, - config: web::Data, -) -> Result> { - let page_content: String = hbs.render("about", &config.style)?; - Ok(HttpResponse::Ok().body(page_content)) +pub async fn about(config: web::Data) -> Result> { + Ok(HttpResponse::Ok().body( + crate::templates::views::about::about(&config.style.colorscheme, &config.style.theme).0, + )) } /// Handles the route of settings page of the `websurfx` meta search engine website. #[get("/settings")] pub async fn settings( - hbs: web::Data>, config: web::Data, ) -> Result> { - let page_content: String = hbs.render("settings", &config.style)?; - Ok(HttpResponse::Ok().body(page_content)) + Ok(HttpResponse::Ok().body( + crate::templates::views::settings::settings( + &config.style.colorscheme, + &config.style.theme, + &config + .upstream_search_engines + .keys() + .collect::>(), + )? + .0, + )) } diff --git a/src/server/routes/search.rs b/src/server/routes/search.rs index 9dbd1e1..35c9cc4 100644 --- a/src/server/routes/search.rs +++ b/src/server/routes/search.rs @@ -6,13 +6,12 @@ use crate::{ handler::paths::{file_path, FileType}, models::{ aggregation_models::SearchResults, - engine_models::EngineHandler, + engine_models::{EngineError, EngineHandler}, server_models::{Cookie, SearchParams}, }, results::aggregator::aggregate, }; use actix_web::{get, web, HttpRequest, HttpResponse}; -use handlebars::Handlebars; use regex::Regex; use std::{ fs::File, @@ -20,19 +19,6 @@ use std::{ }; use tokio::join; -/// Handles the route of any other accessed route/page which is not provided by the -/// website essentially the 404 error page. -pub async fn not_found( - hbs: web::Data>, - config: web::Data, -) -> Result> { - let page_content: String = hbs.render("404", &config.style)?; - - Ok(HttpResponse::Ok() - .content_type("text/html; charset=utf-8") - .body(page_content)) -} - /// Handles the route of search page of the `websurfx` meta search engine website and it takes /// two search url parameters `q` and `page` where `page` parameter is optional. /// @@ -49,7 +35,6 @@ pub async fn not_found( /// ``` #[get("/search")] pub async fn search( - hbs: web::Data>, req: HttpRequest, config: web::Data, cache: web::Data, @@ -58,7 +43,7 @@ pub async fn search( match ¶ms.q { Some(query) => { if query.trim().is_empty() { - return Ok(HttpResponse::Found() + return Ok(HttpResponse::TemporaryRedirect() .insert_header(("location", "/")) .finish()); } @@ -112,10 +97,17 @@ pub async fn search( ) ); - let page_content: String = hbs.render("search", &results?)?; - Ok(HttpResponse::Ok().body(page_content)) + Ok(HttpResponse::Ok().body( + crate::templates::views::search::search( + &config.style.colorscheme, + &config.style.theme, + query, + &results?, + ) + .0, + )) } - None => Ok(HttpResponse::Found() + None => Ok(HttpResponse::TemporaryRedirect() .insert_header(("location", "/")) .finish()), } @@ -171,8 +163,6 @@ async fn results( if _flag { results.set_disallowed(); - results.add_style(&config.style); - results.set_page_query(query); cache.cache_results(&results, &url).await?; results.set_safe_search_level(safe_search_level); return Ok(results); @@ -221,23 +211,27 @@ async fn results( true => { let mut search_results = SearchResults::default(); search_results.set_no_engines_selected(); - search_results.set_page_query(query); search_results } } } - None => { - aggregate( - query, - page, - config.aggregator.random_delay, - config.debug, - &config.upstream_search_engines, - config.request_timeout, - safe_search_level, - ) - .await? - } + None => aggregate( + query, + page, + config.aggregator.random_delay, + config.debug, + &config + .upstream_search_engines + .clone() + .into_iter() + .filter_map(|(key, value)| value.then_some(key)) + .map(|engine| EngineHandler::new(&engine)) + .collect::, error_stack::Report>>( + )?, + config.request_timeout, + safe_search_level, + ) + .await?, }; if results.engine_errors_info().is_empty() && results.results().is_empty() @@ -245,7 +239,6 @@ async fn results( { results.set_filtered(); } - results.add_style(&config.style); cache .cache_results(&results, &(format!("{url}{safe_search_level}"))) .await?; diff --git a/src/templates/mod.rs b/src/templates/mod.rs new file mode 100644 index 0000000..bc39dce --- /dev/null +++ b/src/templates/mod.rs @@ -0,0 +1,5 @@ +//! This module provides other modules to handle both the view and its partials for the `websurfx` +//! search engine frontend. + +mod partials; +pub mod views; diff --git a/src/templates/partials/bar.rs b/src/templates/partials/bar.rs new file mode 100644 index 0000000..13f78a8 --- /dev/null +++ b/src/templates/partials/bar.rs @@ -0,0 +1,21 @@ +//! A module that handles `bar` partial for the `search_bar` partial and the home/index/main page in the `websurfx` frontend. + +use maud::{html, Markup, PreEscaped}; + +/// A functions that handles the html code for the bar for the `search_bar` partial and the +/// home/index/main page in the search engine frontend. +/// +/// # Arguments +/// +/// * `query` - It takes the current search query provided by user as an argument. +/// +/// # Returns +/// +/// It returns the compiled html code for the search bar as a result. +pub fn bar(query: &str) -> Markup { + html!( + (PreEscaped("
")) + input type="search" name="search-box" value=(query) placeholder="Type to search"; + button type="submit" onclick="searchWeb()"{"search"} + ) +} diff --git a/src/templates/partials/footer.rs b/src/templates/partials/footer.rs new file mode 100644 index 0000000..beaa8ca --- /dev/null +++ b/src/templates/partials/footer.rs @@ -0,0 +1,29 @@ +//! A module that handles the footer for all the pages in the `websurfx` frontend. + +use maud::{html, Markup, PreEscaped}; + +/// A functions that handles the html code for the footer for all the pages in the search engine +/// frontend. +/// +/// # Returns +/// +/// It returns the compiled html code for the footer as a result. +pub fn footer() -> Markup { + html!( + footer{ + div{ + span{"Powered By "b{"Websurfx"}}span{"-"}span{"a lightening fast, privacy respecting, secure meta + search engine"} + } + div{ + ul{ + li{a href="https://github.com/neon-mmd/websurfx"{"Source Code"}} + li{a href="https://github.com/neon-mmd/websurfx/issues"{"Issues/Bugs"}} + } + } + } + script src="static/settings.js"{} + (PreEscaped("")) + (PreEscaped("")) + ) +} diff --git a/src/templates/partials/header.rs b/src/templates/partials/header.rs new file mode 100644 index 0000000..c477aec --- /dev/null +++ b/src/templates/partials/header.rs @@ -0,0 +1,35 @@ +//! A module that handles the header for all the pages in the `websurfx` frontend. + +use crate::templates::partials::navbar::navbar; +use maud::{html, Markup, PreEscaped, DOCTYPE}; + +/// A function that handles the html code for the header for all the pages in the search engine frontend. +/// +/// # Arguments +/// +/// * `colorscheme` - It takes the colorscheme name as an argument. +/// * `theme` - It takes the theme name as an argument. +/// +/// # Returns +/// +/// It returns the compiled html markup code for the header as a result. +pub fn header(colorscheme: &str, theme: &str) -> Markup { + html!( + (DOCTYPE) + html lang="en" + + head{ + title{"Websurfx"} + meta charset="UTF-8"; + meta name="viewport" content="width=device-width, initial-scale=1"; + link href=(format!("static/colorschemes/{colorscheme}.css")) rel="stylesheet" type="text/css"; + link href=(format!("static/themes/{theme}.css")) rel="stylesheet" type="text/css"; + } + + (PreEscaped("")) + header{ + h1{a href="/"{"Websurfx"}} + (navbar()) + } + ) +} diff --git a/src/templates/partials/mod.rs b/src/templates/partials/mod.rs new file mode 100644 index 0000000..0e6b803 --- /dev/null +++ b/src/templates/partials/mod.rs @@ -0,0 +1,8 @@ +//! This module provides other modules to handle the partials for the views in the `websurfx` frontend. + +pub mod bar; +pub mod footer; +pub mod header; +pub mod navbar; +pub mod search_bar; +pub mod settings_tabs; diff --git a/src/templates/partials/navbar.rs b/src/templates/partials/navbar.rs new file mode 100644 index 0000000..f1f86fd --- /dev/null +++ b/src/templates/partials/navbar.rs @@ -0,0 +1,19 @@ +//! A module that handles `navbar` partial for the header partial in the `websurfx` frontend. + +use maud::{html, Markup}; + +/// A functions that handles the html code for the header partial. +/// +/// # Returns +/// +/// It returns the compiled html code for the navbar as a result. +pub fn navbar() -> Markup { + html!( + nav{ + ul{ + li{a href="about"{"about"}} + li{a href="settings"{"settings"}} + } + } + ) +} diff --git a/src/templates/partials/search_bar.rs b/src/templates/partials/search_bar.rs new file mode 100644 index 0000000..c40244c --- /dev/null +++ b/src/templates/partials/search_bar.rs @@ -0,0 +1,76 @@ +//! A module that handles `search bar` partial for the search page in the `websurfx` frontend. + +use maud::{html, Markup, PreEscaped}; + +use crate::{models::aggregation_models::EngineErrorInfo, templates::partials::bar::bar}; + +/// A constant holding the named safe search level options for the corresponding values 0, 1 and 2. +const SAFE_SEARCH_LEVELS_NAME: [&str; 3] = ["None", "Low", "Moderate"]; + +/// A functions that handles the html code for the search bar for the search page. +/// +/// # Arguments +/// +/// * `engine_errors_info` - It takes the engine errors list containing errors for each upstream +/// search engine which failed to provide results as an argument. +/// * `safe_search_level` - It takes the safe search level with values from 0-2 as an argument. +/// * `query` - It takes the current search query provided by user as an argument. +/// +/// # Returns +/// +/// It returns the compiled html code for the search bar as a result. +pub fn search_bar( + engine_errors_info: &[EngineErrorInfo], + safe_search_level: u8, + query: &str, +) -> Markup { + html!( + .search_area{ + (bar(query)) + .error_box { + @if !engine_errors_info.is_empty(){ + button onclick="toggleErrorBox()" class="error_box_toggle_button"{ + img src="./images/warning.svg" alt="Info icon for error box"; + } + .dropdown_error_box{ + @for errors in engine_errors_info{ + .error_item{ + span class="engine_name"{(errors.engine)} + span class="engine_name"{(errors.error)} + span class="severity_color" style="background: {{{this.severity_color}}};"{} + } + } + } + } + @else { + button onclick="toggleErrorBox()" class="error_box_toggle_button"{ + img src="./images/info.svg" alt="Warning icon for error box"; + } + .dropdown_error_box { + .no_errors{ + "Everything looks good 🙂!!" + } + } + } + } + (PreEscaped("
")) + .search_options { + @if safe_search_level >= 3 { + (PreEscaped("")) + } + @for (idx, name) in SAFE_SEARCH_LEVELS_NAME.iter().enumerate() { + @if (safe_search_level as usize) == idx { + option value=(idx) selected {(format!("SafeSearch: {name}"))} + } + @else{ + option value=(idx) {(format!("SafeSearch: {name}"))} + } + } + (PreEscaped("")) + } + } + ) +} diff --git a/src/templates/partials/settings_tabs/cookies.rs b/src/templates/partials/settings_tabs/cookies.rs new file mode 100644 index 0000000..c8bc8e6 --- /dev/null +++ b/src/templates/partials/settings_tabs/cookies.rs @@ -0,0 +1,25 @@ +//! A module that handles the engines tab for setting page view in the `websurfx` frontend. + +use maud::{html, Markup}; + +/// A functions that handles the html code for the cookies tab for the settings page for the search page. +/// +/// # Returns +/// +/// It returns the compiled html markup code for the cookies tab. +pub fn cookies() -> Markup { + html!( + div class="cookies tab"{ + h1{"Cookies"} + p class="description"{ + "This is the cookies are saved on your system and it contains the preferences + you chose in the settings page" + } + input type="text" name="cookie_field" value="" readonly; + p class="description"{ + "The cookies stored are not used by us for any malicious intend or for + tracking you in any way." + } + } + ) +} diff --git a/src/templates/partials/settings_tabs/engines.rs b/src/templates/partials/settings_tabs/engines.rs new file mode 100644 index 0000000..5394178 --- /dev/null +++ b/src/templates/partials/settings_tabs/engines.rs @@ -0,0 +1,43 @@ +//! A module that handles the engines tab for setting page view in the `websurfx` frontend. + +use maud::{html, Markup}; + +/// A functions that handles the html code for the engines tab for the settings page for the search page. +/// +/// # Arguments +/// +/// * `engine_names` - It takes the list of all available engine names as an argument. +/// +/// # Returns +/// +/// It returns the compiled html markup code for the engines tab. +pub fn engines(engine_names: &[&String]) -> Markup { + html!( + div class="engines tab"{ + h1{"Engines"} + h3{"select search engines"} + p class="description"{ + "Select the search engines from the list of engines that you want results from" + } + .engine_selection{ + .toggle_btn{ + label class="switch"{ + input type="checkbox" class="select_all" onchange="toggleAllSelection()"; + span class="slider round"{} + } + "Select All" + } + hr; + @for engine_name in engine_names{ + .toggle_btn{ + label class="switch"{ + input type="checkbox" class="engine"; + span class="slider round"{} + } + (format!("{}{}",engine_name[..1].to_uppercase().to_owned(), engine_name[1..].to_owned())) + } + } + } + } + ) +} diff --git a/src/templates/partials/settings_tabs/general.rs b/src/templates/partials/settings_tabs/general.rs new file mode 100644 index 0000000..4b0043d --- /dev/null +++ b/src/templates/partials/settings_tabs/general.rs @@ -0,0 +1,28 @@ +//! A module that handles the general tab for setting page view in the `websurfx` frontend. + +use maud::{html, Markup}; + +/// A constant holding the named safe search level options for the corresponding values 0, 1 and 2. +const SAFE_SEARCH_LEVELS: [(u8, &str); 3] = [(0, "None"), (1, "Low"), (2, "Moderate")]; + +/// A functions that handles the html code for the general tab for the settings page for the search page. +/// +/// # Returns +/// +/// It returns the compiled html markup code for the general tab. +pub fn general() -> Markup { + html!( + div class="general tab active"{ + h1{"General"} + h3{"Select a safe search level"} + p class="description"{ + "Select a safe search level from the menu below to filter content based on the level." + } + select name="safe_search_levels"{ + @for (k,v) in SAFE_SEARCH_LEVELS{ + option value=(k){(v)} + } + } + } + ) +} diff --git a/src/templates/partials/settings_tabs/mod.rs b/src/templates/partials/settings_tabs/mod.rs new file mode 100644 index 0000000..84973d9 --- /dev/null +++ b/src/templates/partials/settings_tabs/mod.rs @@ -0,0 +1,7 @@ +//! This module provides other modules to handle the partials for the tabs for the settings page +//! view in the `websurfx` frontend. + +pub mod cookies; +pub mod engines; +pub mod general; +pub mod user_interface; diff --git a/src/templates/partials/settings_tabs/user_interface.rs b/src/templates/partials/settings_tabs/user_interface.rs new file mode 100644 index 0000000..90e1ce9 --- /dev/null +++ b/src/templates/partials/settings_tabs/user_interface.rs @@ -0,0 +1,65 @@ +//! A module that handles the user interface tab for setting page view in the `websurfx` frontend. + +use crate::handler::paths::{file_path, FileType}; +use maud::{html, Markup}; +use std::fs::read_dir; + +/// A helper function that helps in building the list of all available colorscheme/theme names +/// present in the colorschemes and themes folder respectively. +/// +/// # Arguments +/// +/// * `style_type` - It takes the style type of the values `theme` and `colorscheme` as an +/// argument. +/// +/// # Error +/// +/// Returns a list of colorscheme/theme names as a vector of tuple strings on success otherwise +/// returns a standard error message. +fn style_option_list( + style_type: &str, +) -> Result, Box> { + let mut style_option_names: Vec<(String, String)> = Vec::new(); + for file in read_dir(format!( + "{}static/{}/", + file_path(FileType::Theme)?, + style_type, + ))? { + let style_name = file?.file_name().to_str().unwrap().replace(".css", ""); + style_option_names.push((style_name.clone(), style_name.replace('-', " "))); + } + + Ok(style_option_names) +} + +/// A functions that handles the html code for the user interface tab for the settings page for the search page. +/// +/// # Error +/// +/// It returns the compiled html markup code for the user interface tab on success otherwise +/// returns a standard error message. +pub fn user_interface() -> Result> { + Ok(html!( + div class="user_interface tab"{ + h1{"User Interface"} + h3{"select theme"} + p class="description"{ + "Select the theme from the available themes to be used in user interface" + } + select name="themes"{ + @for (k,v) in style_option_list("themes")?{ + option value=(k){(v)} + } + } + h3{"select color scheme"} + p class="description"{ + "Select the color scheme for your theme to be used in user interface" + } + select name="colorschemes"{ + @for (k,v) in style_option_list("colorschemes")?{ + option value=(k){(v)} + } + } + } + )) +} diff --git a/src/templates/views/about.rs b/src/templates/views/about.rs new file mode 100644 index 0000000..9ee2d6d --- /dev/null +++ b/src/templates/views/about.rs @@ -0,0 +1,48 @@ +//! A module that handles the view for the about page in the `websurfx` frontend. + +use maud::{html, Markup}; + +use crate::templates::partials::{footer::footer, header::header}; + +/// A function that handles the html code for the about page view in the search engine frontend. +/// +/// # Arguments +/// +/// * `colorscheme` - It takes the colorscheme name as an argument. +/// * `theme` - It takes the theme name as an argument. +/// +/// # Returns +/// +/// It returns the compiled html markup code as a result. +pub fn about(colorscheme: &str, theme: &str) -> Markup { + html!( + (header(colorscheme, theme)) + main class="about-container"{ + article { + div{ + h1{"Websurfx"} + hr size="4" width="100%" color="#a6e3a1"{} + } + 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." + } + + h2{"Some of the Top Features:"} + + ul{strong{"Lightning fast "}"- Results load within milliseconds for an instant search experience."} + + ul{strong{"Secure search"}" - All searches are performed over an encrypted connection to prevent snooping."} + + ul{strong{"Ad free results"}" - All search results are ad free and clutter free for a clean search experience."} + + ul{strong{"Privacy focused"}" - Websurfx does not track, store or sell your search data. Your privacy is our priority."} + + 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."} + + ul{strong{"Highly customizable"}" - Websurfx comes with 9 built-in color themes and supports creating custom themes effortlessly."} + } + + h3{"Devoloped by: "{a href="https://github.com/neon-mmd/websurfx"{"Websurfx team"}}} + } + (footer()) + ) +} diff --git a/src/templates/views/index.rs b/src/templates/views/index.rs new file mode 100644 index 0000000..3816f22 --- /dev/null +++ b/src/templates/views/index.rs @@ -0,0 +1,28 @@ +//! A module that handles the view for the index/home/main page in the `websurfx` frontend. + +use maud::{html, Markup, PreEscaped}; + +use crate::templates::partials::{bar::bar, footer::footer, header::header}; + +/// A function that handles the html code for the index/html/main page view in the search engine frontend. +/// +/// # Arguments +/// +/// * `colorscheme` - It takes the colorscheme name as an argument. +/// * `theme` - It takes the theme name as an argument. +/// +/// # Returns +/// +/// It returns the compiled html markup code as a result. +pub fn index(colorscheme: &str, theme: &str) -> Markup { + html!( + (header(colorscheme, theme)) + main class="search-container"{ + img src="../images/websurfx_logo.png" alt="Websurfx meta-search engine logo"; + (bar(&String::default())) + (PreEscaped("")) + } + script src="static/index.js"{} + (footer()) + ) +} diff --git a/src/templates/views/mod.rs b/src/templates/views/mod.rs new file mode 100644 index 0000000..bbfe189 --- /dev/null +++ b/src/templates/views/mod.rs @@ -0,0 +1,8 @@ +//! This module provides other modules to handle view for each individual page in the +//! `websurfx` frontend. + +pub mod about; +pub mod index; +pub mod not_found; +pub mod search; +pub mod settings; diff --git a/src/templates/views/not_found.rs b/src/templates/views/not_found.rs new file mode 100644 index 0000000..9e23da9 --- /dev/null +++ b/src/templates/views/not_found.rs @@ -0,0 +1,29 @@ +//! A module that handles the view for the 404 page in the `websurfx` frontend. + +use crate::templates::partials::{footer::footer, header::header}; +use maud::{html, Markup}; + +/// A function that handles the html code for the 404 page view in the search engine frontend. +/// +/// # Arguments +/// +/// * `colorscheme` - It takes the colorscheme name as an argument. +/// * `theme` - It takes the theme name as an argument. +/// +/// # Returns +/// +/// It returns the compiled html markup code as a result. +pub fn not_found(colorscheme: &str, theme: &str) -> Markup { + html!( + (header(colorscheme, theme)) + main class="error_container"{ + img src="images/robot-404.svg" alt="Image of broken robot."; + .error_content{ + h1{"Aw! snap"} + h2{"404 Page Not Found!"} + p{"Go to "{a href="/"{"search page"}}} + } + } + (footer()) + ) +} diff --git a/src/templates/views/search.rs b/src/templates/views/search.rs new file mode 100644 index 0000000..440d585 --- /dev/null +++ b/src/templates/views/search.rs @@ -0,0 +1,122 @@ +//! A module that handles the view for the search page in the `websurfx` frontend. + +use maud::{html, Markup, PreEscaped}; + +use crate::{ + models::aggregation_models::SearchResults, + templates::partials::{footer::footer, header::header, search_bar::search_bar}, +}; + +/// A function that handles the html code for the search page view in the search engine frontend. +/// +/// # Arguments +/// +/// * `colorscheme` - It takes the colorscheme name as an argument. +/// * `theme` - It takes the theme name as an argument. +/// * `query` - It takes the current search query provided by the user as an argument. +/// * `search_results` - It takes the aggregated search results as an argument. +/// +/// # Returns +/// +/// It returns the compiled html markup code as a result. +pub fn search( + colorscheme: &str, + theme: &str, + query: &str, + search_results: &SearchResults, +) -> Markup { + html!( + (header(colorscheme, theme)) + main class="results"{ + (search_bar(&search_results.engine_errors_info, search_results.safe_search_level, query)) + .results_aggregated{ + @if !search_results.results.is_empty() { + @for result in search_results.results.iter(){ + .result { + h1{a href=(result.url){(PreEscaped(&result.title))}} + small{(result.url)} + p{(PreEscaped(&result.description))} + .upstream_engines{ + @for name in result.clone().engine{ + span{(name)} + } + } + } + } + } + @else if search_results.disallowed{ + .result_disallowed{ + .description{ + p{ + "Your search - "{span class="user_query"{(query)}}" - + has been disallowed." + } + p class="description_paragraph"{"Dear user,"} + p class="description_paragraph"{ + "The query - "{span class="user_query"{(query)}}" - has + been blacklisted via server configuration and hence disallowed by the + server. Henceforth no results could be displayed for your query." + } + } + img src="./images/barricade.png" alt="Image of a Barricade"; + } + } + @else if search_results.filtered { + .result_filtered{ + .description{ + p{ + "Your search - "{span class="user_query"{(query)}}" - + has been filtered." + } + p class="description_paragraph"{"Dear user,"} + p class="description_paragraph"{ + "All the search results contain results that has been configured to be + filtered out via server configuration and henceforth has been + completely filtered out." + } + } + img src="./images/filter.png" alt="Image of a paper inside a funnel"; + } + } + @else if search_results.no_engines_selected { + .result_engine_not_selected{ + .description{ + p{ + "No results could be fetched for your search '{span class="user_query"{(query)}}'." + } + p class="description_paragraph"{"Dear user,"} + p class="description_paragraph"{ + "No results could be retrieved from the upstream search engines as no + upstream search engines were selected from the settings page." + } + } + img src="./images/no_selection.png" alt="Image of a white cross inside a red circle"; + } + } + @else{ + .result_not_found { + p{"Your search - "{(query)}" - did not match any documents."} + p class="suggestions"{"Suggestions:"} + ul{ + li{"Make sure that all words are spelled correctly."} + li{"Try different keywords."} + li{"Try more general keywords."} + } + img src="./images/no_results.gif" alt="Man fishing gif"; + } + } + } + .page_navigation { + button type="button" onclick="navigate_backward()"{ + (PreEscaped("←")) "previous" + } + button type="button" onclick="navigate_forward()"{"next" (PreEscaped("→"))} + } + } + script src="static/index.js"{} + script src="static/search_area_options.js"{} + script src="static/pagination.js"{} + script src="static/error_box.js"{} + (footer()) + ) +} diff --git a/src/templates/views/settings.rs b/src/templates/views/settings.rs new file mode 100644 index 0000000..7b69ac7 --- /dev/null +++ b/src/templates/views/settings.rs @@ -0,0 +1,56 @@ +//! A module that handles the view for the settings page in the `websurfx` frontend. + +use maud::{html, Markup}; + +use crate::templates::partials::{ + footer::footer, + header::header, + settings_tabs::{ + cookies::cookies, engines::engines, general::general, user_interface::user_interface, + }, +}; + +/// A function that handles the html code for the settings page view in the search engine frontend. +/// +/// # Arguments +/// +/// * `colorscheme` - It takes the colorscheme name as an argument. +/// * `theme` - It takes the theme name as an argument. +/// * `engine_names` - It takes a list of engine names as an argument. +/// +/// # Error +/// +/// This function returns a compiled html markup code on success otherwise returns a standard error +/// message. +pub fn settings( + colorscheme: &str, + theme: &str, + engine_names: &[&String], +) -> Result> { + Ok(html!( + (header(colorscheme, theme)) + main class="settings"{ + h1{"Settings"} + hr; + .settings_container{ + .sidebar{ + div class="btn active" onclick="setActiveTab(this)"{"general"} + .btn onclick="setActiveTab(this)"{"user interface"} + .btn onclick="setActiveTab(this)"{"engines"} + .btn onclick="setActiveTab(this)"{"cookies"} + } + .main_container{ + (general()) + (user_interface()?) + (engines(engine_names)) + (cookies()) + p class="message"{} + button type="submit" onclick="setClientSettings()"{"Save"} + } + } + } + script src="static/settings.js"{} + script src="static/cookies.js"{} + (footer()) + )) +} diff --git a/tests/index.rs b/tests/index.rs index 91d0814..3bd7381 100644 --- a/tests/index.rs +++ b/tests/index.rs @@ -1,7 +1,6 @@ use std::net::TcpListener; -use handlebars::Handlebars; -use websurfx::{config::parser::Config, run}; +use websurfx::{config::parser::Config, run, templates::views}; // Starts a new instance of the HTTP server, bound to a random available port fn spawn_app() -> String { @@ -21,18 +20,6 @@ fn spawn_app() -> String { format!("http://127.0.0.1:{}/", port) } -// Creates a new instance of Handlebars and registers the templates directory. -// This is used to compare the rendered template with the response body. -fn handlebars() -> Handlebars<'static> { - let mut handlebars = Handlebars::new(); - - handlebars - .register_templates_directory(".html", "./public/templates") - .unwrap(); - - handlebars -} - #[tokio::test] async fn test_index() { let address = spawn_app(); @@ -41,9 +28,8 @@ async fn test_index() { let res = client.get(address).send().await.unwrap(); assert_eq!(res.status(), 200); - let handlebars = handlebars(); let config = Config::parse(true).unwrap(); - let template = handlebars.render("index", &config.style).unwrap(); + let template = views::index::index(&config.style.colorscheme, &config.style.theme).0; assert_eq!(res.text().await.unwrap(), template); }