From f964e2c3c2338434b57b6adf25dfbc346bb89b33 Mon Sep 17 00:00:00 2001 From: Lorenz Leitner Date: Sun, 10 Oct 2021 14:16:03 +0200 Subject: Basic (re)implementation of gonzobot wolfram alpha --- src/hooks/wa.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/hooks/wa.rs (limited to 'src/hooks/wa.rs') diff --git a/src/hooks/wa.rs b/src/hooks/wa.rs new file mode 100644 index 0000000..b6d4eff --- /dev/null +++ b/src/hooks/wa.rs @@ -0,0 +1,84 @@ +use anyhow::{bail, Context, Error, Result}; +use reqwest::{get, Url}; +use serde::{Deserialize, Serialize}; +use serde_json::Result as SerdeJsonResult; +use tracing::trace; + +#[derive(Serialize, Deserialize, Debug)] +struct WaResult { + queryresult: QueryResult, +} + +#[derive(Serialize, Deserialize, Debug)] +struct QueryResult { + pods: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Pod { + title: String, + id: String, + subpods: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct SubPod { + title: String, + plaintext: String, +} + +fn parse_json(str_data: &str) -> SerdeJsonResult { + let w: WaResult = serde_json::from_str(str_data)?; + Ok(w) +} + +#[tracing::instrument] +async fn wa_query(query_str: &str) -> Result { + let app_id = "XXX"; // TODO: Get from env + let api_url = format!( + "http://api.wolframalpha.com/v2/query?input={}&appid={}&output=json", + query_str, app_id + ); + + let body = get(Url::parse(&api_url).context("Failed to parse url")?) + .await + .context("Failed to make request")? + .text() + .await + .context("failed to get request response text")?; + + let full_wa_res = parse_json(&body)?; + trace!("got full_wa_res: {:?}", full_wa_res); + + let pod_plaintexts = full_wa_res.queryresult.pods + .iter() + .filter(|it| it.id.to_lowercase() != "input") + .map(|pod| { + let subpod_texts = pod + .subpods + .iter() + .map(|subpod| subpod.plaintext.clone()) + .collect::>() + .join(", "); + + format!("{}: {}", &pod.title, subpod_texts) + }) + .collect::>() + .join(" - "); + + Ok(pod_plaintexts) +} + +#[cfg(test)] +mod tests { + + use super::wa_query; + use anyhow::{Error, Result}; + + #[tokio::test] + // async fn test_query_result_json_parsing() -> Result<(), Error> { + async fn test_query_result_json_parsing() { + let res = wa_query("weather graz").await.unwrap(); + assert_eq!(res, "asdf"); + } +} -- cgit v1.2.3