]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/oxford.rb
plugin(oxford): fix result handling, closes #37
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / oxford.rb
1 # encoding: UTF-8
2 #-- vim:sw=2:et
3 #++
4 #
5 # :title: Oxford Dictionary lookup plugin for rbot
6 #
7 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
8 # Copyright:: (C) 2006-2007 Giuseppe Bilotta
9 # License:: GPL v2
10 #
11 require 'cgi'
12 require 'uri'
13
14 class OxfordPlugin < Plugin
15   Config.register Config::IntegerValue.new(
16     'oxford.max_lines',
17     :default => 1,
18     :desc => 'The number of lines to respond with.')
19
20   def initialize
21     super
22     @base_url = "https://www.lexico.com"
23   end
24
25   def help(plugin, topic="")
26     'oxford <word>: check for <word> on the lexico english dictionary (powered by oxford english dictionary).'
27   end
28
29   def oxford(m, params)
30     word = params[:word].join(' ')
31
32     url = "#{@base_url}/definition/#{URI::encode word}"
33
34     begin
35       debug "searching definition for #{word.inspect}"
36
37       response = @bot.httputil.get(url, resp: true)
38       definition = parse_definition(response)
39
40       # try to find alternative word (different spelling, typos, etc.)
41       if definition.empty?
42         debug "search for alternative spelling result"
43         url = title = nil
44         exact_matches = response.xpath('//div[@class="no-exact-matches"]//ul/li/a')
45         if not exact_matches.empty? and not exact_matches.first['href'].empty?
46           url = @base_url + exact_matches.first['href']
47           title = exact_matches.first.content
48         else
49           debug 'use web-service to find alternative result'
50           # alternatively attempt to use their webservice (json-p) instead
51           url = "#{@base_url}/search/dataset.js?dataset=noad&dictionary=en&query=#{CGI.escape word}"
52           response = @bot.httputil.get(url, headers: {'X-Requested-With': 'XMLHttpRequest'})
53           alternative = response.gsub(/\\/, '').scan(/href="([^"]+)">([^<]+)</)
54           url = @base_url + alternative.first[0]
55           title = alternative.first[1]
56         end
57
58         debug "search for alternative spelling result, returned title=#{title.inspect} url=#{url.inspect}"
59
60         if url and title
61           unless title.downcase == word.downcase
62             m.reply "did you mean: #{Bold}#{title.ircify_html}#{NormalText}?"
63           end
64           response = @bot.httputil.get(url, resp: true)
65           definition = parse_definition(response)
66         end
67       end
68     rescue => e
69       m.reply "error accessing lexico url -> #{url}"
70       error e
71       return
72     end
73
74     unless definition.empty?
75       m.reply definition.ircify_html, max_lines: @bot.config['oxford.max_lines']
76     else
77       m.reply "couldn't find a definition for #{word} on oxford dictionary"
78     end
79   end
80
81   private
82
83   def parse_definition(r)
84     r.xpath('//section[@class="gramb"]//text()').map(&:content).join(' ')
85   end
86 end
87
88 plugin = OxfordPlugin.new
89 plugin.map 'oxford *word', :action => 'oxford', :threaded => true
90