]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/dict.rb
6edff065c8b26a7de9428c38a02ae6d5fd9bba51
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / dict.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Dictionary lookup plugin for rbot
5 #
6 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
7 # Copyright:: (C) 2006-2007 Giuseppe Bilotta
8 # License:: GPL v2
9 #
10 # Provides a link to the definition of a word in one of the supported
11 # dictionaries. Currently available are
12 #   * the Oxford dictionary for (British) English
13 #   * the De Mauro/Paravia dictionary for Italian
14 #   * the Chambers dictionary for English (accepts both US and UK)
15 #
16 # Other plugins can use this one to check if a given word is valid in italian
17 # or english by using the is_italian?/is_british?/is_english? methods
18 #
19 # TODO: cache results and reuse them if get_cached returns a cache copy
20
21 DEMAURO_LEMMA = /<anchor>(.*?)(?: - (.*?))<go href="lemma.php\?ID=(\d+)"\/><\/anchor>/
22 CHAMBERS_LEMMA = /<p><span class="hwd">(.*?)<\/span> <span class="psa">(.*?)<\/span>(.*?)<\/p>/
23
24 class DictPlugin < Plugin
25   Config.register Config::IntegerValue.new('dict.hits',
26     :default => 3,
27     :desc => "Number of hits to return from a dictionary lookup")
28   Config.register Config::IntegerValue.new('dict.first_par',
29     :default => 0,
30     :desc => "When set to n > 0, the bot will return the first paragraph from the first n dictionary hits")
31
32   def initialize
33     super
34     @dmurl = "http://www.demauroparavia.it/"
35     @dmwapurl = "http://wap.demauroparavia.it/index.php?lemma=%s"
36     @dmwaplemma = "http://wap.demauroparavia.it/lemma.php?ID=%s"
37     @oxurl = "http://www.askoxford.com/concise_oed/%s"
38     @chambersurl = "http://www.chambersharrap.co.uk/chambers/features/chref/chref.py/main?query=%s&title=21st"
39   end
40
41
42   def help(plugin, topic="")
43     case topic
44     when "demauro"
45       return "demauro <word> => provides a link to the definition of <word> from the De Mauro/Paravia dictionary"
46     when "oxford"
47       return "oxford <word> => provides a link to the definition of <word> (it can also be an expression) from the Concise Oxford dictionary"
48     when "chambers"
49       return "chambers <word> => provides a link to the definition of <word> (it can also be an expression) from the Chambers 21st Century Dictionary"
50     end
51     return "<dictionary> <word>: check for <word> on <dictionary> where <dictionary> can be one of: demauro, oxford, chambers"
52   end
53
54   def demauro(m, params)
55     justcheck = params[:justcheck]
56
57     word = params[:word].downcase
58     url = @dmwapurl % CGI.escape(word)
59     xml = nil
60     info = @bot.httputil.get_response(url) rescue nil
61     xml = info.body if info
62     if xml.nil?
63       info = info ? " (#{info.code} - #{info.message})" : ""
64       return false if justcheck
65       m.reply "An error occurred while looking for #{word}#{info}"
66       return
67     end
68     if xml=~ /Non ho trovato occorrenze per/
69       return false if justcheck
70       m.reply "Nothing found for #{word}"
71       return
72     end
73     entries = xml.scan(DEMAURO_LEMMA)
74     text = word
75     urls = []
76     if not entries.transpose.first.grep(/\b#{word}\b/)
77       return false if justcheck
78       text += " not found. Similar words"
79     end
80     return true if justcheck
81     text += ": "
82     n = 0
83     hits = @bot.config['dict.hits']
84     text += entries[0...hits].map { |ar|
85       n += 1
86       urls << @dmwaplemma % ar[2]
87       "#{n}. #{Bold}#{ar[0]}#{Bold} - #{ar[1].gsub(/<\/?em>/,'')}: #{@dmurl}#{ar[2]}"
88     }.join(" | ")
89     m.reply text
90
91     first_pars = @bot.config['dict.first_par']
92
93     return unless first_pars > 0
94
95     Utils.get_first_pars urls, first_pars, :message => m,
96       :strip => /^.+?\s+-\s+/
97
98   end
99
100   def is_italian?(word)
101     return demauro(nil, :word => word, :justcheck => true)
102   end
103
104
105   def oxford(m, params)
106     justcheck = params[:justcheck]
107
108     word = params[:word].join
109     [word, word + "_1"].each { |check|
110       url = @oxurl % CGI.escape(check)
111       if params[:british]
112         url << "?view=uk"
113       end
114       h = @bot.httputil.get(url, :max_redir => 5)
115       if h and h.match(%r!<h2>#{word}(?:<sup>1</sup>)?</h2>!)
116         m.reply("#{word} : #{url}") unless justcheck
117         defn = $'
118         m.reply("#{Bold}%s#{Bold}: %s" % [word, defn.ircify_html(:nbsp => :space)], :overlong => :truncate)
119         return true
120       end
121     }
122     return false if justcheck
123     m.reply "#{word} not found"
124   end
125
126   def is_british?(word)
127     return oxford(nil, :word => word, :justcheck => true, :british => true)
128   end
129
130
131   def chambers(m, params)
132     justcheck = params[:justcheck]
133
134     word = params[:word].to_s.downcase
135     url = @chambersurl % CGI.escape(word)
136     xml = nil
137     info = @bot.httputil.get_response(url) rescue nil
138     xml = info.body if info
139     case xml
140     when nil
141       info = info ? " (#{info.code} - #{info.message})" : ""
142       return false if justcheck
143       m.reply "An error occurred while looking for #{word}#{info}"
144       return
145     when /Sorry, no entries for <b>.*?<\/b> were found./
146       return false if justcheck
147       m.reply "Nothing found for #{word}"
148       return
149     when /No exact matches for <b>.*?<\/b>, but the following may be helpful./
150       return false if justcheck
151       m.reply "Nothing found for #{word}, but see #{url} for possible suggestions"
152       return
153     end
154     # Else, we have a hit
155     return true if justcheck
156     m.reply "#{word}: #{url}"
157     entries = xml.scan(CHAMBERS_LEMMA)
158     hits = @bot.config['dict.hits']
159     entries[0...hits].map { |ar|
160       m.reply(("#{Bold}%s#{Bold} #{Underline}%s#{Underline}%s" % ar).ircify_html, :overlong => :truncate)
161     }
162   end
163
164   def is_english?(word)
165     return chambers(nil, :word => word, :justcheck => true)
166   end
167
168 end
169
170 plugin = DictPlugin.new
171 plugin.map 'demauro :word', :action => 'demauro', :thread => true
172 plugin.map 'oxford *word', :action => 'oxford', :thread => true
173 plugin.map 'chambers *word', :action => 'chambers', :thread => true
174