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