filmbuff 0.1.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/History CHANGED
@@ -1,3 +1,16 @@
1
+ == 0.1.5
2
+
3
+ * major enhancements
4
+ * Ruby 1.8.x support. Only tested with 1.8.7-p334 but it should work with
5
+ versions below as well. I don't intend to test with 1.8.x again, so consider
6
+ yourself warned.
7
+ * Use the new HTTParty-Icebox gem instead of vendoring the code.
8
+ * Changed runtime format. Now returns the length in seconds rather than
9
+ minutes, allowing greater customization.
10
+
11
+ * minor enhancements
12
+ * Removed redundant Rspec tests.
13
+
1
14
  == 0.1.2 2011-03-07
2
15
 
3
16
  * minor enhancements
data/README.md CHANGED
@@ -20,7 +20,22 @@ Alternatively you can check out the latest code directly from Github
20
20
 
21
21
  ## Usage
22
22
 
23
- Film Buff 0.1.0 provides two easy ways to return an object with information on a movie or TV show. First, set up an IMDb instance:
23
+ Accessible title information is:
24
+
25
+ - Title
26
+ - Tagline
27
+ - Plot
28
+ - Runtime
29
+ - Rating
30
+ - Amount of votes
31
+ - Poster URL
32
+ - Genres
33
+ - Release date
34
+ - IMDb ID
35
+
36
+ ### Examples
37
+
38
+ Film Buff 0.1.x provides two easy ways to return an object with information on a movie or TV show. First, set up an IMDb instance:
24
39
 
25
40
  require 'filmbuff'
26
41
  imdb = FilmBuff::IMDb.new
@@ -14,13 +14,11 @@ Gem::Specification.new do |s|
14
14
 
15
15
  s.rubyforge_project = "filmbuff"
16
16
 
17
- s.required_ruby_version = ">= 1.9.2"
18
-
19
- s.add_dependency("httparty", "0.7.4")
20
-
21
- s.add_development_dependency("rspec", "2.5.0")
17
+ s.add_dependency("httparty", "~> 0.7.4")
18
+ s.add_dependency("httparty-icebox", "~> 0.0.1")
19
+ s.add_development_dependency("rspec", "~> 2.5.0")
22
20
 
23
21
  s.files = `git ls-files`.split("\n")
24
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
25
23
  s.require_paths = ["lib"]
26
24
  end
@@ -1,6 +1,6 @@
1
1
  require 'httparty'
2
+ require 'httparty-icebox'
2
3
 
3
4
  dir = File.expand_path(File.dirname(__FILE__))
4
- require File.join(dir, 'filmbuff', 'httparty_icebox')
5
5
  require File.join(dir, 'filmbuff', 'imdb')
6
6
  require File.join(dir, 'filmbuff', 'title')
@@ -4,7 +4,7 @@ module FilmBuff
4
4
 
5
5
  include HTTParty
6
6
  include HTTParty::Icebox
7
- cache :store => 'file', :timeout => 120, :location => Dir.tmpdir
7
+ cache :store => 'memory', :timeout => 120
8
8
 
9
9
  base_uri 'app.imdb.com'
10
10
  default_params = {
@@ -21,14 +21,14 @@ module FilmBuff
21
21
  public
22
22
  def find_by_id(imdb_id)
23
23
  result = self.class.get('/title/maindetails', :query => {
24
- tconst: imdb_id, locale: @locale
24
+ :tconst => imdb_id, :locale => @locale
25
25
  }).parsed_response
26
26
  Title.new(result["data"])
27
27
  end
28
28
 
29
29
  def find_by_title(title)
30
30
  results = self.class.get('/find', :query => {
31
- q: title, locale: @locale
31
+ :q => title, :locale => @locale
32
32
  }).parsed_response
33
33
  find_by_id(results["data"]["results"][0]["list"][0]["tconst"])
34
34
  end
@@ -1,6 +1,6 @@
1
1
  module FilmBuff
2
2
  class Title
3
- attr_accessor :imdb_id, :title, :tagline, :plot, :runtime, :rating, :votes,
3
+ attr_reader :imdb_id, :title, :tagline, :plot, :runtime, :rating, :votes,
4
4
  :poster_url, :genres, :release_date
5
5
 
6
6
  def initialize(options = {})
@@ -8,8 +8,7 @@ module FilmBuff
8
8
  @title = options["title"]
9
9
  @tagline = options["tagline"]
10
10
  @plot = options["plot"]["outline"] if options["plot"]
11
- @runtime = "#{(options["runtime"]["time"]/60).to_i} min" if
12
- options["runtime"]
11
+ @runtime = options["runtime"]["time"] if options["runtime"]
13
12
  @rating = options["rating"]
14
13
  @votes = options["num_votes"]
15
14
  @poster_url = options["image"]["url"] if options["image"]
@@ -1,3 +1,3 @@
1
1
  module Filmbuff
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.5"
3
3
  end
@@ -5,19 +5,6 @@ describe FilmBuff::IMDb do
5
5
  @imdb = FilmBuff::IMDb.new
6
6
  end
7
7
 
8
- describe "#locale" do
9
- it "returns the locale" do
10
- @imdb.locale.should == "en_US"
11
- end
12
- end
13
-
14
- describe "#locale=" do
15
- it "sets locale to the given value" do
16
- @imdb.locale = "de_DE"
17
- @imdb.locale.should == "de_DE"
18
- end
19
- end
20
-
21
8
  describe "#find_by_id" do
22
9
  before(:all) do
23
10
  @title = @imdb.find_by_id("tt0032138")
@@ -22,13 +22,13 @@ describe FilmBuff::Title do
22
22
  end
23
23
 
24
24
  it "has a plot" do
25
- @title.plot.should == "Dorothy Gale is swept away to a magical land in " <<
26
- "a tornado and embarks on a quest to see the Wizard who can help her " <<
25
+ @title.plot.should == "Dorothy Gale is swept away to a magical land in" <<
26
+ " a tornado and embarks on a quest to see the Wizard who can help her " <<
27
27
  "return home."
28
28
  end
29
29
 
30
30
  it "has a runtime" do
31
- @title.runtime.should == "101 min"
31
+ @title.runtime.should == 6060
32
32
  end
33
33
 
34
34
  it "has a rating" do
@@ -44,7 +44,7 @@ describe FilmBuff::Title do
44
44
  end
45
45
 
46
46
  it "has genres" do
47
- @title.genres.should == %w[ Adventure Comedy Family Fantasy Musical]
47
+ @title.genres.should == %w[ Adventure Comedy Family Fantasy Musical ]
48
48
  end
49
49
 
50
50
  it "has a release date" do
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: filmbuff
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.2
5
+ version: 0.1.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kristoffer Sachse
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-07 00:00:00 +01:00
13
+ date: 2011-03-15 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -19,22 +19,33 @@ dependencies:
19
19
  requirement: &id001 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
- - - "="
22
+ - - ~>
23
23
  - !ruby/object:Gem::Version
24
24
  version: 0.7.4
25
25
  type: :runtime
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec
28
+ name: httparty-icebox
29
29
  prerelease: false
30
30
  requirement: &id002 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
- - - "="
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 0.0.1
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
34
45
  - !ruby/object:Gem::Version
35
46
  version: 2.5.0
36
47
  type: :development
37
- version_requirements: *id002
48
+ version_requirements: *id003
38
49
  description: Film Buff provides a Ruby wrapper for IMDb's JSON API, which is the fastest and easiest way to get information from IMDb.
39
50
  email:
40
51
  - kristoffer@sachse.nu
@@ -53,7 +64,6 @@ files:
53
64
  - Rakefile
54
65
  - filmbuff.gemspec
55
66
  - lib/filmbuff.rb
56
- - lib/filmbuff/httparty_icebox.rb
57
67
  - lib/filmbuff/imdb.rb
58
68
  - lib/filmbuff/title.rb
59
69
  - lib/filmbuff/version.rb
@@ -75,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
85
  requirements:
76
86
  - - ">="
77
87
  - !ruby/object:Gem::Version
78
- version: 1.9.2
88
+ version: "0"
79
89
  required_rubygems_version: !ruby/object:Gem::Requirement
80
90
  none: false
81
91
  requirements:
@@ -85,12 +95,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
95
  requirements: []
86
96
 
87
97
  rubyforge_project: filmbuff
88
- rubygems_version: 1.6.0
98
+ rubygems_version: 1.6.2
89
99
  signing_key:
90
100
  specification_version: 3
91
101
  summary: A Ruby wrapper for IMDb's JSON API
92
- test_files:
93
- - spec/filmbuff/imdb_spec.rb
94
- - spec/filmbuff/title_spec.rb
95
- - spec/filmbuff_spec.rb
96
- - spec/spec_helper.rb
102
+ test_files: []
103
+
@@ -1,283 +0,0 @@
1
- # = Icebox : Caching for HTTParty
2
- #
3
- # Cache responses in HTTParty models [http://github.com/jnunemaker/httparty]
4
- #
5
- # === Usage
6
- #
7
- # class Foo
8
- # include HTTParty
9
- # include HTTParty::Icebox
10
- # cache :store => 'file', :timeout => 600, :location => MY_APP_ROOT.join('tmp', 'cache')
11
- # end
12
- #
13
- # Modeled after Martyn Loughran's APICache [http://github.com/newbamboo/api_cache]
14
- # and Ruby On Rails's caching [http://api.rubyonrails.org/classes/ActiveSupport/Cache.html]
15
- #
16
- # Author: Karel Minarik [www.karmi.cz]
17
- #
18
- # === Notes
19
- #
20
- # Thanks to Amit Chakradeo for pointing out response objects have to be stored marhalled on FS
21
- # Thanks to Marlin Forbes for pointing out the query parameters have to be included in the cache key
22
- #
23
- #
24
-
25
- require 'logger'
26
- require 'fileutils'
27
- require 'tmpdir'
28
- require 'pathname'
29
- require 'digest/md5'
30
-
31
- module HTTParty #:nodoc:
32
- # == Caching for HTTParty
33
- # See documentation in HTTParty::Icebox::ClassMethods.cache
34
- #
35
- module Icebox
36
-
37
- module ClassMethods
38
-
39
- # Enable caching and set cache options
40
- # Returns memoized cache object
41
- #
42
- # Following options are available, default values are in []:
43
- #
44
- # +store+:: Storage mechanism for cached data (memory, filesystem, your own) [memory]
45
- # +timeout+:: Cache expiration in seconds [60]
46
- # +logger+:: Path to logfile or logger instance [nil, silent]
47
- #
48
- # Any additional options are passed to the Cache constructor
49
- #
50
- # Usage:
51
- #
52
- # # Enable caching in HTTParty, in memory, for 1 minute
53
- # cache # Use default values
54
- #
55
- # # Enable caching in HTTParty, on filesystem (/tmp), for 10 minutes
56
- # cache :store => 'file', :timeout => 600, :location => '/tmp/'
57
- #
58
- # # Use your own cache store (see +AbstractStore+ class below)
59
- # cache :store => 'memcached', :timeout => 600, :server => '192.168.1.1:1001'
60
- #
61
- def cache(options={})
62
- options[:store] ||= 'memory'
63
- options[:timeout] ||= 60
64
- logger = options[:logger]
65
- @cache ||= Cache.new( options.delete(:store), options )
66
- end
67
-
68
- end
69
-
70
- # When included, extend class with +cache+ method
71
- # and redefine +get+ method to use cache
72
- #
73
- def self.included(receiver) #:nodoc:
74
- receiver.extend ClassMethods
75
- receiver.class_eval do
76
-
77
- # Get reponse from network
78
- #
79
- # TODO: Why alias :new :old is not working here? Returns NoMethodError
80
- #
81
- def self.get_without_caching(path, options={})
82
- perform_request Net::HTTP::Get, path, options
83
- end
84
-
85
- # Get response from cache, if available
86
- #
87
- def self.get_with_caching(path, options={})
88
- key = path.downcase # this makes a copy of path
89
- key << options[:query].to_s if defined? options[:query]
90
- if cache.exists?(key) and not cache.stale?(key)
91
- Cache.logger.debug "CACHE -- GET #{path}#{options[:query]}"
92
- return cache.get(key)
93
- else
94
- Cache.logger.debug "/!\\ NETWORK -- GET #{path}#{options[:query]}"
95
- response = get_without_caching(path, options)
96
- cache.set(key, response) if response.code.to_s == "200" # this works for string and integer response codes
97
- return response
98
- end
99
- end
100
-
101
- # Redefine original HTTParty +get+ method to use cache
102
- #
103
- def self.get(path, options={})
104
- self.get_with_caching(path, options)
105
- end
106
-
107
- end
108
- end
109
-
110
- # === Cache container
111
- #
112
- # Pass a store name ('memory', etc) to new
113
- #
114
- class Cache
115
- attr_accessor :store
116
-
117
- def initialize(store, options={})
118
- self.class.logger = options[:logger]
119
- @store = self.class.lookup_store(store).new(options)
120
- end
121
-
122
- def get(key)
123
- @store.get encode(key) unless stale?(key)
124
- end
125
-
126
- def set(key, value)
127
- # puts "Cache.set, key: #{key}, value: #{value}"
128
- @store.set encode(key), value
129
- end
130
-
131
- def exists?(key)
132
- @store.exists? encode(key)
133
- end
134
-
135
- def stale?(key)
136
- @store.stale? encode(key)
137
- end
138
-
139
- def self.logger
140
- @logger || default_logger
141
- end
142
-
143
- def self.default_logger
144
- logger = ::Logger.new(STDERR)
145
- end
146
-
147
- # Pass a filename (String), IO object, Logger instance or +nil+ to silence the logger
148
- def self.logger=(device)
149
- @logger = device.kind_of?(::Logger) ? device : ::Logger.new(device)
150
- end
151
-
152
- private
153
- # Return store class based on passed name
154
- def self.lookup_store(name)
155
- store_name = "#{name.capitalize}Store"
156
- return Store::const_get(store_name)
157
- rescue NameError => e
158
- raise Store::StoreNotFound, "The cache store '#{store_name}' was not found. Did you load any such class?"
159
- end
160
-
161
- def encode(key)
162
- Digest::MD5.hexdigest(key)
163
- end
164
- end
165
-
166
-
167
- # === Cache stores
168
- #
169
- module Store
170
-
171
- class StoreNotFound < StandardError; end #:nodoc:
172
-
173
- # ==== Abstract Store
174
- # Inherit your store from this class
175
- # *IMPORTANT*: Do not forget to call +super+ in your +initialize+ method!
176
- #
177
- class AbstractStore
178
- def initialize(options={})
179
- raise ArgumentError, "You need to set the :timeout parameter" unless options[:timeout]
180
- @timeout = options[:timeout]
181
- message = "Cache: Using #{self.class.to_s.split('::').last}"
182
- message << " in location: #{options[:location]}" if options[:location]
183
- message << " with timeout #{options[:timeout]} sec"
184
- Cache.logger.info message unless options[:logger].nil?
185
- return self
186
- end
187
- %w{set get exists? stale?}.each do |method_name|
188
- define_method(method_name) { raise NoMethodError, "Please implement method #{method_name} in your store class" }
189
- end
190
- end
191
-
192
- # ==== Store objects in memory
193
- # See HTTParty::Icebox::ClassMethods.cache
194
- #
195
- class MemoryStore < AbstractStore
196
- def initialize(options={})
197
- super; @store = {}; self
198
- end
199
- def set(key, value)
200
- Cache.logger.info("Cache: set (#{key})")
201
- @store[key] = [Time.now, value]; true
202
- end
203
- def get(key)
204
- data = @store[key][1]
205
- Cache.logger.info("Cache: #{data.nil? ? "miss" : "hit"} (#{key})")
206
- data
207
- end
208
- def exists?(key)
209
- !@store[key].nil?
210
- end
211
- def stale?(key)
212
- return true unless exists?(key)
213
- Time.now - created(key) > @timeout
214
- end
215
- private
216
- def created(key)
217
- @store[key][0]
218
- end
219
- end
220
-
221
- # ==== Store objects on the filesystem
222
- # See HTTParty::Icebox::ClassMethods.cache
223
- #
224
- class FileStore < AbstractStore
225
- def initialize(options={})
226
- super
227
- options[:location] ||= Dir::tmpdir
228
- @path = Pathname.new( options[:location] )
229
- FileUtils.mkdir_p( @path )
230
- self
231
- end
232
- def set(key, value)
233
- Cache.logger.info("Cache: set (#{key})")
234
- File.open( @path.join(key), 'w' ) { |file| file << Marshal.dump(value) }
235
- true
236
- end
237
- def get(key)
238
- data = Marshal.load(File.read( @path.join(key)))
239
- Cache.logger.info("Cache: #{data.nil? ? "miss" : "hit"} (#{key})")
240
- data
241
- end
242
- def exists?(key)
243
- File.exists?( @path.join(key) )
244
- end
245
- def stale?(key)
246
- return true unless exists?(key)
247
- Time.now - created(key) > @timeout
248
- end
249
- private
250
- def created(key)
251
- File.mtime( @path.join(key) )
252
- end
253
- end
254
- end
255
-
256
- end
257
- end
258
-
259
-
260
- # Major parts of this code are based on architecture of ApiCache.
261
- # Copyright (c) 2008 Martyn Loughran
262
- #
263
- # Other parts are inspired by the ActiveSupport::Cache in Ruby On Rails.
264
- # Copyright (c) 2005-2009 David Heinemeier Hansson
265
- #
266
- # Permission is hereby granted, free of charge, to any person obtaining
267
- # a copy of this software and associated documentation files (the
268
- # "Software"), to deal in the Software without restriction, including
269
- # without limitation the rights to use, copy, modify, merge, publish,
270
- # distribute, sublicense, and/or sell copies of the Software, and to
271
- # permit persons to whom the Software is furnished to do so, subject to
272
- # the following conditions:
273
- #
274
- # The above copyright notice and this permission notice shall be
275
- # included in all copies or substantial portions of the Software.
276
- #
277
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
278
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
279
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
280
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
281
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
282
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
283
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.