]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/imdb.rb
imdb plugin: search on the 'aka' sites, allowing the correct movie to be found even...
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / imdb.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: IMDB plugin for rbot
5 #
6 # Author:: Arnaud Cornet <arnaud.cornet@gmail.com>
7 # Copyright:: (C) 2005 Arnaud Cornet
8 # License:: MIT license
9 #
10 # Notes by Giuseppe Bilotta:
11 # TODO return more than one match (configurable)
12 # TODO why do we use CGI.unescapeHTML? shall we rely on the rbot methods?
13
14 require 'cgi'
15 require 'uri/common'
16
17 class Imdb
18   def initialize(bot)
19     @bot = bot
20   end
21
22   def search(rawstr)
23     str = URI.escape(rawstr) << ";site=aka"
24     resp = nil
25     begin
26       resp = @bot.httputil.get_response("http://us.imdb.com/find?q=#{str}",
27                                         :max_redir => -1)
28     rescue Exception => e
29       error e.message
30       warning e.backtrace.join("\n")
31       return nil
32     end
33
34     if resp.code == "200"
35       m = /<a href="(\/(?:title|name)\/(?:tt|nm)[0-9]+\/?)[^"]*"(?:[^>]*)>(?:[^<]*)<\/a>/.match(resp.body)
36       if m
37         url = m[1]
38         return url
39       end
40     elsif resp.code == "302"
41       return resp['location'].gsub(/http:\/\/us.imdb.com/, "").gsub(/\?.*/, "")
42     end
43     return nil
44   end
45
46   def info(rawstr)
47     sr = search(rawstr)
48     if !sr
49       debug "IMDB: search returned NIL"
50       return nil
51     end
52     type = sr.match(/^\/([^\/]+)\//)[1].downcase.intern rescue nil
53     case type
54     when :title
55       return info_title(sr)
56     when :name
57       return info_name(sr)
58     else
59       return "#{sr}"
60     end
61   end
62
63   def grab_info(info, body)
64     /<div class="info">\s+<h5>#{info}:<\/h5>\s+(.*?)<\/div>/mi.match(body)[1] rescue nil
65   end
66
67   def info_title(sr)
68     resp = nil
69     begin
70       resp = @bot.httputil.get_response('http://us.imdb.com' + sr,
71                                         :max_redir => -1)
72     rescue Exception => e
73       error e.message
74       warning e.backtrace.join("\n")
75       return nil
76     end
77
78     if resp.code == "200"
79       m = /<title>([^<]*)<\/title>/.match(resp.body)
80       return nil if !m
81       title = CGI.unescapeHTML(m[1])
82
83       m = /<b>([0-9.]+)\/10<\/b>\n?\r?\s+<small>\(<a href="ratings">([0-9,]+) votes?<\/a>\)<\/small>/.match(resp.body)
84       return nil if !m
85       score = m[1]
86       votes = m[2]
87
88       plot = nil
89       data = grab_info(/Plot (?:Outline|Summary)/, resp.body)
90       if data
91         plot = "Plot: #{data.ircify_html.gsub(/\s+more$/,'')}"
92       end
93
94       genre = Array.new
95       resp.body.scan(/<a href="\/Sections\/Genres\/[^\/]+\/">([^<]+)<\/a>/) do |gnr|
96         genre << gnr
97       end
98       info = "#{title} : http://us.imdb.com#{sr}\n"
99       info << "Ratings: #{score}/10 (#{votes} voters). Genre: #{genre.join('/')}\n"
100       info << plot if plot
101       return info
102     end
103     return nil
104   end
105
106   def info_name(sr)
107     resp = nil
108     begin
109       resp = @bot.httputil.get_response('http://us.imdb.com' + sr,
110                                         :max_redir => -1)
111     rescue Exception => e
112       error e.message
113       warning e.backtrace.join("\n")
114       return nil
115     end
116
117     if resp.code == "200"
118       m = /<title>([^<]*)<\/title>/.match(resp.body)
119       return nil if !m
120       name = CGI.unescapeHTML(m[1])
121
122       birth = nil
123       data = grab_info("Date of Birth", resp.body)
124       if data
125         birth = "Birth: #{data.ircify_html.gsub(/\s+more$/,'')}"
126       end
127
128       death = nil
129       data = grab_info("Date of Death", resp.body)
130       if data
131         death = "Death: #{data.ircify_html.gsub(/\s+more$/,'')}"
132       end
133
134       awards = nil
135       data = grab_info("Awards", resp.body)
136       if data
137         awards = "Awards: #{data.ircify_html.gsub(/\s+more$/,'')}"
138       end
139
140       info = "#{name} : http://us.imdb.com#{sr}\n"
141       info << [birth, death].compact.join('. ') << "\n"
142       info << awards if awards
143       return info
144
145     end
146     return nil
147   end
148 end
149
150 class ImdbPlugin < Plugin
151   def help(plugin, topic="")
152     "imdb <string> => search http://www.imdb.org for <string>"
153   end
154
155   def imdb(m, params)
156     what = params[:what].to_s
157     i = Imdb.new(@bot)
158     info = i.info(what)
159     if !info
160       m.reply "Nothing found for #{what}"
161       return nil
162     end
163     m.reply info
164   end
165 end
166
167 plugin = ImdbPlugin.new
168 plugin.map "imdb *what"
169