module DuckGo

Constants

VERSION

Public Instance Methods

extract_common(data) click to toggle source

Extract common info

# File lib/duckgo.rb, line 114
def extract_common(data)
  output = {
    "Heading" => data["Heading"],
    "Entity" => data["Entity"],
    "Type" => "",
    "Description" => data["AbstractText"],
    "Further Reading" => data["AbstractURL"],
    "Related" => []
  }
  case data["Type"]
    when "A"
      type = "Article"
    when "C"
      type = "Category"
    when "D"
      type = "Disambiguation"
    when "E"
      type = "Exclusive"
    when "N"
      type = "Name"
    else
      type = "Nothing or unknown"
  end
  output["Type"] = type
  data["RelatedTopics"].each do |topic|
    unless topic["Text"].nil?
      output["Related"] << topic["Text"]
    end
  end
  output.delete_if do |key, value|
     value.empty?
  end
  return output
end
extract_extras(data, extras_data) click to toggle source

Extract extra info based on an input extras_data

# File lib/duckgo.rb, line 93
def extract_extras(data, extras_data)
  extras = {}
  if extras_data["Infobox"]
    extras["Infobox"] = extract_infobox(data)
  end
  if extras_data["Results"]
    extras["Results"] = extract_results(data)
  end
  if extras_data["Answer"]
    extras["Answer"] = extras_data["Answer"]
  end
  if extras_data["Definition"]
    extras["Definition"] = extras_data["Definition"]
  end
  if extras_data["Bang Redirect"]
    extras["Bang Redirect"] = extras_data["Bang Redirect"]
  end
  return extras
end
extract_infobox(data) click to toggle source

Extract infobox from hash Official example : api.duckduckgo.com/?q=valley+forge+national+park&format=json&pretty=1

# File lib/duckgo.rb, line 160
def extract_infobox(data)
  output = {}
  tsums = data["Infobox"]["content"]
  tsums.each do |section|
    output[ section["label"] ] = section["value"]
  end
  return output
end
extract_results(data) click to toggle source

Extract results from hash

# File lib/duckgo.rb, line 150
def extract_results(data)
  output = {}
  data["Results"].each do |result|
    output[result["Text"]] = result["FirstURL"]
  end
  return output
end
find_extras(data) click to toggle source

Return data describing the extra info fields

# File lib/duckgo.rb, line 61
def find_extras(data)
  extras = {}
  unless data["Infobox"].empty?
    extras["Infobox"] = {
      "Total" => data["Infobox"]["content"].length
    }
  end
  unless data["Results"].empty?
    extras["Results"] = {
      "Total" => data["Results"].length
    }
  end
  unless data["Answer"].empty?
    extras["Answer"] = {
      "Answer" => data["Answer"],
      "Type" => data["AnswerType"]
    }
  end
  unless data["Definition"].empty?
    extras["Definition"] = {
      "Definition" => data["Definition"],
      "Source" => data["DefinitionSource"],
      "URL" => data["DefinitionURL"]
    }
  end
  unless data["Redirect"].empty?
    extras["Bang Redirect"] = data["Redirect"]
  end
  return extras
end
get(params, path="/", domain="https://api.duckduckgo.com") click to toggle source

Do a raw api request based on paramaters

# File lib/duckgo.rb, line 11
def get(params, path="/", domain="https://api.duckduckgo.com") # domain can also just be plain duckduckgo.com
  if params.nil?
    endpoint = "#{domain}/#{path}"
  else
    endpoint = "#{domain}/#{path}?#{URI.encode_www_form(params)}"
  end
  body = open(endpoint).read
  return body
end
get_data(keywords, format=0, skip_disambig=1, no_redirect=1, parse=true) click to toggle source

Dump the useful data straight from DuckDuckGo's API If format is XML, return it as a string even if parse is true

# File lib/duckgo.rb, line 23
def get_data(keywords, format=0, skip_disambig=1, no_redirect=1, parse=true)
  params = {
    "q" => keywords,
    "format" => ["json", "xml"][format],
    "skip_disambig" => [0, 1][skip_disambig],
    "no_redirect" => [0, 1][no_redirect]
  }
  keywords.split(" ").each do |word|
    if word.start_with?("!")
      puts "Warning: '!x word' syntax results in a bang redirect"
    end
  end
  body = get(params)
  if parse
    if format == 0
      return JSON.parse(body)
    else
      return body
    end
  else
    return body
  end
end
get_favicon(page) click to toggle source

Get a website/page's favicon through duckduckgo's proxy

# File lib/duckgo.rb, line 48
def get_favicon(page)
  favicon = get(nil, "/i/#{page}.ico")
  require 'digest'
  generic_resp = "ad4b0f606e0f8465bc4c4c170b37e1a3"
  if Digest::MD5.hexdigest(favicon) == generic_resp
    puts "Warning: response is 200-OK, but content is a generic response\nThis probably means the favicon is unreachable"
    return nil
  else
    return favicon
  end
end
handle(keywords) click to toggle source

Handle a common search automatically

# File lib/duckgo.rb, line 170
def handle(keywords)
  data = get_data(keywords)
  common = extract_common(data)
  extras_data = find_extras(data)
  extras = extract_extras(data, extras_data)
  result = common.merge(extras)
  puts result.to_yaml
end