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