/* * Copyright (C) 2021 Arsen Musayelyan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // wolframalpha is a Trident plugin that queries the WolframAlpha API and says the result package wolframalpha import ( "encoding/xml" "fmt" "log" "net/http" "net/url" "strings" "trident" ) // Result stores the result of the WolframAlpha query type Result struct { Pods []Pod `xml:"pod"` } // Pod stores pod tags from result type Pod struct { XMLName xml.Name `xml:"pod"` ID string `xml:"id,attr"` SubPods []SubPod `xml:"subpod"` } // SubPod stores subpod tags from pod type SubPod struct { XMLName xml.Name `xml:"subpod,omitempty"` Plaintext *Plaintext `xml:"plaintext,omitempty"` } // Plaintext stores plaintext tags from subpod type Plaintext struct { XMLName xml.Name `xml:"plaintext"` String string `xml:",chardata"` } func RunPlugin(query string, data map[string]interface{}) { // Escape query for inclusion in URL escapedQuery := url.QueryEscape(query) // Query WolframAlpha API res, err := http.Get(fmt.Sprintf("https://api.wolframalpha.com/v2/query?input=%s&appid=%s", escapedQuery, data["appid"].(string))) if err != nil { log.Fatalln(err) } // Close response body at end of function defer res.Body.Close() // Create new nil struct to store query results var resStruct Result // Create new XML decoder reading from API response body dec := xml.NewDecoder(res.Body) // Decode contents of response body into struct err = dec.Decode(&resStruct) if err != nil { log.Fatalln(err) } // Create string builder to combine results all := strings.Builder{} for _, pod := range resStruct.Pods { switch pod.ID { case "Result", "RealSolution", "Solution": // If pod ID is one of the above cases, write it to builder all.WriteString(pod.ID) for _, subpod := range pod.SubPods { // Write string from subpod plaintext tag to builder all.WriteString(subpod.Plaintext.String) } } } // Use voice to say built string trident.Say(all.String()) }