X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=data%2Frbot%2Fplugins%2Fimdb.rb;h=96501659d70f96d7d8d19eeb905505bc91c5ce31;hb=d13c4f4e8d1d6a9b126540ba60dd541048b23772;hp=699e54dd922a36e3e47a96ba598f4e5dd9ab2620;hpb=e188fce6cd7d2f7236ee2b5fbd2b2bc53cb9136b;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/data/rbot/plugins/imdb.rb b/data/rbot/plugins/imdb.rb index 699e54dd..96501659 100644 --- a/data/rbot/plugins/imdb.rb +++ b/data/rbot/plugins/imdb.rb @@ -4,11 +4,12 @@ # :title: IMDB plugin for rbot # # Author:: Arnaud Cornet +# Author:: Giuseppe "Oblomov" Bilotta +# # Copyright:: (C) 2005 Arnaud Cornet -# License:: MIT license +# Copyright:: (C) 2007 Giuseppe Bilotta # -# Notes by Giuseppe Bilotta: -# TODO return more than one match (configurable) +# License:: MIT license require 'uri/common' @@ -17,13 +18,15 @@ class Imdb TITLE_OR_NAME_MATCH = /]*)>([^<]*)<\/a>/ TITLE_MATCH = /]*)>([^<]*)<\/a>/ NAME_MATCH = /]*)>([^<]*)<\/a>/ + FINAL_ARTICLE_MATCH = /, ([A-Z]\S{0,2})$/ def initialize(bot) @bot = bot end def search(rawstr) - str = URI.escape(rawstr) << ";site=aka" + str = URI.escape(rawstr) + str << ";site=aka" if @bot.config['imdb.aka'] return do_search(str) end @@ -39,43 +42,68 @@ class Imdb end if resp.code == "200" - m = TITLE_OR_NAME_MATCH.match(resp.body) - if m - url = m[1] - return url + m = [] + m << TITLE_OR_NAME_MATCH.match(resp.body) if @bot.config['imdb.popular'] + if resp.body.match(/\(Exact Matches\)<\/b>/) and @bot.config['imdb.exact'] + m << TITLE_OR_NAME_MATCH.match($') + end + m.compact! + unless m.empty? + return m.map { |mm| + mm[1] + }.uniq end elsif resp.code == "302" + debug "automatic redirection" new_loc = resp['location'].gsub(IMDB, "") if new_loc.match(/\/find\?q=(.*)/) return do_search($1) else - return new_loc.gsub(/\?.*/, "") + return [new_loc.gsub(/\?.*/, "")] end end return nil end def info(rawstr) - sr = search(rawstr) - if !sr + urls = search(rawstr) + debug urls + if urls.nil_or_empty? 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 + results = [] + urls.each { |sr| + type = sr.match(/^\/([^\/]+)\//)[1].downcase.intern rescue nil + case type + when :title + results << info_title(sr) + when :name + results << info_name(sr) + else + results << "#{sr}" + end + } + return results end def grab_info(info, body) /
\s+
#{info}:<\/h5>\s+(.*?)<\/div>/mi.match(body)[1] rescue nil end + def fix_article(org_tit) + title = org_tit.dup + if @bot.config['imdb.fix_article'] and title.gsub!(FINAL_ARTICLE_MATCH, '') + art = $1.dup + debug art.inspect + if art[-1,1].match(/[a-z]/) + art << " " + end + return art + title + end + return title + end + def info_title(sr) resp = nil begin @@ -86,29 +114,51 @@ class Imdb return nil end + info = [] + if resp.code == "200" m = /([^<]*)<\/title>/.match(resp.body) return nil if !m - title = Utils.decode_html_entities(m[1]) + title_date = m[1] + pre_title, date, extra = title_date.scan(/^(.*)\((\d\d\d\d(?:[IV]+)?)\)\s*(.+)?$/).first + pre_title.strip! + title = fix_article(pre_title) - 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] + dir = nil + data = grab_info(/Directors?/, resp.body) + if data + dir = data.scan(NAME_MATCH).map { |url, name| + name + }.join(', ') + end - plot = nil - data = grab_info(/Plot (?:Outline|Summary)/, resp.body) + country = nil + data = grab_info(/Country/, resp.body) if data - plot = "Plot: #{data.ircify_html.gsub(/\s+more$/,'')}" + country = data.ircify_html + end + + info << [title, "(#{country}, #{date})", extra, dir ? "[#{dir}]" : nil, ": http://us.imdb.com#{sr}"].compact.join(" ") + + ratings = "no votes" + m = /<b>([0-9.]+)\/10<\/b>\n?\r?\s+<small>\(<a href="ratings">([0-9,]+) votes?<\/a>\)<\/small>/.match(resp.body) + if m + ratings = "#{m[1]}/10 (#{m[2]} voters)" 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 + + plot = nil + data = grab_info(/Plot (?:Outline|Summary)/, resp.body) + if data + plot = "Plot: " + data.ircify_html.gsub(/\s+more$/,'') + end + + info << ["Ratings: " << ratings, "Genre: " << genre.join('/') , plot].compact.join(". ") + return info end return nil @@ -124,10 +174,14 @@ class Imdb return nil end + info = [] + if resp.code == "200" m = /<title>([^<]*)<\/title>/.match(resp.body) return nil if !m - name = Utils.decode_html_entities(m[1]) + name = m[1] + + info << "#{name} : http://us.imdb.com#{sr}" birth = nil data = grab_info("Date of Birth", resp.body) @@ -141,6 +195,8 @@ class Imdb death = "Death: #{data.ircify_html.gsub(/\s+more$/,'')}" end + info << [birth, death].compact.join('. ') if birth or death + movies = {} filmorate = nil @@ -152,23 +208,33 @@ class Imdb 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) + next unless what movies[what] = str.scan(TITLE_MATCH)[0..2].map { |url, tit| - Utils.decode_html_entities(tit) + fix_article(tit) } } end - debug movies.inspect - info = "#{name} : http://us.imdb.com#{sr}\n" - info << [birth, death].compact.join('. ') << "\n" + preferred = ['Actor', 'Director'] + if resp.body.match(/Jump to filmography as: (.*?)<\/div>/) + txt = $1 + preferred = txt.scan(/<a[^>]+>([^<]+)<\/a>/)[0..2].map { |pref| + pref.first + } + end + unless movies.empty? - info << "Top Movies:: " + all_keys = movies.keys.sort + debug all_keys.inspect + keys = [] + preferred.each { |key| + keys << key if all_keys.include? key + } + keys = all_keys if keys.empty? ar = [] - movies.keys.sort.each { |key| + keys.each { |key| ar << key.dup - ar.last << ": " + movies[key].join(', ') + ar.last << ": " + movies[key].join('; ') } info << ar.join('. ') end @@ -180,6 +246,19 @@ class Imdb end class ImdbPlugin < Plugin + BotConfig.register BotConfigBooleanValue.new('imdb.aka', + :default => true, + :desc => "Look for IMDB matches also in translated titles and other 'also known as' information") + BotConfig.register BotConfigBooleanValue.new('imdb.popular', + :default => true, + :desc => "Display info on popular IMDB entries matching the request closely") + BotConfig.register BotConfigBooleanValue.new('imdb.exact', + :default => true, + :desc => "Display info on IMDB entries matching the request exactly") + BotConfig.register BotConfigBooleanValue.new('imdb.fix_article', + :default => false, + :desc => "Try to detect an article placed at the end and move it in front of the title") + def help(plugin, topic="") "imdb <string> => search http://www.imdb.org for <string>" end @@ -192,7 +271,13 @@ class ImdbPlugin < Plugin m.reply "Nothing found for #{what}" return nil end - m.reply info + if info.length == 1 + m.reply Utils.decode_html_entities info.first.join("\n") + else + m.reply info.map { |i| + Utils.decode_html_entities i.join(" | ") + }.join("\n") + end end end