tomato_power 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/Guardfile +9 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +57 -0
  7. data/Rakefile +1 -0
  8. data/lib/tomato_power/api/api.rb +97 -0
  9. data/lib/tomato_power/api/tomato_methods.rb +82 -0
  10. data/lib/tomato_power/client.rb +35 -0
  11. data/lib/tomato_power/helpers/helpers.rb +12 -0
  12. data/lib/tomato_power/helpers/parsers.rb +28 -0
  13. data/lib/tomato_power/movie/actor.rb +12 -0
  14. data/lib/tomato_power/movie/clip.rb +10 -0
  15. data/lib/tomato_power/movie/movie.rb +56 -0
  16. data/lib/tomato_power/movie/review.rb +15 -0
  17. data/lib/tomato_power/version.rb +3 -0
  18. data/lib/tomato_power.rb +22 -0
  19. data/spec/spec_helper.rb +5 -0
  20. data/spec/support/sample_data/no_results +1 -0
  21. data/spec/support/sample_data/sample_actor +5 -0
  22. data/spec/support/sample_data/sample_actors +186 -0
  23. data/spec/support/sample_data/sample_alias +64 -0
  24. data/spec/support/sample_data/sample_clip +6 -0
  25. data/spec/support/sample_data/sample_clips +147 -0
  26. data/spec/support/sample_data/sample_movie +1 -0
  27. data/spec/support/sample_data/sample_movies +46 -0
  28. data/spec/support/sample_data/sample_review +8 -0
  29. data/spec/support/sample_data/sample_reviews +191 -0
  30. data/spec/support/vcr/TomatoPower_API/API_Methods/valid_methods/should_create_methods.yml +598 -0
  31. data/spec/support/vcr/TomatoPower_API/API_options_validation/valid_options/should_consider_0_options_valid.yml +306 -0
  32. data/spec/support/vcr/TomatoPower_API/API_options_validation/valid_options/should_not_raise_error.yml +101 -0
  33. data/spec/support/vcr/TomatoPower_API/List_request/searching_by_title/should_return_a_list_of_movie_objects.yml +101 -0
  34. data/spec/support/vcr/TomatoPower_API/List_request/searching_by_title/should_url_encode_search_string_before_sending.yml +102 -0
  35. data/spec/support/vcr/TomatoPower_API/List_request/should_return_a_list_of_movie_objects.yml +101 -0
  36. data/spec/support/vcr/TomatoPower_API/List_request/should_url_encode_search_string_before_sending.yml +102 -0
  37. data/spec/support/vcr/TomatoPower_API/Movie_request/cast/should_return_cast_of_movie.yml +356 -0
  38. data/spec/support/vcr/TomatoPower_API/Movie_request/clips/should_return_clips_of_movie.yml +638 -0
  39. data/spec/support/vcr/TomatoPower_API/Movie_request/no_results/should_return_error_string_if_no_results_are_found.yml +49 -0
  40. data/spec/support/vcr/TomatoPower_API/Movie_request/reviews/should_return_reviews.yml +271 -0
  41. data/spec/support/vcr/TomatoPower_API/Movie_request/should_return_single_movie.yml +161 -0
  42. data/spec/support/vcr/TomatoPower_API/Movie_request/similar/should_return_similar_movies.yml +121 -0
  43. data/spec/support/vcr/TomatoPower_Client/box_office_movies/should_return_list_of_movies.yml +396 -0
  44. data/spec/support/vcr/TomatoPower_Client/current_release_dvds/should_return_list_of_movies.yml +427 -0
  45. data/spec/support/vcr/TomatoPower_Client/in_theaters_movies/should_return_list_of_movies.yml +380 -0
  46. data/spec/support/vcr/TomatoPower_Client/new_release_dvds/should_return_list_of_movies.yml +392 -0
  47. data/spec/support/vcr/TomatoPower_Client/opening_movies/should_return_list_of_movies.yml +213 -0
  48. data/spec/support/vcr/TomatoPower_Client/search_by_id/should_return_list_of_movies_by_id.yml +88 -0
  49. data/spec/support/vcr/TomatoPower_Client/search_by_title/should_return_list_of_movies_by_title.yml +89 -0
  50. data/spec/support/vcr/TomatoPower_Client/top_rentals/should_return_list_of_movies.yml +409 -0
  51. data/spec/support/vcr/TomatoPower_Client/upcoming_dvds/should_return_list_of_movies.yml +359 -0
  52. data/spec/support/vcr/TomatoPower_Client/upcoming_movies/should_return_list_of_movies.yml +341 -0
  53. data/spec/support/vcr/TomatoPower_Movie/clips/should_return_clips.yml +250 -0
  54. data/spec/support/vcr/TomatoPower_Movie/full_cast/should_return_cast.yml +279 -0
  55. data/spec/support/vcr/TomatoPower_Movie/reviews/should_return_reviews.yml +205 -0
  56. data/spec/support/vcr/TomatoPower_Movie/similar/should_return_similar_movies.yml +231 -0
  57. data/spec/support/vcr/TomatoPower_Movie/similar/should_return_similars.yml +81 -0
  58. data/spec/support/vcr.rb +13 -0
  59. data/spec/unit_specs/actor_spec.rb +16 -0
  60. data/spec/unit_specs/api_spec.rb +126 -0
  61. data/spec/unit_specs/client_spec.rb +73 -0
  62. data/spec/unit_specs/clip_spec.rb +14 -0
  63. data/spec/unit_specs/helpers.rb +50 -0
  64. data/spec/unit_specs/helpers_spec.rb +4 -0
  65. data/spec/unit_specs/movie_spec.rb +75 -0
  66. data/spec/unit_specs/parsers_spec.rb +55 -0
  67. data/spec/unit_specs/review_spec.rb +17 -0
  68. data/spec/unit_specs/tomato_power_spec.rb +6 -0
  69. data/tomato_power.gemspec +29 -0
  70. metadata +295 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ spec/config/tomato_power_config.yaml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format Fuubar
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tomato_power.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sean Kay
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # TomatoPower
2
+
3
+ TomatoPower is a wrapper for the
4
+ [Rotten Tomatoes API](http://developer.rottentomatoes.com/).
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'tomato_power'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install tomato_power
19
+
20
+ ## Usage
21
+
22
+ 1. Create an instance of the `TomatoPower` client.
23
+
24
+ client = TomatoPower.new <your_rotten_tomatoes_api_key>
25
+
26
+ 2. Start using the gem!
27
+
28
+ ## Examples
29
+ Searching for a movie returns an array of `TomatoPower::Movie` objects.
30
+
31
+ >> movies = client.search_by_title("The Dark Knight")
32
+ >> movies[0].title
33
+ => "The Dark Knight"
34
+
35
+ Easily access information from movies and cast members.
36
+
37
+ >> actors = movie.full_cast
38
+ >> actor = actors[0]
39
+ >> actor.name
40
+ => "Christian Bale"
41
+ >> actor.characters
42
+ => ["Batman/Bruce Wayne"]
43
+
44
+ Search for similar movies
45
+
46
+ >> movies = client.search_by_title("The Dark Knight")
47
+ >> similar_movies = movies[0].similar
48
+ >> similar_movies[0].title
49
+ => "Batman Begins"
50
+
51
+ ## Contributing
52
+
53
+ 1. Fork it
54
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
55
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
56
+ 4. Push to the branch (`git push origin my-new-feature`)
57
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,97 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'open-uri'
3
+ require 'json'
4
+
5
+ module TomatoPower
6
+ 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
+
12
+ def initialize api_key
13
+ @api_key = api_key
14
+ end
15
+
16
+ #Defines methods in `TOMATO_METHODS`
17
+ # ==Parameters:
18
+ # options:
19
+ # Hash of options allowed (#see tomato_methods.rb).
20
+ #
21
+ def method_missing method, options={}
22
+ if TOMATO_METHODS.keys.include?(method)
23
+ self.class.send(:define_method, method) do |options={}|
24
+ if options_valid? method, options
25
+ fetch api_url TOMATO_METHODS[method][:url], options
26
+ end
27
+ end
28
+ else
29
+ super
30
+ end
31
+ self.send method, options
32
+ end
33
+
34
+ def respond_to? method
35
+ if TOMATO_METHODS.keys.include? method
36
+ true
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def fetch url
45
+ tomato = get url
46
+ payload = TomatoPower::Parser::parse JSON.parse(tomato)
47
+ end
48
+
49
+ def get url
50
+ open(url) do |f|
51
+ f.read
52
+ end
53
+ end
54
+
55
+ def options_valid? method, options={}
56
+ options.keys.each do |option|
57
+ if option == :page_limit && options[:page_limit] > MAX_PAGE_LIMIT
58
+ options[:pagelimit] = MAX_PAGE_LIMIT
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
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,82 @@
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
+ module TomatoPower
10
+ TOMATO_METHODS = {
11
+ :movies_search =>
12
+ {
13
+ :url => "/movies.json?",
14
+ :whitelist => [:q, :page, :page_limit],
15
+ },
16
+ :box_office_movies =>
17
+ {
18
+ :url => "/lists/movies/box_office.json?",
19
+ :whitelist => [:limit, :country]
20
+ },
21
+ :in_theaters_movies =>
22
+ {
23
+ :url => "/lists/movies/in_theaters.json?",
24
+ :whitelist => [:page, :page_limit, :country]
25
+ },
26
+ :opening_movies =>
27
+ {
28
+ :url => "/lists/movies/opening.json?",
29
+ :whitelist => [:limit, :country]
30
+ },
31
+ :upcoming_movies =>
32
+ {
33
+ :url => "/lists/movies/upcoming.json?",
34
+ :whitelist => [:page, :page_limit, :country]
35
+ },
36
+ :top_rentals =>
37
+ {
38
+ :url => "/lists/dvds/top_rentals.json?",
39
+ :whitelist => [:limit, :country]
40
+ },
41
+ :current_release_dvds =>
42
+ {
43
+ :url => "/lists/dvds/current_releases.json?",
44
+ :whitelist => [:page, :page_limit,:country]
45
+ },
46
+ :new_release_dvds =>
47
+ {
48
+ :url => "/lists/dvds/new_releases.json?",
49
+ :whitelist => [:page, :page_limit, :country]
50
+ },
51
+ :upcoming_dvds =>
52
+ {
53
+ :url => "/lists/dvds/upcoming.json?",
54
+ :whitelist => [:page, :page_limit, :country]
55
+ },
56
+ :movie_cast =>
57
+ {
58
+ :url => "/cast.json?",
59
+ :whitelist => [:movie_id]
60
+ },
61
+ :movie_clips =>
62
+ {
63
+ :url => "/clips.json?",
64
+ :whitelist => [:movie_id]
65
+ },
66
+ :movie_reviews =>
67
+ {
68
+ :url => "/reviews.json?",
69
+ :whitelist => [:movie_id, :review_type, :page_limit, :page, :country]
70
+ },
71
+ :movie_similar =>
72
+ {
73
+ :url => "/similar.json?",
74
+ :whitelist => [:movie_id]
75
+ },
76
+ :movie_alias =>
77
+ {
78
+ :url => "/movie_alias.json?",
79
+ :whitelist => [:type, :id]
80
+ },
81
+ }
82
+ end
@@ -0,0 +1,35 @@
1
+ require 'forwardable'
2
+
3
+ module TomatoPower
4
+ class Client
5
+
6
+ extend Forwardable
7
+
8
+ def initialize
9
+ @api = TomatoPower::api
10
+ end
11
+
12
+ def_delegators :@api,
13
+ :box_office_movies,
14
+ :opening_movies,
15
+ :upcoming_movies,
16
+ :top_rentals,
17
+ :current_release_dvds,
18
+ :new_release_dvds,
19
+ :upcoming_dvds
20
+ def_delegator :@api, :in_theaters_movies, :movies_in_theaters
21
+
22
+ def search_by_title(movie_title, options={})
23
+ options[:q] = movie_title
24
+ @api.movies_search(options)
25
+ end
26
+
27
+ def search_by_id(movie_id)
28
+ options = {}
29
+ options[:type] = 'imdb' #current only supports 'imdb' type
30
+ options[:id] = movie_id
31
+ @api.movie_alias(options)
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ require 'yaml'
2
+
3
+ module Helpers
4
+ String.class_eval do
5
+ def is_valid_url?
6
+ uri = URI.parse self
7
+ uri.kind_of? URI::HTTP
8
+ rescue URI::InvalidURIError
9
+ false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ module TomatoPower
2
+ module Parser
3
+ def self.parse json={}
4
+ payload =[]
5
+ if json["movies"]
6
+ json["movies"].each do |movie|
7
+ payload << Movie.new(movie)
8
+ end
9
+ elsif json["cast"]
10
+ json["cast"].each do |actor|
11
+ payload << Actor.new(actor)
12
+ end
13
+ elsif json["clips"]
14
+ json["clips"].each do |clip|
15
+ payload << Clip.new(clip)
16
+ end
17
+ elsif json["reviews"]
18
+ json["reviews"].each do |review|
19
+ payload << Review.new(review)
20
+ end
21
+ else
22
+ payload << Movie.new(json)
23
+ end
24
+ payload << "No Results" if payload.length < 1
25
+ payload
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ module TomatoPower
2
+ class Actor
3
+
4
+ attr_reader :id, :name, :characters
5
+
6
+ def initialize actor={}
7
+ @id = actor["id"]
8
+ @name = actor["name"]
9
+ @characters = actor["characters"]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module TomatoPower
2
+ class Clip
3
+ attr_reader :title, :duration, :thumbnail
4
+ def initialize clip={}
5
+ @title = clip["title"]
6
+ @duration = clip["duration"]
7
+ @thumbnail = clip["thumbnail"]
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ module TomatoPower
2
+ class Movie
3
+
4
+ attr_reader :id, :info, :abridged_cast, :title, :ratings, :mpaa_rating,
5
+ :runtime,:release_dates, :synopsis, :posters, :alternate_ids, :links,
6
+ :studio, :abridged_directors
7
+
8
+ def initialize movie={}
9
+ @api = TomatoPower::api
10
+
11
+ @info = movie
12
+ @id = movie["id"]
13
+ @title = movie["title"]
14
+ @mpaa_rating = movie["mpaa_rating"]
15
+ @runtime = movie["runtime"]
16
+ @release_dates = movie["release_dates"]
17
+ @ratings = movie["ratings"]
18
+ @synopsis = movie["synopsis"]
19
+ @posters = movie["posters"]
20
+ @abridged_cast = movie["abridged_cast"]
21
+ @alternate_ids = movie["alternate_ids"]
22
+ @links = movie["links"]
23
+ @abridged_directors = movie["abridged_directors"]
24
+ @studio = movie["studio"]
25
+ end
26
+
27
+ MOVIE_METHOD_ALIAS = {
28
+ :full_cast => :movie_cast,
29
+ :clips => :movie_clips,
30
+ :reviews => :movie_reviews,
31
+ :similar => :movie_similar,
32
+ :alias => :movie_alias
33
+ }
34
+
35
+ def method_missing method, options={}
36
+ if MOVIE_METHOD_ALIAS.keys.include?(method)
37
+ method = MOVIE_METHOD_ALIAS[method]
38
+ self.class.send(:define_method, method) do |options={}|
39
+ options[:movie_id] = @id
40
+ @api.send(method, options )
41
+ end
42
+ else
43
+ super
44
+ end
45
+ self.send method
46
+ end
47
+
48
+ def respond_to? method
49
+ if MOVIE_METHOD_ALIAS.keys.include? method
50
+ true
51
+ else
52
+ super
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,15 @@
1
+ module TomatoPower
2
+ class Review
3
+
4
+ attr_reader :critic, :date, :freshness, :publication, :quote, :links
5
+ def initialize review={}
6
+ @critic = review["critic"]
7
+ @date = review["date"]
8
+ @freshness = review["freshness"]
9
+ @publication = review["publication"]
10
+ @quote = review["quote"]
11
+ @links = review["links"]
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module TomatoPower
2
+ VERSION = "0.0.5"
3
+ end
@@ -0,0 +1,22 @@
1
+ require "tomato_power/version"
2
+
3
+ module TomatoPower
4
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'client')
5
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','api', 'api')
6
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','api', 'tomato_methods')
7
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','movie', 'actor')
8
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','clip')
9
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','movie')
10
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'movie','review')
11
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power','helpers', 'helpers')
12
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'tomato_power', 'helpers','parsers')
13
+
14
+ def self.new api_key=ENV.fetch("ROTTEN_TOMATOES_API_KEY")
15
+ self.api = API.new api_key
16
+ Client.new
17
+ end
18
+
19
+ class << self
20
+ attr_accessor :api
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ $: << File.join(File.dirname(__FILE__), "/../lib")
2
+ require 'rubygems'
3
+ require 'support/vcr'
4
+ require 'tomato_power'
5
+ require 'unit_specs/helpers'
@@ -0,0 +1 @@
1
+ {"total":0,"movies":[]}
@@ -0,0 +1,5 @@
1
+ {
2
+ "id": "162655641",
3
+ "name": "Tom Hanks",
4
+ "characters": ["Woody"]
5
+ }