lastfm plugin: overlong artisti descriptions are truncated; artist events can be...
[rbot] / data / rbot / plugins / urban.rb
1 require 'uri'
2
3 class UrbanPlugin < Plugin
4
5   def help( plugin, topic="")
6     "urban [word] [n]: give the [n]th definition of [word] from urbandictionary.com. urbanday: give the word-of-the-day at urban"
7   end
8
9   def urban(m, params)
10     words = params[:words].to_s
11     n = params[:n].nil? ? 1 : params[:n].to_i rescue 1
12
13     if words.empty?
14       resp = @bot.httputil.head('http://www.urbandictionary.com/random.php',
15                                :max_redir => -1)
16       if resp.code == "302" && (loc = resp['location'])
17         words = URI.unescape(loc.match(/define.php\?term=(.*)$/)[1]) rescue nil
18       end
19     end
20     # we give a very high 'skip' because this will allow us to get the number of definitions by retrieving the previous definition
21     uri = "http://www.urbanwap.com/search.php?term=#{URI.escape words}&skip=65536"
22     page = @bot.httputil.get(uri)
23     if page.nil?
24       m.reply "Couldn't retrieve an urban dictionary definition of #{words}"
25       return
26     end
27     if page =~ / is undefined<\/card><\/wml>/
28       m.reply "There is no urban dictionary definition of #{words}"
29       return
30     end
31     if page =~ /&amp;skip=(\d+)">prev<\/a>/
32       numdefs = $1.to_i + 1
33     else
34       numdefs = 1
35     end
36     n = numdefs + n + 1 if n < 0
37     if n > numdefs
38       m.reply "Urban dictionary only has #{numdefs} definitions for '#{words}'"
39       n = numdefs
40     end
41     if n < numdefs
42       uri = "http://www.urbanwap.com/search.php?term=#{URI.escape words}&skip=#{n-1}"
43       page = @bot.httputil.get(uri)
44       if page.nil?
45         case n % 10
46         when 1
47           ord = 'st'
48         when 2
49           ord = 'nd'
50         when 3
51           ord = 'rd'
52         else
53           ord = 'th'
54         end
55         m.reply "Couldn't retrieve the #{n}#{ord} urban dictionary definition of #{words}"
56         return
57       end
58     end
59     m.reply "#{get_def(page)} (#{n}/#{numdefs})"
60   end
61
62   def get_def(text)
63     # Start by removing the prev/home/next links
64     t = text.gsub(/(?:<a href[^>]*>prev<\/a> )?<a href[^>]*>home<\/a>(?: <a href[^>]*>next<\/a>)?/,'')
65     # Close up paragraphs
66     t.gsub!(/<\/?p>/, ' ')
67     t.gsub!("\n", ' ')
68     # Reverse headings
69     t.gsub!(/<\/?b>/,"#{Reverse}")
70     # Enbolden links
71     t.gsub!(/<\/?a(?: [^>]*)?>/,"#{Bold}")
72     # Reverse examples
73     t.gsub!(/<\/?(?:i|em)>/,"#{Underline}")
74     # Clear anything else
75     t.gsub!(/<.*?>/, '')
76
77     Utils.decode_html_entities t.strip
78   end
79
80   def uotd(m, params)
81     home = @bot.httputil.get("http://www.urbanwap.com/")
82     if home.nil?
83       m.reply "Couldn't get the urban dictionary word of the day"
84       return
85     end
86     home.match(/Word of the Day: <a href="(.*?)">.*?<\/a>/)
87     wotd = $1
88     debug "Urban word of the day: #{wotd}"
89     page = @bot.httputil.get(wotd)
90     if page.nil?
91       m.reply "Couldn't get the urban dictionary word of the day"
92     else
93       m.reply get_def(page)
94     end
95   end
96 end
97
98 plugin = UrbanPlugin.new
99 plugin.map "urban *words :n", :requirements => { :n => /^-?\d+$/ }, :action => 'urban'
100 plugin.map "urban [*words]", :action => 'urban'
101 plugin.map "urbanday", :action => 'uotd'
102