tomato_power 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +22 -13
- data/lib/tomato_power/api/api.rb +30 -66
- data/lib/tomato_power/api/api_service.rb +115 -0
- data/lib/tomato_power/api/tomato_methods.rb +17 -16
- data/lib/tomato_power/client.rb +13 -0
- data/lib/tomato_power/helpers/helpers.rb +2 -0
- data/lib/tomato_power/helpers/parsers.rb +26 -1
- data/lib/tomato_power/movie/actor.rb +1 -0
- data/lib/tomato_power/movie/clip.rb +1 -0
- data/lib/tomato_power/movie/movie.rb +20 -6
- data/lib/tomato_power/movie/poster.rb +14 -0
- data/lib/tomato_power/movie/review.rb +1 -0
- data/lib/tomato_power/version.rb +1 -1
- data/lib/tomato_power.rb +7 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/sample_data/sample_posters +6 -0
- data/spec/unit_specs/api/api_services_spec.rb +39 -0
- data/spec/unit_specs/{api_spec.rb → api/api_spec.rb} +3 -27
- data/spec/unit_specs/helpers/helpers.rb +53 -0
- data/spec/unit_specs/{parsers_spec.rb → helpers/parsers_spec.rb} +12 -12
- data/spec/unit_specs/helpers_spec.rb +0 -2
- data/spec/unit_specs/{actor_spec.rb → movie/actor_spec.rb} +1 -1
- data/spec/unit_specs/{client_spec.rb → movie/client_spec.rb} +1 -1
- data/spec/unit_specs/{clip_spec.rb → movie/clip_spec.rb} +1 -1
- data/spec/unit_specs/{movie_spec.rb → movie/movie_spec.rb} +21 -6
- data/spec/unit_specs/movie/poster_spec.rb +17 -0
- data/spec/unit_specs/{review_spec.rb → movie/review_spec.rb} +2 -2
- metadata +26 -74
- data/spec/support/vcr/TomatoPower_API/API_Methods/valid_methods/should_create_methods.yml +0 -598
- data/spec/support/vcr/TomatoPower_API/API_options_validation/valid_options/should_consider_0_options_valid.yml +0 -306
- data/spec/support/vcr/TomatoPower_API/API_options_validation/valid_options/should_not_raise_error.yml +0 -101
- data/spec/support/vcr/TomatoPower_API/List_request/searching_by_title/should_return_a_list_of_movie_objects.yml +0 -101
- data/spec/support/vcr/TomatoPower_API/List_request/searching_by_title/should_url_encode_search_string_before_sending.yml +0 -102
- data/spec/support/vcr/TomatoPower_API/List_request/should_return_a_list_of_movie_objects.yml +0 -101
- data/spec/support/vcr/TomatoPower_API/List_request/should_url_encode_search_string_before_sending.yml +0 -102
- data/spec/support/vcr/TomatoPower_API/Movie_request/cast/should_return_cast_of_movie.yml +0 -356
- data/spec/support/vcr/TomatoPower_API/Movie_request/clips/should_return_clips_of_movie.yml +0 -638
- data/spec/support/vcr/TomatoPower_API/Movie_request/no_results/should_return_error_string_if_no_results_are_found.yml +0 -49
- data/spec/support/vcr/TomatoPower_API/Movie_request/reviews/should_return_reviews.yml +0 -271
- data/spec/support/vcr/TomatoPower_API/Movie_request/should_return_single_movie.yml +0 -161
- data/spec/support/vcr/TomatoPower_API/Movie_request/similar/should_return_similar_movies.yml +0 -121
- data/spec/support/vcr/TomatoPower_Client/box_office_movies/should_return_list_of_movies.yml +0 -396
- data/spec/support/vcr/TomatoPower_Client/current_release_dvds/should_return_list_of_movies.yml +0 -427
- data/spec/support/vcr/TomatoPower_Client/in_theaters_movies/should_return_list_of_movies.yml +0 -380
- data/spec/support/vcr/TomatoPower_Client/new_release_dvds/should_return_list_of_movies.yml +0 -392
- data/spec/support/vcr/TomatoPower_Client/opening_movies/should_return_list_of_movies.yml +0 -213
- data/spec/support/vcr/TomatoPower_Client/search_by_id/should_return_list_of_movies_by_id.yml +0 -88
- data/spec/support/vcr/TomatoPower_Client/search_by_title/should_return_list_of_movies_by_title.yml +0 -89
- data/spec/support/vcr/TomatoPower_Client/top_rentals/should_return_list_of_movies.yml +0 -409
- data/spec/support/vcr/TomatoPower_Client/upcoming_dvds/should_return_list_of_movies.yml +0 -359
- data/spec/support/vcr/TomatoPower_Client/upcoming_movies/should_return_list_of_movies.yml +0 -341
- data/spec/support/vcr/TomatoPower_Movie/clips/should_return_clips.yml +0 -250
- data/spec/support/vcr/TomatoPower_Movie/full_cast/should_return_cast.yml +0 -279
- data/spec/support/vcr/TomatoPower_Movie/reviews/should_return_reviews.yml +0 -205
- data/spec/support/vcr/TomatoPower_Movie/similar/should_return_similar_movies.yml +0 -231
- data/spec/support/vcr/TomatoPower_Movie/similar/should_return_similars.yml +0 -81
- data/spec/unit_specs/helpers.rb +0 -50
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -18,36 +18,45 @@ Or install it yourself as:
|
|
18
18
|
$ gem install tomato_power
|
19
19
|
|
20
20
|
## Usage
|
21
|
-
|
22
|
-
1. Create an instance of the `TomatoPower` client.
|
21
|
+
Create a `TomatoPower::Client`.
|
23
22
|
|
24
|
-
client = TomatoPower.new <your_rotten_tomatoes_api_key>
|
23
|
+
>> client = TomatoPower.new <your_rotten_tomatoes_api_key>
|
25
24
|
|
26
|
-
2. Start using the gem!
|
27
25
|
|
28
26
|
## Examples
|
29
|
-
|
27
|
+
|
28
|
+
Search for a movie by title or IMDB id.
|
30
29
|
|
31
30
|
>> movies = client.search_by_title("The Dark Knight")
|
31
|
+
|
32
|
+
>> movies = client.search_by_id("0468569")
|
33
|
+
|
34
|
+
Both searches would result in:
|
35
|
+
|
32
36
|
>> movies[0].title
|
33
37
|
=> "The Dark Knight"
|
34
38
|
|
35
|
-
|
39
|
+
Search for similar movies:
|
36
40
|
|
37
|
-
>>
|
41
|
+
>> movies = client.search_by_title("The Dark Knight")
|
42
|
+
>> similar_movies = movies[0].similar
|
43
|
+
>> similar_movies[0].title
|
44
|
+
=> "Batman Begins"
|
45
|
+
|
46
|
+
|
47
|
+
Get cast of a movie:
|
48
|
+
|
49
|
+
>> actors = movie.cast
|
38
50
|
>> actor = actors[0]
|
39
51
|
>> actor.name
|
40
52
|
=> "Christian Bale"
|
41
53
|
>> actor.characters
|
42
54
|
=> ["Batman/Bruce Wayne"]
|
43
55
|
|
44
|
-
|
45
|
-
|
46
|
-
>> movies = client.search_by_title("The Dark Knight")
|
47
|
-
>> similar_movies = movies[0].similar
|
48
|
-
>> similar_movies[0].title
|
49
|
-
=> "Batman Begins"
|
56
|
+
Get posters of a movie:
|
50
57
|
|
58
|
+
>> posters = movie.posters.thumbnail
|
59
|
+
=> "http://content6.flixster.com/movie/11/16/51/11165160_mob.jpg"
|
51
60
|
## Contributing
|
52
61
|
|
53
62
|
1. Fork it
|
data/lib/tomato_power/api/api.rb
CHANGED
@@ -1,29 +1,25 @@
|
|
1
1
|
require 'active_support/core_ext/hash'
|
2
2
|
require 'open-uri'
|
3
|
-
require 'json'
|
4
3
|
|
5
4
|
module TomatoPower
|
5
|
+
# The main API class to interface with the Rotten Tomatoes API
|
6
|
+
#
|
7
|
+
# Handles all API calls
|
6
8
|
class API
|
7
|
-
API_VERSION = 'v1.0'
|
8
|
-
MAX_PAGE_LIMIT = 50
|
9
|
-
BASE_URL = "http://api.rottentomatoes.com/api/public/#{API_VERSION}"
|
10
|
-
MOVIE_URL = "#{ BASE_URL }/movies/"
|
11
9
|
|
12
10
|
def initialize api_key
|
13
11
|
@api_key = api_key
|
14
12
|
end
|
15
13
|
|
16
|
-
#Defines methods in
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
#Defines methods that are in TOMATO_METHODS (tomato_methods.rb)
|
15
|
+
#
|
16
|
+
#@param method Method to be created.
|
17
|
+
#@param options [Hash] optional options being passed to the function call.
|
18
|
+
#@note TOMATO_METHODS is a hash containing all of the Rotten Tomatoes API calls.
|
21
19
|
def method_missing method, options={}
|
22
|
-
if TOMATO_METHODS.
|
20
|
+
if TOMATO_METHODS.key?(method)
|
23
21
|
self.class.send(:define_method, method) do |options={}|
|
24
|
-
|
25
|
-
fetch api_url TOMATO_METHODS[method][:url], options
|
26
|
-
end
|
22
|
+
fetch(TOMATO_METHODS[method][:url], @api_key, options) if options_valid? method, options
|
27
23
|
end
|
28
24
|
else
|
29
25
|
super
|
@@ -31,8 +27,12 @@ module TomatoPower
|
|
31
27
|
self.send method, options
|
32
28
|
end
|
33
29
|
|
30
|
+
# Whether or not this class responds to a function.
|
31
|
+
# Obligatory when dynamically creating functions with :define_method
|
32
|
+
# @param method method in question.
|
33
|
+
# @return [true, false]
|
34
34
|
def respond_to? method
|
35
|
-
if TOMATO_METHODS.
|
35
|
+
if TOMATO_METHODS.key? method
|
36
36
|
true
|
37
37
|
else
|
38
38
|
super
|
@@ -41,57 +41,21 @@ module TomatoPower
|
|
41
41
|
|
42
42
|
private
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
unless TOMATO_METHODS[method][:whitelist].include?(option)
|
61
|
-
raise ArgumentError.new(
|
62
|
-
"Invalid key: #{option} for #{method}.
|
63
|
-
Valid keys are #{TOMATO_METHODS[method][:whitelist]}."
|
64
|
-
)
|
65
|
-
false
|
66
|
-
end
|
67
|
-
end
|
68
|
-
true
|
69
|
-
end
|
70
|
-
|
71
|
-
def api_url endpoint, options={}
|
72
|
-
if movie_id = options[:movie_id]
|
73
|
-
options.delete :movie_id
|
74
|
-
movie_url endpoint, movie_id, options
|
75
|
-
else
|
76
|
-
list_url endpoint, options
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def movie_url endpoint, movie_id, options={}
|
81
|
-
url = "#{MOVIE_URL}#{movie_id}#{endpoint}apikey=#{@api_key}#{request_params(options)}"
|
82
|
-
end
|
83
|
-
|
84
|
-
def list_url endpoint, options={}
|
85
|
-
url = "#{BASE_URL}#{endpoint}apikey=#{@api_key}#{request_params(options)}"
|
86
|
-
end
|
87
|
-
|
88
|
-
def request_params options ={}
|
89
|
-
params = ""
|
90
|
-
options.each_key do |key|
|
91
|
-
options[key] = URI.escape(options[key]) if options[key].is_a?(String)
|
92
|
-
params << "&#{key}=#{options[key]}"
|
93
|
-
end
|
94
|
-
params
|
44
|
+
# Fetches the API call results via APIService
|
45
|
+
#
|
46
|
+
# @param endpoint [String] API endpoint url
|
47
|
+
# @param api_key [String] Client API Key
|
48
|
+
# @param options [Hash] options for API call
|
49
|
+
def fetch endpoint, api_key, options
|
50
|
+
APIService.fetch endpoint, api_key, options
|
51
|
+
end
|
52
|
+
|
53
|
+
# Determines if options are valid for given method.
|
54
|
+
#
|
55
|
+
# @param method [Symbol] API method
|
56
|
+
# @param options [Hash] options for API call
|
57
|
+
def options_valid? method, options
|
58
|
+
APIService.options_valid? method, options
|
95
59
|
end
|
96
60
|
end
|
97
61
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module TomatoPower
|
4
|
+
|
5
|
+
# API service to interface with Rotten Tomatoes API
|
6
|
+
class APIService
|
7
|
+
|
8
|
+
MAX_PAGE_LIMIT = 50
|
9
|
+
API_VERSION = 'v1.0'
|
10
|
+
BASE_URL = "http://api.rottentomatoes.com/api/public/#{API_VERSION}"
|
11
|
+
MOVIE_URL = "#{ BASE_URL }/movies/"
|
12
|
+
LIST_URL = "#{ BASE_URL }/lists/"
|
13
|
+
|
14
|
+
# Gets the url then parses results.
|
15
|
+
#
|
16
|
+
#@param endpoint [String] API url.
|
17
|
+
#@param api_key [String] Client API key
|
18
|
+
#@param options [Hash] optins for the API call
|
19
|
+
#@return (see #parse)
|
20
|
+
def self.fetch endpoint, api_key, options={}
|
21
|
+
tomato = get api_url(endpoint, api_key, options)
|
22
|
+
parse(tomato) if tomato
|
23
|
+
end
|
24
|
+
|
25
|
+
# Constructs the API URL path depending on the options being passed in.
|
26
|
+
# Since the options are being checked against a whitelist before reaching this
|
27
|
+
# point, it is guaranteed that the options here are valid.
|
28
|
+
#
|
29
|
+
# The URL is constructed by introspecting the options. Only search calls contain
|
30
|
+
# the :q symbol, therefore a search_url is created. Likewise for movie specific searches
|
31
|
+
# requiring a :movie_id.
|
32
|
+
#
|
33
|
+
# @param endpoint [String] the end point of the API call.
|
34
|
+
# @param options [Hash<String>] options for the API call.
|
35
|
+
# @return url [String] constructed url for the API call.
|
36
|
+
# @note see TOMATO_METHODS or {http://developer.rottentomatoes.com/ Rotten Tomatoes API} for valid options.
|
37
|
+
def self.api_url endpoint, api_key, options={}
|
38
|
+
if movie_id = options[:movie_id]
|
39
|
+
options.delete :movie_id
|
40
|
+
endpoint = endpoint.dup.insert(0, movie_id.to_s)
|
41
|
+
url = MOVIE_URL
|
42
|
+
elsif options[:q] || options[:id]
|
43
|
+
url = BASE_URL
|
44
|
+
else
|
45
|
+
url = LIST_URL
|
46
|
+
end
|
47
|
+
"#{url}#{endpoint}apikey=#{api_key}#{request_params(options)}"
|
48
|
+
end
|
49
|
+
|
50
|
+
# Checks whether or not the received options are valid for a given method.
|
51
|
+
# @note An option is valid when it is present in the :whitelist of the corresponding method in TOMATO_METHODS.
|
52
|
+
#
|
53
|
+
# @param method [Symbol] method being called.
|
54
|
+
# @param options [Hash] options for the method.
|
55
|
+
# @return [true, false]
|
56
|
+
def self.options_valid? method, options={}
|
57
|
+
options.each_key do |option|
|
58
|
+
if option == :page_limit && options[:page_limit] > MAX_PAGE_LIMIT
|
59
|
+
options[:pagelimit] = MAX_PAGE_LIMIT
|
60
|
+
end
|
61
|
+
unless TOMATO_METHODS[method][:whitelist].include?(option)
|
62
|
+
raise ArgumentError.new(
|
63
|
+
"Invalid key: #{option} for #{method}.
|
64
|
+
Valid keys are #{TOMATO_METHODS[method][:whitelist]}."
|
65
|
+
)
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
# Parses the GET response.
|
74
|
+
#
|
75
|
+
# @param response [String] response from the GET request.
|
76
|
+
# @return result [Array] Array of the parsed results.
|
77
|
+
def self.parse response
|
78
|
+
response = JSON.parse(response)
|
79
|
+
TomatoPower::Parser::parse(response)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Constructs params to be appended to the constructed URL.
|
83
|
+
#
|
84
|
+
# @param options [Hash] options to be appended to the final URL
|
85
|
+
# @return params [String] params for the API call URL.
|
86
|
+
def self.request_params options ={}
|
87
|
+
params = ""
|
88
|
+
options.each_key do |key|
|
89
|
+
option = options[key]
|
90
|
+
option = URI.escape(option) if option.is_a?(String)
|
91
|
+
params << "&#{key}=#{option}"
|
92
|
+
end
|
93
|
+
params
|
94
|
+
end
|
95
|
+
|
96
|
+
# Gets API URL.
|
97
|
+
#
|
98
|
+
# @param url [String] API url.
|
99
|
+
# @return results [Hash<String>] Results from API call.
|
100
|
+
def self.get url
|
101
|
+
if url.is_valid_url?
|
102
|
+
begin
|
103
|
+
open(url) do |f|
|
104
|
+
f.read
|
105
|
+
end
|
106
|
+
rescue OpenURI::HTTPError => error
|
107
|
+
puts "Error: #{error}\nMake sure that the API URL and your API key are valid."
|
108
|
+
puts "URL: #{url}"
|
109
|
+
end
|
110
|
+
else
|
111
|
+
raise ArgumentError.new("Invalid API URL: #{url}")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -1,12 +1,13 @@
|
|
1
|
-
# List of methods and whitelist of allowed options for the corresponding
|
2
|
-
# RottenTomatoes API call.
|
3
|
-
# ==
|
4
|
-
# rotten_tomatoes_api_method =>
|
5
|
-
# {
|
6
|
-
# :url => "resource_url",
|
7
|
-
# :whitelist => [allowed options]
|
8
|
-
# }
|
9
1
|
module TomatoPower
|
2
|
+
# List of urls and whitelist of allowed API methods for the corresponding
|
3
|
+
# RottenTomatoes API call.
|
4
|
+
# ==
|
5
|
+
# rotten_tomatoes_api_method =>
|
6
|
+
# {
|
7
|
+
# :url => "resource_url",
|
8
|
+
# :whitelist => [allowed options]
|
9
|
+
# }
|
10
|
+
# ==
|
10
11
|
TOMATO_METHODS = {
|
11
12
|
:movies_search =>
|
12
13
|
{
|
@@ -15,42 +16,42 @@ module TomatoPower
|
|
15
16
|
},
|
16
17
|
:box_office_movies =>
|
17
18
|
{
|
18
|
-
:url => "
|
19
|
+
:url => "movies/box_office.json?",
|
19
20
|
:whitelist => [:limit, :country]
|
20
21
|
},
|
21
22
|
:in_theaters_movies =>
|
22
23
|
{
|
23
|
-
:url => "
|
24
|
+
:url => "movies/in_theaters.json?",
|
24
25
|
:whitelist => [:page, :page_limit, :country]
|
25
26
|
},
|
26
27
|
:opening_movies =>
|
27
28
|
{
|
28
|
-
:url => "
|
29
|
+
:url => "movies/opening.json?",
|
29
30
|
:whitelist => [:limit, :country]
|
30
31
|
},
|
31
32
|
:upcoming_movies =>
|
32
33
|
{
|
33
|
-
:url => "
|
34
|
+
:url => "movies/upcoming.json?",
|
34
35
|
:whitelist => [:page, :page_limit, :country]
|
35
36
|
},
|
36
37
|
:top_rentals =>
|
37
38
|
{
|
38
|
-
:url => "
|
39
|
+
:url => "dvds/top_rentals.json?",
|
39
40
|
:whitelist => [:limit, :country]
|
40
41
|
},
|
41
42
|
:current_release_dvds =>
|
42
43
|
{
|
43
|
-
:url => "
|
44
|
+
:url => "dvds/current_releases.json?",
|
44
45
|
:whitelist => [:page, :page_limit,:country]
|
45
46
|
},
|
46
47
|
:new_release_dvds =>
|
47
48
|
{
|
48
|
-
:url => "
|
49
|
+
:url => "dvds/new_releases.json?",
|
49
50
|
:whitelist => [:page, :page_limit, :country]
|
50
51
|
},
|
51
52
|
:upcoming_dvds =>
|
52
53
|
{
|
53
|
-
:url => "
|
54
|
+
:url => "dvds/upcoming.json?",
|
54
55
|
:whitelist => [:page, :page_limit, :country]
|
55
56
|
},
|
56
57
|
:movie_cast =>
|
data/lib/tomato_power/client.rb
CHANGED
@@ -3,6 +3,11 @@ require 'forwardable'
|
|
3
3
|
module TomatoPower
|
4
4
|
class Client
|
5
5
|
|
6
|
+
# Main entry point for end users.
|
7
|
+
# Client handles interactions from the user and delegates API calls to the
|
8
|
+
# API class.
|
9
|
+
#
|
10
|
+
# Certain functions are not delegated due to usability design deicisons.
|
6
11
|
extend Forwardable
|
7
12
|
|
8
13
|
def initialize
|
@@ -19,11 +24,19 @@ module TomatoPower
|
|
19
24
|
:upcoming_dvds
|
20
25
|
def_delegator :@api, :in_theaters_movies, :movies_in_theaters
|
21
26
|
|
27
|
+
# Searches for a movie by title.
|
28
|
+
#
|
29
|
+
# @param movie_title [String] The movie title to search for
|
30
|
+
# @param options [Hash] An optional hash for passing options to the API.
|
31
|
+
# @note See {http://developer.rottentomatoes.com/ Rotten Tomatoes API} possible options.
|
22
32
|
def search_by_title(movie_title, options={})
|
23
33
|
options[:q] = movie_title
|
24
34
|
@api.movies_search(options)
|
25
35
|
end
|
26
36
|
|
37
|
+
# Searches for a movie by IMDB id.
|
38
|
+
# @note As of Rotten Tomatoes API v1.0,they only support ID look up via IMDB ids.
|
39
|
+
# @param movie_id [String] movie's id
|
27
40
|
def search_by_id(movie_id)
|
28
41
|
options = {}
|
29
42
|
options[:type] = 'imdb' #current only supports 'imdb' type
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module TomatoPower
|
2
|
+
# Handles parsing of the returned results from an API call.
|
2
3
|
module Parser
|
3
|
-
|
4
|
+
#Parses a json object into a Tomato Power object.
|
5
|
+
#
|
6
|
+
#@param json [JSON] json object from API call response
|
7
|
+
#@return payload [Array] array of parsed Tomato Power objects
|
8
|
+
def self.parse json
|
4
9
|
payload =[]
|
5
10
|
if json["movies"]
|
6
11
|
json["movies"].each do |movie|
|
@@ -24,5 +29,25 @@ module TomatoPower
|
|
24
29
|
payload << "No Results" if payload.length < 1
|
25
30
|
payload
|
26
31
|
end
|
32
|
+
|
33
|
+
# Parses TomatoPower::Movie posters
|
34
|
+
#
|
35
|
+
# @param poster_types [Hash] types of posters
|
36
|
+
# @return [TomatoPower::Poster] poster links
|
37
|
+
def self.parse_posters poster_types
|
38
|
+
Poster.new(poster_types)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Parses TomatoPower::Movie abridged cast members
|
42
|
+
#
|
43
|
+
# @param abridged_cast [Hash] abridged cast from a movie
|
44
|
+
# @return parsed_cast [Array] array of TomatoPower::Actor objects
|
45
|
+
def self.parse_cast abridged_cast
|
46
|
+
parsed_cast =[]
|
47
|
+
abridged_cast.each do |cast_member|
|
48
|
+
parsed_cast << Actor.new( cast_member )
|
49
|
+
end
|
50
|
+
parsed_cast
|
51
|
+
end
|
27
52
|
end
|
28
53
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module TomatoPower
|
2
|
+
# A Movie
|
2
3
|
class Movie
|
3
4
|
|
4
|
-
attr_reader :id, :info, :
|
5
|
-
:runtime,:release_dates, :synopsis, :
|
5
|
+
attr_reader :id, :info, :title, :ratings, :mpaa_rating,
|
6
|
+
:runtime,:release_dates, :synopsis, :alternate_ids, :links,
|
6
7
|
:studio, :abridged_directors
|
7
8
|
|
8
9
|
def initialize movie={}
|
@@ -24,6 +25,7 @@ module TomatoPower
|
|
24
25
|
@studio = movie["studio"]
|
25
26
|
end
|
26
27
|
|
28
|
+
# Aliased API methods for a better interface.
|
27
29
|
MOVIE_METHOD_ALIAS = {
|
28
30
|
:full_cast => :movie_cast,
|
29
31
|
:clips => :movie_clips,
|
@@ -32,17 +34,29 @@ module TomatoPower
|
|
32
34
|
:alias => :movie_alias
|
33
35
|
}
|
34
36
|
|
37
|
+
# Poster for a movie
|
38
|
+
# @return poster links
|
39
|
+
def posters
|
40
|
+
posters ||= TomatoPower::Parser::parse_posters @posters
|
41
|
+
end
|
42
|
+
|
43
|
+
# cast from a movie
|
44
|
+
#
|
45
|
+
# @note this returns the abridged cast.
|
46
|
+
def cast
|
47
|
+
actors ||= TomatoPower::Parser::parse_cast @abridged_cast
|
48
|
+
end
|
49
|
+
|
35
50
|
def method_missing method, options={}
|
36
51
|
if MOVIE_METHOD_ALIAS.keys.include?(method)
|
37
|
-
method = MOVIE_METHOD_ALIAS[method]
|
38
52
|
self.class.send(:define_method, method) do |options={}|
|
39
|
-
options[:movie_id] = @id
|
40
|
-
@api.send(method, options
|
53
|
+
options[:movie_id] = @id
|
54
|
+
@api.send(MOVIE_METHOD_ALIAS[method], options)
|
41
55
|
end
|
42
56
|
else
|
43
57
|
super
|
44
58
|
end
|
45
|
-
self.send method
|
59
|
+
self.send method, options
|
46
60
|
end
|
47
61
|
|
48
62
|
def respond_to? method
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module TomatoPower
|
2
|
+
class Poster
|
3
|
+
|
4
|
+
attr_reader :thumbnail, :profile, :detailed, :original
|
5
|
+
|
6
|
+
def initialize posters={}
|
7
|
+
@thumbnail = posters["thumbnail"]
|
8
|
+
@profile = posters["profile"]
|
9
|
+
@detailed = posters["detailed"]
|
10
|
+
@original = posters["originall"]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
data/lib/tomato_power/version.rb
CHANGED
data/lib/tomato_power.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
1
|
require "tomato_power/version"
|
2
2
|
|
3
3
|
module TomatoPower
|
4
|
+
|
4
5
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'client')
|
5
6
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','api', 'api')
|
7
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','api', 'api_service')
|
6
8
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','api', 'tomato_methods')
|
7
9
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','movie', 'actor')
|
10
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','movie', 'poster')
|
8
11
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','clip')
|
9
12
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','movie')
|
10
13
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','review')
|
11
14
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','helpers', 'helpers')
|
12
15
|
require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'helpers','parsers')
|
13
16
|
|
17
|
+
# Handles Rotten Tomatoes API key assignment and creates a new client for the
|
18
|
+
# end user.
|
14
19
|
def self.new api_key=ENV.fetch("ROTTEN_TOMATOES_API_KEY")
|
15
20
|
self.api = API.new api_key
|
16
21
|
Client.new
|
17
22
|
end
|
18
23
|
|
24
|
+
# Sets class level accessor
|
25
|
+
# @api : API object
|
19
26
|
class << self
|
20
27
|
attr_accessor :api
|
21
28
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,6 @@
|
|
1
|
+
{
|
2
|
+
"thumbnail": "http://content9.flixster.com/movie/10/93/18/10931807_mob.jpg",
|
3
|
+
"profile": "http://content9.flixster.com/movie/10/93/18/10931807_pro.jpg",
|
4
|
+
"detailed": "http://content9.flixster.com/movie/10/93/18/10931807_det.jpg",
|
5
|
+
"original": "http://content9.flixster.com/movie/10/93/18/10931807_ori.jpg"
|
6
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module TomatoPower
|
4
|
+
describe "APIService" do
|
5
|
+
before do
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "fetch" do
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "api_url" do
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "API options validation" do
|
15
|
+
|
16
|
+
describe "valid options" do
|
17
|
+
|
18
|
+
it "should not raise error" do
|
19
|
+
expect { APIService.options_valid?(:movies_search, {:q => "movie", :page => 1})}.
|
20
|
+
not_to raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should consider 0 options valid" do
|
24
|
+
|
25
|
+
expect { APIService.options_valid?(:movies_search)}.
|
26
|
+
not_to raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "invalid options" do
|
32
|
+
it "should raise error" do
|
33
|
+
expect { APIService.options_valid?(:movies_search, {:invalid => "movie"})}.
|
34
|
+
to raise_error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|