cschiewek-imdb 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +79 -0
- data/bin/imdb +10 -0
- data/lib/imdb.rb +16 -0
- data/lib/imdb/cli.rb +104 -0
- data/lib/imdb/movie.rb +107 -0
- data/lib/imdb/movie_list.rb +33 -0
- data/lib/imdb/search.rb +45 -0
- data/lib/imdb/string_extensions.rb +25 -0
- data/lib/imdb/top_250.rb +10 -0
- data/spec/imdb/cli_spec.rb +34 -0
- data/spec/imdb/movie_spec.rb +98 -0
- data/spec/imdb/search_spec.rb +40 -0
- data/spec/imdb/top_250_spec.rb +21 -0
- data/spec/spec_helper.rb +47 -0
- metadata +83 -0
data/README.rdoc
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
= imdb
|
2
|
+
|
3
|
+
The code, issue tracker and wiki can be found at:
|
4
|
+
|
5
|
+
* http://github.com/ariejan/imdb
|
6
|
+
|
7
|
+
== DESCRIPTION:
|
8
|
+
|
9
|
+
This packages allows you to easy access publicly available data from IMDB.
|
10
|
+
|
11
|
+
== FEATURES/PROBLEMS:
|
12
|
+
|
13
|
+
IMDB currently features the following:
|
14
|
+
|
15
|
+
* Querying details movie info
|
16
|
+
* Searching for movies
|
17
|
+
* Command-line utility included.
|
18
|
+
|
19
|
+
== SYNOPSIS:
|
20
|
+
|
21
|
+
Movies:
|
22
|
+
|
23
|
+
i = Imdb::Movie.new("0095016")
|
24
|
+
|
25
|
+
i.title
|
26
|
+
#=> "Die Hard"
|
27
|
+
i.cast_member.first
|
28
|
+
#=> "Bruce Willis"
|
29
|
+
|
30
|
+
Searching:
|
31
|
+
|
32
|
+
i = Imdb::Search.new("Star Trek")
|
33
|
+
|
34
|
+
i.movies.size
|
35
|
+
#=> 97
|
36
|
+
|
37
|
+
Using the command line utility is quite easy:
|
38
|
+
|
39
|
+
$ imdb Star Trek
|
40
|
+
|
41
|
+
or to get movie info
|
42
|
+
|
43
|
+
$ imdb 0095016
|
44
|
+
|
45
|
+
== REQUIREMENTS:
|
46
|
+
|
47
|
+
All required gems are installed automagically through RubyGems.
|
48
|
+
|
49
|
+
* Hpricot 0.8.1
|
50
|
+
* HTTParty 0.4.3
|
51
|
+
|
52
|
+
== INSTALL:
|
53
|
+
|
54
|
+
* sudo gem install imdb
|
55
|
+
|
56
|
+
== LICENSE:
|
57
|
+
|
58
|
+
(The MIT License)
|
59
|
+
|
60
|
+
Copyright (c) 2009 Ariejan de Vroom
|
61
|
+
|
62
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
63
|
+
a copy of this software and associated documentation files (the
|
64
|
+
'Software'), to deal in the Software without restriction, including
|
65
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
66
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
67
|
+
permit persons to whom the Software is furnished to do so, subject to
|
68
|
+
the following conditions:
|
69
|
+
|
70
|
+
The above copyright notice and this permission notice shall be
|
71
|
+
included in all copies or substantial portions of the Software.
|
72
|
+
|
73
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
74
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
75
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
76
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
77
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
78
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
79
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/imdb
ADDED
data/lib/imdb.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'hpricot'
|
7
|
+
|
8
|
+
require 'imdb/movie'
|
9
|
+
require 'imdb/movie_list'
|
10
|
+
require 'imdb/search'
|
11
|
+
require 'imdb/top_250'
|
12
|
+
require 'imdb/string_extensions'
|
13
|
+
|
14
|
+
module Imdb
|
15
|
+
VERSION = '0.5.0'
|
16
|
+
end
|
data/lib/imdb/cli.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Imdb
|
4
|
+
class CLI
|
5
|
+
|
6
|
+
# Run the imdb command
|
7
|
+
#
|
8
|
+
# Searching
|
9
|
+
#
|
10
|
+
# imdb Star Trek
|
11
|
+
#
|
12
|
+
# Get a movie, supply a 7 digit IMDB id
|
13
|
+
#
|
14
|
+
# imdb 0095016
|
15
|
+
#
|
16
|
+
def self.execute(stdout, arguments=[])
|
17
|
+
|
18
|
+
@stdout = stdout
|
19
|
+
|
20
|
+
options = {
|
21
|
+
}
|
22
|
+
mandatory_options = %w( )
|
23
|
+
|
24
|
+
parser = OptionParser.new do |opts|
|
25
|
+
opts.banner = <<-BANNER.gsub(/^ /,'')
|
26
|
+
IMDB #{Imdb::VERSION}
|
27
|
+
|
28
|
+
Usage: #{File.basename($0)} Search Query
|
29
|
+
#{File.basename($0)} 0095016
|
30
|
+
|
31
|
+
BANNER
|
32
|
+
opts.separator ""
|
33
|
+
opts.on("-v", "--version",
|
34
|
+
"Show the current version.") { stdout.puts "IMDB #{Imdb::VERSION}"; exit }
|
35
|
+
opts.on("-h", "--help",
|
36
|
+
"Show this help message.") { stdout.puts opts; exit }
|
37
|
+
opts.parse!(arguments)
|
38
|
+
|
39
|
+
if mandatory_options && mandatory_options.find { |option| options[option.to_sym].nil? }
|
40
|
+
stdout.puts opts; exit
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
query = arguments.join(" ").strip
|
45
|
+
exit if query.blank?
|
46
|
+
|
47
|
+
movie, search = nil, nil
|
48
|
+
|
49
|
+
# If ID, fetch movie
|
50
|
+
if query.match(/\d\d\d\d\d\d\d/)
|
51
|
+
fetch_movie(query)
|
52
|
+
else
|
53
|
+
search_movie(query)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.fetch_movie(imdb_id)
|
58
|
+
@stdout.puts ">> Fetching movie #{imdb_id}"
|
59
|
+
|
60
|
+
movie = Imdb::Movie.new(imdb_id)
|
61
|
+
|
62
|
+
display_movie_details(movie)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.search_movie(query)
|
66
|
+
@stdout.puts ">> Searching for \"#{query}\""
|
67
|
+
|
68
|
+
search = Imdb::Search.new(query)
|
69
|
+
|
70
|
+
if search.movies.size == 1
|
71
|
+
display_movie_details(search.movies.first)
|
72
|
+
else
|
73
|
+
display_search_results(search.movies)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.display_movie_details(movie)
|
78
|
+
title = "#{movie.title} (#{movie.year})"
|
79
|
+
id = "ID #{movie.id}"
|
80
|
+
|
81
|
+
@stdout.puts
|
82
|
+
@stdout.puts "#{title}#{" " * (75 - 1 - title.length - id.length)}#{id} "
|
83
|
+
@stdout.puts "=" * 75
|
84
|
+
@stdout.puts "Rating: #{movie.rating}"
|
85
|
+
@stdout.puts "Duration: #{movie.length} minutes"
|
86
|
+
@stdout.puts "Directed by: #{movie.director.join(", ")}"
|
87
|
+
@stdout.puts "Cast: #{movie.cast_members[0..4].join(", ")}"
|
88
|
+
@stdout.puts "Genre: #{movie.genres.join(", ")}"
|
89
|
+
@stdout.puts "Plot: #{movie.plot}"
|
90
|
+
@stdout.puts "IMDB URL: #{movie.url}"
|
91
|
+
@stdout.puts "=" * 75
|
92
|
+
@stdout.puts
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.display_search_results(movies = [])
|
96
|
+
movies = movies[0..9] # limit to ten top hits
|
97
|
+
|
98
|
+
movies.each do |movie|
|
99
|
+
@stdout.puts " > #{movie.id} | #{movie.title}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
data/lib/imdb/movie.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
module Imdb
|
2
|
+
|
3
|
+
# Represents a Movie on IMDB.com
|
4
|
+
class Movie
|
5
|
+
attr_accessor :id, :url, :title
|
6
|
+
|
7
|
+
# Initialize a new IMDB movie object with it's IMDB id (as a String)
|
8
|
+
#
|
9
|
+
# movie = Imdb::Movie.new("0095016")
|
10
|
+
#
|
11
|
+
# Imdb::Movie objects are lazy loading, meaning that no HTTP request
|
12
|
+
# will be performed when a new object is created. Only when you use an
|
13
|
+
# accessor that needs the remote data, a HTTP request is made (once).
|
14
|
+
#
|
15
|
+
def initialize(imdb_id, title = nil)
|
16
|
+
@id = imdb_id
|
17
|
+
@url = "http://www.imdb.com/title/tt#{imdb_id}/"
|
18
|
+
@title = title.gsub(/"/, "") if title
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns an array with cast members
|
22
|
+
def cast_members
|
23
|
+
document.search("table.cast td.nm a").map { |link| link.innerHTML.strip.imdb_unescape_html } rescue []
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the name of the director
|
27
|
+
def director
|
28
|
+
# document.at("h5[text()='Director:'] ~ a").innerHTML.strip.imdb_unescape_html rescue nil
|
29
|
+
document.search("h5[text()^='Director'] ~ a").map { |link| link.innerHTML.strip.imdb_unescape_html } rescue []
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns an array of genres (as strings)
|
33
|
+
def genres
|
34
|
+
document.search("h5[text()='Genre:'] ~ a[@href*=/Sections/Genres/']").map { |link| link.innerHTML.strip.imdb_unescape_html } rescue []
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the duration of the movie in minutes as an integer.
|
38
|
+
def length
|
39
|
+
document.search("//h5[text()^='Runtime']/..").innerHTML[/\d+ min/].to_i rescue nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a string containing the plot.
|
43
|
+
def plot
|
44
|
+
document.search("//h5[text()^='Plot']/..").innerHTML.split("\n")[2].gsub(/<.+>.+<\/.+>/, '').strip.imdb_unescape_html rescue nil
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a string containing the URL to the movie poster.
|
48
|
+
def poster
|
49
|
+
document.at("a[@name='poster'] img")['src'][/http:.+@@/] + '.jpg' rescue nil
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a float containing the average user rating
|
53
|
+
def rating
|
54
|
+
document.at(".general.rating b").innerHTML.strip.imdb_unescape_html.split('/').first.to_f rescue nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns a string containing the tagline
|
58
|
+
def tagline
|
59
|
+
document.search("//h5[text()^='Tagline']/..").innerHTML.split("\n")[2].gsub(/<.+>.+<\/.+>/, '').strip.imdb_unescape_html rescue nil
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns a string containing the title
|
63
|
+
def title(force_refresh = false)
|
64
|
+
if @title && !force_refresh
|
65
|
+
@title
|
66
|
+
else
|
67
|
+
@title = document.at("h1").innerHTML.split('<span').first.strip.imdb_unescape_html rescue nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns an integer containing the year (CCYY) the movie was released in.
|
72
|
+
def year
|
73
|
+
document.search('a[@href^="/Sections/Years/"]').innerHTML.to_i
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns a date containing the release date fo the movie.
|
77
|
+
def release_date
|
78
|
+
@date = Date.strptime(document.search("//h5[text()^='Release Date']/..").innerHTML.split("\n")[2].gsub(/<.+>.+<\/.+>/, '').split('(').first.strip,
|
79
|
+
'%d %b %Y') rescue nil
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Returns a new Hpricot document for parsing.
|
85
|
+
def document
|
86
|
+
@document ||= Hpricot(Imdb::Movie.find_by_id(@id))
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# Use HTTParty to fetch the raw HTML for this movie.
|
92
|
+
def self.find_by_id(imdb_id)
|
93
|
+
open("http://www.imdb.com/title/tt#{imdb_id}/")
|
94
|
+
end
|
95
|
+
|
96
|
+
# Convenience method for search
|
97
|
+
def self.search(query)
|
98
|
+
Imdb::Search.new(query).movies
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.top_250
|
102
|
+
Imdb::Top250.new.movies
|
103
|
+
end
|
104
|
+
|
105
|
+
end # Movie
|
106
|
+
|
107
|
+
end # Imdb
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Imdb
|
2
|
+
|
3
|
+
class MovieList
|
4
|
+
def movies
|
5
|
+
@movies ||= parse_movies
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
def parse_movies
|
10
|
+
document.search('a[@href^="/title/tt"]').reject do |element|
|
11
|
+
element.innerHTML.imdb_strip_tags.empty? ||
|
12
|
+
element.parent.innerHTML =~ /media from/i
|
13
|
+
end.map do |element|
|
14
|
+
id = element['href'][/\d+/]
|
15
|
+
|
16
|
+
data = element.parent.innerHTML.split("<br />")
|
17
|
+
if !data[0].nil? && !data[1].nil? && data[0] =~ /img/
|
18
|
+
title = data[1]
|
19
|
+
else
|
20
|
+
title = data[0]
|
21
|
+
end
|
22
|
+
|
23
|
+
title = title.imdb_strip_tags.imdb_unescape_html
|
24
|
+
title.gsub!(/\s+\(\d\d\d\d\)$/, '')
|
25
|
+
|
26
|
+
[id, title]
|
27
|
+
end.uniq.map do |values|
|
28
|
+
Imdb::Movie.new(*values)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end # MovieList
|
32
|
+
|
33
|
+
end # Imdb
|
data/lib/imdb/search.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Imdb
|
2
|
+
|
3
|
+
# Search IMDB for a title
|
4
|
+
class Search < MovieList
|
5
|
+
attr_reader :query
|
6
|
+
|
7
|
+
# Initialize a new IMDB search with the specified query
|
8
|
+
#
|
9
|
+
# search = Imdb::Search.new("Star Trek")
|
10
|
+
#
|
11
|
+
# Imdb::Search is lazy loading, meaning that unless you access the +movies+
|
12
|
+
# attribute, no query is made to IMDB.com.
|
13
|
+
#
|
14
|
+
def initialize(query)
|
15
|
+
@query = query
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns an array of Imdb::Movie objects for easy search result yielded.
|
19
|
+
# If the +query+ was an exact match, a single element array will be returned.
|
20
|
+
def movies
|
21
|
+
@movies ||= (exact_match? ? parse_movie : parse_movies)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def document
|
26
|
+
@document ||= Hpricot(Imdb::Search.query(@query))
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.query(query)
|
30
|
+
open("http://www.imdb.com/find?q=#{CGI::escape(query)};s=tt")
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_movie
|
34
|
+
id = document.at("a[@name='poster']")['href'][/\d+$/]
|
35
|
+
title = document.at("h1").innerHTML.split('<span').first.strip.imdb_unescape_html
|
36
|
+
[Imdb::Movie.new(id, title)]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns true if the search yielded only one result, an exact match
|
40
|
+
def exact_match?
|
41
|
+
!document.at("//h3[text()^='Overview']/..").nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
end # Search
|
45
|
+
end # Imdb
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'iconv'
|
3
|
+
|
4
|
+
|
5
|
+
module Imdb #:nordoc:
|
6
|
+
module StringExtensions
|
7
|
+
|
8
|
+
# Unescape HTML
|
9
|
+
def imdb_unescape_html
|
10
|
+
Iconv.conv("UTF-8", 'ISO-8859-1', CGI::unescapeHTML(self))
|
11
|
+
end
|
12
|
+
|
13
|
+
# Strip tags
|
14
|
+
def imdb_strip_tags
|
15
|
+
gsub(/<\/?[^>]*>/, "")
|
16
|
+
end
|
17
|
+
|
18
|
+
# Strips out whitespace then tests if the string is empty.
|
19
|
+
def blank?
|
20
|
+
strip.empty?
|
21
|
+
end unless method_defined?(:blank?)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
String.send :include, Imdb::StringExtensions
|
data/lib/imdb/top_250.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'imdb/cli'
|
3
|
+
|
4
|
+
describe Imdb::CLI, "execute" do
|
5
|
+
|
6
|
+
describe "yield search results" do
|
7
|
+
before(:each) do
|
8
|
+
@stdout_io = StringIO.new
|
9
|
+
Imdb::CLI.execute(@stdout_io, ["Star Trek"])
|
10
|
+
@stdout_io.rewind
|
11
|
+
@stdout = @stdout_io.read
|
12
|
+
end
|
13
|
+
|
14
|
+
it "report data" do
|
15
|
+
@stdout.should =~ /0060028/
|
16
|
+
@stdout.should =~ /Star Trek/
|
17
|
+
@stdout.should =~ /1966/
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "yield one movie" do
|
22
|
+
before(:each) do
|
23
|
+
@stdout_io = StringIO.new
|
24
|
+
Imdb::CLI.execute(@stdout_io, ["0117731"])
|
25
|
+
@stdout_io.rewind
|
26
|
+
@stdout = @stdout_io.read
|
27
|
+
end
|
28
|
+
|
29
|
+
it "report data" do
|
30
|
+
@stdout.should =~ /Star Trek\: First Contact \(1996\)/
|
31
|
+
@stdout.should =~ /Jonathan Frakes/
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
# This test uses "Die hard (1988)" as a testing sample:
|
4
|
+
#
|
5
|
+
# http://www.imdb.com/title/tt0095016/
|
6
|
+
#
|
7
|
+
|
8
|
+
describe "Imdb::Movie" do
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
# Get Die Hard (1988)
|
12
|
+
@movie = Imdb::Movie.new("0095016")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should find the cast members" do
|
16
|
+
cast = @movie.cast_members
|
17
|
+
|
18
|
+
cast.should be_an(Array)
|
19
|
+
cast.should include("Bruce Willis")
|
20
|
+
cast.should include("Bonnie Bedelia")
|
21
|
+
cast.should include("Alan Rickman")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should find the director" do
|
25
|
+
@movie.director.should be_an(Array)
|
26
|
+
@movie.director.size.should eql(1)
|
27
|
+
@movie.director.first.should =~ /John McTiernan/
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should find the genres" do
|
31
|
+
genres = @movie.genres
|
32
|
+
|
33
|
+
genres.should be_an(Array)
|
34
|
+
genres.should include('Action')
|
35
|
+
genres.should include('Crime')
|
36
|
+
genres.should include('Drama')
|
37
|
+
genres.should include('Thriller')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should find the length (in minutes)" do
|
41
|
+
@movie.length.should eql(131)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should find the plot" do
|
45
|
+
@movie.plot.should eql("New York cop John McClane gives terrorists a dose of their own medicine as they hold hostages in an LA office building.")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should find the poster" do
|
49
|
+
@movie.poster.should eql("http://ia.media-imdb.com/images/M/MV5BMTIxNTY3NjM0OV5BMl5BanBnXkFtZTcwNzg5MzY0MQ@@.jpg")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should find the rating" do
|
53
|
+
@movie.rating.should eql(8.3)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should find the title" do
|
57
|
+
@movie.title.should =~ /Die Hard/
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should find the tagline" do
|
61
|
+
@movie.tagline.should =~ /It will blow you through the back wall of the theater/
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should find the year" do
|
65
|
+
@movie.year.should eql(1988)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should find the release date" do
|
69
|
+
@movie.release_date.should be_a(Date)
|
70
|
+
@movie.release_date.should eql(Date.new(1988, 7, 15))
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "special scenarios" do
|
74
|
+
|
75
|
+
it "should find multiple directors" do
|
76
|
+
# The Matrix Revolutions (2003)
|
77
|
+
movie = Imdb::Movie.new("0242653")
|
78
|
+
|
79
|
+
movie.director.should be_an(Array)
|
80
|
+
movie.director.size.should eql(2)
|
81
|
+
movie.director.should include("Larry Wachowski")
|
82
|
+
movie.director.should include("Andy Wachowski")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should provide a convenience method to search" do
|
87
|
+
movies = Imdb::Movie.search("Star Trek")
|
88
|
+
movies.should respond_to(:each)
|
89
|
+
movies.each { |movie| movie.should be_an_instance_of(Imdb::Movie) }
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should provide a convenience method to top 250" do
|
93
|
+
movies = Imdb::Movie.top_250
|
94
|
+
movies.should respond_to(:each)
|
95
|
+
movies.each { |movie| movie.should be_an_instance_of(Imdb::Movie) }
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "Imdb::Search with multiple search results" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@search = Imdb::Search.new("Star Trek")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should remember the query" do
|
10
|
+
@search.query.should == "Star Trek"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should find > 10 results" do
|
14
|
+
@search.movies.size.should > 10
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return Imdb::Movie objects only" do
|
18
|
+
@search.movies.each { |movie| movie.should be_an(Imdb::Movie) }
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not return movies with no title" do
|
22
|
+
@search.movies.each { |movie| movie.title.should_not be_blank }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "Imdb::Search with an exact match" do
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
@search = Imdb::Search.new("Matrix Revolutions")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should find one result" do
|
34
|
+
@search.movies.size.should eql(1)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have the corrected title" do
|
38
|
+
@search.movies.first.title.should =~ /The Matrix Revolutions/i
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe Imdb::Top250 do
|
4
|
+
before(:each) do
|
5
|
+
@movies = Imdb::Top250.new.movies
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be a list of movies" do
|
9
|
+
@movies.each { |movie| movie.should be_an_instance_of(Imdb::Movie) }
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return the top 250 movies from IMDB.com" do
|
13
|
+
@movies.size.should == 250
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should provide array like access to the movies" do
|
17
|
+
@first = @movies.first
|
18
|
+
@first.title.should == "The Shawshank Redemption"
|
19
|
+
@first.genres.should include("Drama")
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# By default if you have the FakeWeb gem installed when the specs are
|
2
|
+
# run they will hit recorded responses. However, if you don't have
|
3
|
+
# the FakeWeb gem installed or you set the environment variable
|
4
|
+
# LIVE_TEST then the tests will hit the live site IMDB.com.
|
5
|
+
###
|
6
|
+
# Having both methods available for testing allows you to quickly
|
7
|
+
# refactor and add features, while also being able to make sure that
|
8
|
+
# no changes to the IMDB.com interface have affected the parser.
|
9
|
+
###
|
10
|
+
|
11
|
+
begin
|
12
|
+
require 'spec'
|
13
|
+
rescue LoadError
|
14
|
+
require 'rubygems'
|
15
|
+
gem 'rspec'
|
16
|
+
require 'spec'
|
17
|
+
end
|
18
|
+
|
19
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
20
|
+
require 'imdb'
|
21
|
+
|
22
|
+
def read_fixture(path)
|
23
|
+
File.read(File.expand_path(File.join(File.dirname(__FILE__), "fixtures", path)))
|
24
|
+
end
|
25
|
+
|
26
|
+
unless ENV['LIVE_TEST']
|
27
|
+
begin
|
28
|
+
require 'rubygems'
|
29
|
+
require 'fakeweb'
|
30
|
+
|
31
|
+
FakeWeb.allow_net_connect = false
|
32
|
+
{ "http://www.imdb.com:80/find?q=Matrix+Revolutions;s=tt" => "search_matrix_revolutions",
|
33
|
+
"http://www.imdb.com:80/find?q=Star+Trek;s=tt" => "search_star_trek",
|
34
|
+
"http://www.imdb.com:80/title/tt0117731/" => "tt0117731",
|
35
|
+
"http://www.imdb.com:80/title/tt0095016/" => "tt0095016",
|
36
|
+
"http://www.imdb.com:80/title/tt0242653/" => "tt0242653",
|
37
|
+
"http://www.imdb.com:80/title/tt0242653/?fr=c2M9MXxsbT01MDB8ZmI9dXx0dD0xfG14PTIwfHFzPU1hdHJpeCBSZXZvbHV0aW9uc3xodG1sPTF8c2l0ZT1kZnxxPU1hdHJpeCBSZXZvbHV0aW9uc3xwbj0w;fc=1;ft=20" => "tt0242653",
|
38
|
+
"http://www.imdb.com:80/chart/top" => "top_250",
|
39
|
+
"http://www.imdb.com/title/tt0111161/" => "tt0111161",
|
40
|
+
}.each do |url, response|
|
41
|
+
FakeWeb.register_uri(:get, url, :response => read_fixture(response))
|
42
|
+
end
|
43
|
+
rescue LoadError
|
44
|
+
puts "Could not load FakeWeb, these tests will hit IMDB.com"
|
45
|
+
puts "You can run `gem install fakeweb` to stub out the responses."
|
46
|
+
end
|
47
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cschiewek-imdb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Curtis Schiewek
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-21 00:00:00 -07:00
|
13
|
+
default_executable: imdb
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hpricot
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.8.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: httparty
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.3
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: curtis.schiewek@gmail.com
|
37
|
+
executables:
|
38
|
+
- imdb
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- README.rdoc
|
45
|
+
- lib/imdb.rb
|
46
|
+
- lib/imdb/cli.rb
|
47
|
+
- lib/imdb/movie.rb
|
48
|
+
- lib/imdb/movie_list.rb
|
49
|
+
- lib/imdb/search.rb
|
50
|
+
- lib/imdb/string_extensions.rb
|
51
|
+
- lib/imdb/top_250.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage:
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --charset=UTF-8
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.2.0
|
75
|
+
signing_key:
|
76
|
+
specification_version: 2
|
77
|
+
summary: Internet Movie DataBase
|
78
|
+
test_files:
|
79
|
+
- spec/imdb/cli_spec.rb
|
80
|
+
- spec/imdb/movie_spec.rb
|
81
|
+
- spec/imdb/search_spec.rb
|
82
|
+
- spec/imdb/top_250_spec.rb
|
83
|
+
- spec/spec_helper.rb
|