/lib/ddg.coffee
CoffeeScript | 66 lines | 59 code | 5 blank | 2 comment | 7 complexity | 2f09751d012bb95abae542b0b51897ea MD5 | raw file
- {log:logger, round2, html2txt, inspect, timeout} = require './util'
- {parse:parseURL} = require 'url'
- {request} = require '../lib/request'
- # Busca no DuckDuckGo
- # http://api.duckduckgo.com/?q=<query>&format=json&pretty=1
- module.exports = ddg = (query, langs, callback=(->))->
- logger "DDG Search for \"#{query}\", Open API..."
- encQuery = encodeURIComponent query
- url = 'http://api.duckduckgo.com/?format=json&q=' + encQuery
- request(url, 'Accept-Language': ddg.mkAcceptLang langs)
- .then (res)->
- try
- logger.debug 'DDG response data', data:res.data
- data = JSON.parse res.data
- result = data.Results?[0] or {}
- resultUrl = data.DefinitionURL or data.AbstractURL or result.FirstURL
- resultTxt = data.Definition or data.AbstractText or result.Text
- if resultUrl and resultTxt
- callback null, url: resultUrl, content: resultTxt
- else
- callback new Error 'no result.'
- catch err
- logger.error 'DDG data parser fail', err
- callback err
- .catch (err)->
- callback err
- ddg.mkAcceptLang = (langs...)->
- langs = langs[0] if langs[0].constructor is Array
- qval = 1.1
- ( "#{lang};q=#{round2 qval-=.1}" for lang in langs ).join ','
- ddg.siteAPI = (query, langs, callback=(->))->
- logger "DDG Search for \"#{query}\", Site API..."
- lang = ddg.mkQueryLang langs[0]
- encQuery = encodeURIComponent query
- url = "https://duckduckgo.com/d.js?q=#{encQuery}&l=#{lang}&norw=1"
- headers = {
- 'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:46.0) Gecko/20150101 Firefox/46.0'
- 'Accept-Language': ddg.mkAcceptLang langs
- 'Accept-Encoding': 'gzip'
- 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
- 'Connection': 'Keep-Alive'
- }
- request(url, headers)
- .then (res)->
- if 0 <= res.data.indexOf '"c":"http://www.google.com/search?q="+q'
- throw Error 'no result. (blocked)'
- unless match = res.data.split(/\s+/).join(' ').match /nrn\('d',(\[\{.*\}\])\)/
- throw Error 'DDG Site API Changed? (nrn)'
- result = JSON.parse(match[1])[0]
- unless result.a? and result.t? and result.c?.match /^https?:/
- throw Error "DDG Site API Changed? (#{inspect result})"
- if result.c.match /google.com\/search\?.*q=/
- throw Error 'no result.'
- timeout 0, -> callback null, title: html2txt(result.t), url: result.c, content: html2txt(result.a)
- .catch (err)-> timeout 0, -> callback err
- ddg.mkQueryLang = (lang)->
- lang = lang.toLowerCase().split '-'
- if lang.length is 2
- lang[1] + '-' + lang[0]
- else
- lang[0]