tomato_power 0.0.5 → 0.0.7
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/.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
|