summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2026-07-31 21:59:42 +0800
committerlittleblack111 <littleblack11111@gmail.com>2026-07-31 22:23:29 +0800
commit1d6da847b7075b4babf3409b9445db0b54677893 (patch)
tree1dd6141f2450bef7d35cd3bd36331b5b258f5e85
parent586f32bb99c7539f2d89ac617b86a62166b30993 (diff)
qml_plugin: duckduckgo
-rw-r--r--qml_plugin/Cargo.lock462
-rw-r--r--qml_plugin/Cargo.toml5
-rw-r--r--qml_plugin/src/lib.rs1
-rw-r--r--qml_plugin/src/web.rs2
-rw-r--r--qml_plugin/src/web/duckduckgo.rs127
-rw-r--r--qml_plugin/src/web/google.rs0
6 files changed, 595 insertions, 2 deletions
diff --git a/qml_plugin/Cargo.lock b/qml_plugin/Cargo.lock
index ee9fb39..e84ee50 100644
--- a/qml_plugin/Cargo.lock
+++ b/qml_plugin/Cargo.lock
@@ -173,7 +173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3"
dependencies = [
"chrono",
- "phf",
+ "phf 0.12.1",
]
[[package]]
@@ -261,6 +261,35 @@ dependencies = [
]
[[package]]
+name = "cookie"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
+dependencies = [
+ "percent-encoding",
+ "time",
+ "version_check",
+]
+
+[[package]]
+name = "cookie_store"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206"
+dependencies = [
+ "cookie",
+ "document-features",
+ "idna",
+ "log",
+ "publicsuffix",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "time",
+ "url",
+]
+
+[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -305,6 +334,29 @@ dependencies = [
]
[[package]]
+name = "cssparser"
+version = "0.37.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c9cdaae01d5ed7882b04d795e7f752f46ff52d2fa3b50a20d28c464510bba98"
+dependencies = [
+ "cssparser-macros",
+ "dtoa-short",
+ "itoa",
+ "phf 0.13.1",
+ "smallvec",
+]
+
+[[package]]
+name = "cssparser-macros"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10a2a99df6e410a8ff4245aa2006499ea662245f967cc7c0a38c83ef8eb44dbf"
+dependencies = [
+ "quote",
+ "syn 2.0.119",
+]
+
+[[package]]
name = "cxx"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -450,6 +502,33 @@ dependencies = [
]
[[package]]
+name = "deranged"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
+
+[[package]]
+name = "derive_more"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
+dependencies = [
+ "derive_more-impl",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn 2.0.119",
+]
+
+[[package]]
name = "displaydoc"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -461,12 +540,59 @@ dependencies = [
]
[[package]]
+name = "document-features"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
+name = "dtoa"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590"
+
+[[package]]
+name = "dtoa-short"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87"
+dependencies = [
+ "dtoa",
+]
+
+[[package]]
+name = "duckduckgo"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36355bd0a557b39a74c28749937b7fa1bcb092642dfd07823f77d2fff7491eb1"
+dependencies = [
+ "anyhow",
+ "chrono",
+ "phf 0.13.1",
+ "regex",
+ "reqwest",
+ "scraper",
+ "serde",
+ "serde_json",
+ "urlencoding",
+]
+
+[[package]]
name = "dunce"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
[[package]]
+name = "ego-tree"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b04dc5a38e4f151a79d9f2451ae6037fb6eaf5cba34771f44781f80e508498e3"
+
+[[package]]
name = "either"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -488,6 +614,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
+name = "fastrand"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
+
+[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -572,6 +704,15 @@ dependencies = [
]
[[package]]
+name = "getopts"
+version = "0.2.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df"
+dependencies = [
+ "unicode-width 0.2.2",
+]
+
+[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -634,6 +775,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
+name = "html5ever"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8"
+dependencies = [
+ "log",
+ "markup5ever",
+]
+
+[[package]]
name = "http"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1350,6 +1501,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
[[package]]
+name = "litrs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
+
+[[package]]
+name = "lock_api"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
name = "log"
version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1362,6 +1528,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
+name = "markup5ever"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de"
+dependencies = [
+ "log",
+ "tendril",
+ "web_atoms",
+]
+
+[[package]]
name = "memchr"
version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1385,6 +1562,12 @@ dependencies = [
]
[[package]]
+name = "new_debug_unreachable"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
+
+[[package]]
name = "num-bigint"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1395,6 +1578,12 @@ dependencies = [
]
[[package]]
+name = "num-conv"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
+
+[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1446,6 +1635,29 @@ dependencies = [
]
[[package]]
+name = "parking_lot"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-link",
+]
+
+[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1457,7 +1669,51 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7"
dependencies = [
- "phf_shared",
+ "phf_shared 0.12.1",
+]
+
+[[package]]
+name = "phf"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
+dependencies = [
+ "phf_macros",
+ "phf_shared 0.13.1",
+ "serde",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1"
+dependencies = [
+ "phf_generator",
+ "phf_shared 0.13.1",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
+dependencies = [
+ "fastrand",
+ "phf_shared 0.13.1",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
+dependencies = [
+ "phf_generator",
+ "phf_shared 0.13.1",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
]
[[package]]
@@ -1470,6 +1726,15 @@ dependencies = [
]
[[package]]
+name = "phf_shared"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1493,6 +1758,18 @@ dependencies = [
]
[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "precomputed-hash"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
+
+[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1502,14 +1779,35 @@ dependencies = [
]
[[package]]
+name = "psl-types"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
+
+[[package]]
+name = "publicsuffix"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf"
+dependencies = [
+ "idna",
+ "psl-types",
+]
+
+[[package]]
name = "qml_plugin"
version = "0.1.0"
dependencies = [
+ "anyhow",
"cxx",
"cxx-qt",
"cxx-qt-build",
"cxx-qt-lib",
+ "duckduckgo",
"kalk",
+ "reqwest",
+ "serde",
+ "serde_json",
"smart-calculator",
"tokio",
]
@@ -1627,6 +1925,15 @@ dependencies = [
]
[[package]]
+name = "redox_syscall"
+version = "0.5.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
name = "regex"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1663,6 +1970,8 @@ checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
dependencies = [
"base64",
"bytes",
+ "cookie",
+ "cookie_store",
"encoding_rs",
"futures-core",
"h2",
@@ -1683,6 +1992,7 @@ dependencies = [
"rustls-platform-verifier",
"serde",
"serde_json",
+ "serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-rustls",
@@ -1842,6 +2152,27 @@ dependencies = [
]
[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "scraper"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdd0be4d296f048bfb06dd01bbc80ef789ddd2e55583e8d2e6b804942abfabc2"
+dependencies = [
+ "cssparser",
+ "ego-tree",
+ "getopts",
+ "html5ever",
+ "precomputed-hash",
+ "selectors",
+ "tendril",
+]
+
+[[package]]
name = "scratch"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1881,6 +2212,25 @@ dependencies = [
]
[[package]]
+name = "selectors"
+version = "0.38.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8adfa1c298912827b8a28b223b3b874357397ae706e6190acd9bf28cee99114d"
+dependencies = [
+ "bitflags",
+ "cssparser",
+ "derive_more",
+ "log",
+ "new_debug_unreachable",
+ "phf 0.13.1",
+ "phf_codegen",
+ "precomputed-hash",
+ "rustc-hash",
+ "servo_arc",
+ "smallvec",
+]
+
+[[package]]
name = "semver"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1930,6 +2280,27 @@ dependencies = [
]
[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "servo_arc"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930"
+dependencies = [
+ "stable_deref_trait",
+]
+
+[[package]]
name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2013,6 +2384,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
+name = "string_cache"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901"
+dependencies = [
+ "new_debug_unreachable",
+ "parking_lot",
+ "phf_shared 0.13.1",
+ "precomputed-hash",
+]
+
+[[package]]
+name = "string_cache_codegen"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69"
+dependencies = [
+ "phf_generator",
+ "phf_shared 0.13.1",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2088,6 +2483,15 @@ dependencies = [
]
[[package]]
+name = "tendril"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fed54709c5b3a53d09bb1c113ea4f5ceafd1e772ddcb0030a82e1d56c087b08"
+dependencies = [
+ "new_debug_unreachable",
+]
+
+[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2137,6 +2541,36 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.3.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244"
+dependencies = [
+ "deranged",
+ "num-conv",
+ "powerfmt",
+ "serde_core",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
+
+[[package]]
+name = "time-macros"
+version = "0.2.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
name = "tinystr"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2325,6 +2759,12 @@ dependencies = [
]
[[package]]
+name = "urlencoding"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
+
+[[package]]
name = "utf16_iter"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2337,6 +2777,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2437,6 +2883,18 @@ dependencies = [
]
[[package]]
+name = "web_atoms"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297"
+dependencies = [
+ "phf 0.13.1",
+ "phf_codegen",
+ "string_cache",
+ "string_cache_codegen",
+]
+
+[[package]]
name = "webpki-root-certs"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/qml_plugin/Cargo.toml b/qml_plugin/Cargo.toml
index 5ae6a1c..19e6f19 100644
--- a/qml_plugin/Cargo.toml
+++ b/qml_plugin/Cargo.toml
@@ -7,10 +7,15 @@ edition = "2024"
crate-type = ["cdylib"]
[dependencies]
+anyhow = "1.0.104"
cxx = "1.0.198"
cxx-qt = "0.9.1"
cxx-qt-lib = "0.9.1"
+duckduckgo = "0.3.3"
kalk = "3.2.3"
+reqwest = "0.13.4"
+serde = { version = "1.0.229", features = ["derive"] }
+serde_json = "1.0.151"
smart-calculator = "1.0.3"
tokio = { version = "1.53.1", features = ["rt-multi-thread", "macros"] }
diff --git a/qml_plugin/src/lib.rs b/qml_plugin/src/lib.rs
index 12d0684..e4ad346 100644
--- a/qml_plugin/src/lib.rs
+++ b/qml_plugin/src/lib.rs
@@ -10,3 +10,4 @@ static RUNTIME: LazyLock<tokio::runtime::Runtime> = LazyLock::new(
);
mod launcher;
+mod web;
diff --git a/qml_plugin/src/web.rs b/qml_plugin/src/web.rs
new file mode 100644
index 0000000..49c81fb
--- /dev/null
+++ b/qml_plugin/src/web.rs
@@ -0,0 +1,2 @@
+pub mod duckduckgo;
+pub mod google;
diff --git a/qml_plugin/src/web/duckduckgo.rs b/qml_plugin/src/web/duckduckgo.rs
new file mode 100644
index 0000000..f80e4c8
--- /dev/null
+++ b/qml_plugin/src/web/duckduckgo.rs
@@ -0,0 +1,127 @@
+use std::ops::{Deref, DerefMut};
+
+use duckduckgo::{
+ browser::Browser,
+ params::{SafeSearch, SearchParams, Toggle},
+};
+use reqwest::Url;
+use serde::Deserialize;
+
+const DUCKDUCKGO: &str = "https://duckduckgo.com";
+
+pub struct DuckDuckGoContent {
+ title: String,
+ description_html: String,
+ preview_image: Option<Url>,
+}
+
+#[derive(Debug, Deserialize)]
+pub struct Infobox {
+ pub content: Vec<InfoboxContent>,
+}
+
+impl Deref for Infobox {
+ type Target = Vec<InfoboxContent>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.content
+ }
+}
+
+impl DerefMut for Infobox {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.content
+ }
+}
+
+#[derive(Debug, Deserialize)]
+pub struct InfoboxContent {
+ pub data_type: String,
+ pub label: String,
+ pub value: InfoboxValue,
+ pub wiki_order: String, // Kept as String since the JSON had "101" in quotes
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(untagged)]
+pub enum InfoboxValue {
+ Entity(EntityValue),
+ String(String),
+}
+
+#[derive(Debug, Deserialize)]
+pub struct EntityValue {
+ #[serde(rename = "entity-type")]
+ pub entity_type: String,
+ pub id: String,
+ #[serde(rename = "numeric-id")]
+ pub numeric_id: u32,
+}
+
+pub async fn query(input: &str) -> anyhow::Result<DuckDuckGoContent> {
+ let resp = Browser::new()
+ .get_api_response(
+ input,
+ Some(
+ &SearchParams::new()
+ .safe_search(SafeSearch::Off)
+ .full_urls(Toggle::On),
+ ),
+ )
+ .await?;
+
+ let infobox = match resp
+ .info_box
+ .map(serde_json::from_value::<Infobox>)
+ {
+ Some(Ok(o)) => Some(o),
+ _ => None,
+ };
+
+ let alt_desc = resp
+ .entity
+ .unwrap_or(
+ match infobox {
+ Some(i) => i
+ .iter()
+ .find(|i| i.data_type == "wd_description" || i.data_type == "official_website")
+ .map_or(
+ String::new(),
+ |i| {
+ if i.data_type == "official_website" {
+ i.label
+ .clone()
+ } else {
+ match i.value {
+ InfoboxValue::Entity(ref entity_value) => unreachable!(),
+ InfoboxValue::String(ref s) => s.to_string(),
+ }
+ }
+ },
+ ),
+ // TODO: find better way to get title from infobox
+ None => String::new(),
+ },
+ );
+
+ Ok(
+ DuckDuckGoContent {
+ title: resp
+ .heading
+ .unwrap_or(
+ resp.definition
+ .unwrap_or(alt_desc.clone()),
+ ),
+ description_html: resp
+ .answer
+ .unwrap_or(
+ resp.r#abstract
+ .unwrap_or(alt_desc),
+ ),
+ // TODO: try also Results[*].Icon.URL and RelatedTopics[*].Icon.URL
+ preview_image: resp
+ .image
+ .and_then(|i| Url::parse(&(DUCKDUCKGO.to_owned() + &i)).ok()),
+ },
+ )
+}
diff --git a/qml_plugin/src/web/google.rs b/qml_plugin/src/web/google.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/qml_plugin/src/web/google.rs