Skip to content

Instantly share code, notes, and snippets.

@terakilobyte
Last active November 21, 2015 21:37
Show Gist options
  • Select an option

  • Save terakilobyte/55b0c4df0f1679ff6536 to your computer and use it in GitHub Desktop.

Select an option

Save terakilobyte/55b0c4df0f1679ff6536 to your computer and use it in GitHub Desktop.
defmodule Rumbl.InfoSys.Wolfram do
import SweetXml
import Ecto.Query, only: [from: 2]
alias Rumbl.InfoSys.Result
# Starts this task as a separate evm process that won't block anything, and tells it to execute
# the fetch function
def start_link(query, query_ref, owner, limit) do
Task.start_link(__MODULE__, :fetch, [query, query_ref, owner, limit])
end
# takes in the query(query_str), the reference(query_ref) to the originators pid (process ID), the owner (hardcoded to "wolfram")
# and limit, the max results we'll take
# it pipes the query_str through the fetch_xml function, then into get_pod, then finally sends the results
# back to the query_ref
def fetch(query_str, query_ref, owner, _limit) do
query_str
|> fetch_xml()
|> get_pod
|> send_results(query_ref, owner)
end
# looks inside the xml to see if a Result or Definitions xml pod exists
# Return the first truthy condition
defp get_pod(xml) do
xpath(xml, ~x"//queryresult/pod[contains(@title, 'Result')]
/subpod/plaintext/text()")
||
xpath(xml, ~x"//queryresult/pod[contains(@title, 'Definitions')]
/subpod/plaintext/text()")
end
# sends back a blank result if the result was empty
defp send_results(nil, query_ref, owner) do
send(owner, {:results, query_ref, []})
end
# sends back a blank result if neither of the pods matched
defp send_results(false, query_ref, owner) do
send(owner, {:results, query_ref, [])
end
# send the results of a successful query back
defp send_results(answer, query_ref, owner) do
results = [%Result{backend: user(), score: 95, text: to_string(answer)}]
send(owner, {:results, query_ref, results})
end
# executes the http get verb to the wolframalpha api
defp fetch_xml(query_str) do
url = "http://api.wolframalpha.com/v2/query?" <>
"input=#{URI.encode(query_str)}&" <>
"appid=#{app_id()}&" <>
"format=plaintext"
HTTPoison.request!(:get, url, "", [], [recv_timeout: 30_000, timeout: 30_000]).body
end
# reads in the secret varaible to get the appid key for the api lookup
defp app_id, do: Application.get_env(:rumbl, :wolfram)[:app_id]
# gets the username "wolfram" from the database
defp user() do
Rumbl.Repo.one!(from u in Rumbl.User, where: u.username == "wolfram")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment