]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/bash.rb
bash plugin: check if the html is actually there
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / bash.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: bash.org quote retrieval
5 #
6 # Author:: Robin Kearney <robin@riviera.org.uk>
7 # Author:: cs
8 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
9 #
10 # Copyright:: (C) 2005 Robin Kearney
11 # Copyright:: (C) 2007 cs, Giuseppe Bilotta
12 #
13 # License:: public domain
14 #
15 # TODO improve output of quote
16 # TODO show more than one quote
17 # TODO allow selection of only quotes with vote > 0
18
19 require 'rexml/document'
20
21 class ::BashQuote
22   attr_accessor :num, :text, :irc_text, :vote
23
24   def initialize(num, text, vote)
25     @num = num.to_i
26     @text = text
27     @vote = vote
28     @irc_text = mk_irc_text
29   end
30
31   def url
32     "http://www.bash.org/?#{@num}"
33   end
34
35   private
36   def mk_irc_text
37     cur_nick = nil
38     last_nick = nil
39     text = String.new
40     @text.each_line { |l|
41       debug "line: #{l.inspect}"
42       cur_nick = l.match(/^\s*(&lt;.*?&gt;|\(.*?\)|.*?:)\s/)[1] rescue nil
43       debug "nick: #{cur_nick.inspect}; last: #{last_nick.inspect}"
44       if cur_nick and cur_nick == last_nick
45         text << l.sub(cur_nick,"")
46       else
47         last_nick = cur_nick.dup if cur_nick
48         text << l
49       end
50     }
51     debug text
52     # TODO: the gsub of br tags to | should be an ircify_html option
53     text.gsub(/(?:<br \/>\s*)+/, ' | ').ircify_html
54   end
55
56 end
57
58 class BashPlugin < Plugin
59
60   Config.register Config::EnumValue.new('bash.access',
61     :values => ['xml', 'html'], :default => 'html',
62     :desc => "Which method the bot should use to access bash.org quotes: xml files or standard webpages")
63
64   include REXML
65   def help(plugin, topic="")
66     "bash => print a random quote from bash.org, bash quote_id => print that quote id from bash.org, bash latest => print the latest quote from bash.org (currently broken, need to get josh@bash.org to fix the xml)"
67   end
68
69   def bash(m, params)
70     id = params[:id]
71     case @bot.config['bash.access'].intern
72     when :xml
73       xml_bash(m, id)
74     else
75       html_bash(m, :id => id)
76     end
77   end
78
79   def search(m, params)
80     esc = CGI.escape(params[:words].to_s)
81     html = @bot.httputil.get("http://bash.org/?search=#{esc}")
82     html_bash(m, :html => html)
83   end
84
85   def html_bash(m, opts={})
86     quotes = []
87
88     html = opts[:html]
89     if not html
90       id = opts[:id]
91       case id
92       when 'latest'
93         html = @bot.httputil.get("http://bash.org/?latest")
94       when nil
95         html = @bot.httputil.get("http://bash.org/?random", :cache => false)
96       else
97         html = @bot.httputil.get("http://bash.org/?" + id)
98       end
99     end
100
101     if not html
102       m.reply "unable to retrieve quotes"
103       return
104     end
105
106     html_quotes = html.split(/<p class="quote">/)
107     html_quotes.each { |htqt|
108       # debug htqt.inspect
109       if htqt.match(/<a href="\?(\d+)"[^>]*>.*?\((-?\d+)\).*?<p class="qt">(.*)<\/p>\s+(?:<\/td>.*)?\z/m)
110         num = $1
111         vote = $2
112         text = $3
113         quotes << BashQuote.new(num, text, vote)
114       end
115     }
116
117     case quotes.length
118     when 0
119       m.reply "no quotes found"
120       return
121     when 1
122       quote = quotes.first
123     else
124       # For the time being, we only echo the first quote, but in the future we
125       # may want to echo more than one for latest/random
126       quote = quotes.first
127     end
128     m.reply "#%d (%d): %s" % [quote.num, quote.vote, quote.irc_text]
129   end
130
131   def xml_bash(m, id=nil)
132     case id
133     when 'latest'
134       xml = @bot.httputil.get("http://bash.org/xml/?latest&num=1")
135     when nil
136       xml = @bot.httputil.get("http://bash.org/xml/?random&num=1", :cache => false)
137     else
138       xml = @bot.httputil.get("http://bash.org/xml/?" + id + "&num=1")
139     end 
140
141     unless xml
142       m.reply "bash.org rss parse failed"
143       return
144     end
145     doc = Document.new xml
146     unless doc
147       m.reply "bash.org rss parse failed"
148       return
149     end
150     doc.elements.each("*/item") {|e|
151       if(id != 0) 
152         reply = e.elements["title"].text.gsub(/QDB: /,"") + " " + e.elements["link"].text.gsub(/QDB: /,"") + "\n"
153         reply = reply + e.elements["description"].text.gsub(/\<br \/\>/, "\n")
154       else
155         reply = e.elements["title"].text.gsub(/QDB: /,"") + " " + e.elements["link"].text.gsub(/QDB: /,"") + "\n"
156         reply = reply + e.elements["description"].text.gsub(/\<br \/\>/, "\n")
157       end
158       m.reply reply
159     }
160   end
161 end
162
163 plugin = BashPlugin.new
164
165 plugin.map "bash search *words", :action => :search
166 plugin.map "bash [:id]"
167