PageRenderTime 25ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ddg.coffee

https://gitlab.com/raulhc/telegram-bot
CoffeeScript | 66 lines | 59 code | 5 blank | 2 comment | 7 complexity | 2f09751d012bb95abae542b0b51897ea MD5 | raw file
  1. {log:logger, round2, html2txt, inspect, timeout} = require './util'
  2. {parse:parseURL} = require 'url'
  3. {request} = require '../lib/request'
  4. # Busca no DuckDuckGo
  5. # http://api.duckduckgo.com/?q=<query>&format=json&pretty=1
  6. module.exports = ddg = (query, langs, callback=(->))->
  7. logger "DDG Search for \"#{query}\", Open API..."
  8. encQuery = encodeURIComponent query
  9. url = 'http://api.duckduckgo.com/?format=json&q=' + encQuery
  10. request(url, 'Accept-Language': ddg.mkAcceptLang langs)
  11. .then (res)->
  12. try
  13. logger.debug 'DDG response data', data:res.data
  14. data = JSON.parse res.data
  15. result = data.Results?[0] or {}
  16. resultUrl = data.DefinitionURL or data.AbstractURL or result.FirstURL
  17. resultTxt = data.Definition or data.AbstractText or result.Text
  18. if resultUrl and resultTxt
  19. callback null, url: resultUrl, content: resultTxt
  20. else
  21. callback new Error 'no result.'
  22. catch err
  23. logger.error 'DDG data parser fail', err
  24. callback err
  25. .catch (err)->
  26. callback err
  27. ddg.mkAcceptLang = (langs...)->
  28. langs = langs[0] if langs[0].constructor is Array
  29. qval = 1.1
  30. ( "#{lang};q=#{round2 qval-=.1}" for lang in langs ).join ','
  31. ddg.siteAPI = (query, langs, callback=(->))->
  32. logger "DDG Search for \"#{query}\", Site API..."
  33. lang = ddg.mkQueryLang langs[0]
  34. encQuery = encodeURIComponent query
  35. url = "https://duckduckgo.com/d.js?q=#{encQuery}&l=#{lang}&norw=1"
  36. headers = {
  37. 'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:46.0) Gecko/20150101 Firefox/46.0'
  38. 'Accept-Language': ddg.mkAcceptLang langs
  39. 'Accept-Encoding': 'gzip'
  40. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
  41. 'Connection': 'Keep-Alive'
  42. }
  43. request(url, headers)
  44. .then (res)->
  45. if 0 <= res.data.indexOf '"c":"http://www.google.com/search?q="+q'
  46. throw Error 'no result. (blocked)'
  47. unless match = res.data.split(/\s+/).join(' ').match /nrn\('d',(\[\{.*\}\])\)/
  48. throw Error 'DDG Site API Changed? (nrn)'
  49. result = JSON.parse(match[1])[0]
  50. unless result.a? and result.t? and result.c?.match /^https?:/
  51. throw Error "DDG Site API Changed? (#{inspect result})"
  52. if result.c.match /google.com\/search\?.*q=/
  53. throw Error 'no result.'
  54. timeout 0, -> callback null, title: html2txt(result.t), url: result.c, content: html2txt(result.a)
  55. .catch (err)-> timeout 0, -> callback err
  56. ddg.mkQueryLang = (lang)->
  57. lang = lang.toLowerCase().split '-'
  58. if lang.length is 2
  59. lang[1] + '-' + lang[0]
  60. else
  61. lang[0]