]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/oxford.rb
fix: TCPSocked.gethostbyname is deprecated
[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           unless alternative.empty?
55             url = @base_url + alternative.first[0]
56             title = alternative.first[1]
57           end
58         end
59
60         debug "search for alternative spelling result, returned title=#{title.inspect} url=#{url.inspect}"
61
62         if url and title
63           unless title.downcase == word.downcase
64             m.reply "did you mean: #{Bold}#{title.ircify_html}#{NormalText}?"
65           end
66           response = @bot.httputil.get(url, resp: true)
67           definition = parse_definition(response)
68         end
69       end
70     rescue => e
71       m.reply "error accessing lexico url -> #{url}"
72       error e
73       return
74     end
75
76     unless definition.empty?
77       m.reply definition.ircify_html, max_lines: @bot.config['oxford.max_lines']
78     else
79       m.reply "couldn't find a definition for #{word} on oxford dictionary"
80     end
81   end
82
83   private
84
85   def parse_definition(r)
86     r.xpath('//section[@class="gramb"]//text()').map(&:content).join(' ')
87   end
88 end
89
90 plugin = OxfordPlugin.new
91 plugin.map 'oxford *word', :action => 'oxford', :threaded => true
92