tmdb_party 0.4.1 → 0.5.0
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 +3 -1
- data/Rakefile +9 -20
- data/VERSION.yml +2 -2
- data/lib/tmdb_party.rb +32 -18
- data/lib/tmdb_party/attributes.rb +29 -13
- data/lib/tmdb_party/cast_member.rb +36 -0
- data/lib/tmdb_party/country.rb +25 -0
- data/lib/tmdb_party/image.rb +39 -14
- data/lib/tmdb_party/movie.rb +28 -31
- data/lib/tmdb_party/person.rb +19 -11
- data/lib/tmdb_party/studio.rb +19 -0
- data/{test → spec}/fixtures/imdb_no_results.json +0 -0
- data/{test → spec}/fixtures/imdb_search.json +0 -0
- data/spec/fixtures/megan_fox.json +630 -0
- data/{test → spec}/fixtures/no_groups.json +0 -0
- data/spec/fixtures/nothing_found.json +1 -0
- data/{test → spec}/fixtures/rad.json +0 -0
- data/{test → spec}/fixtures/search.json +0 -0
- data/spec/fixtures/search_person.json +38 -0
- data/spec/fixtures/shitty_shit_result.json +1 -0
- data/{test → spec}/fixtures/single_result.json +0 -0
- data/{test → spec}/fixtures/transformers.json +16 -3
- data/spec/lib/tmdb_party/cast_member_spec.rb +52 -0
- data/spec/lib/tmdb_party/country_spec.rb +24 -0
- data/spec/lib/tmdb_party/image_spec.rb +73 -0
- data/spec/lib/tmdb_party/movie_spec.rb +110 -0
- data/spec/lib/tmdb_party/person_spec.rb +55 -0
- data/spec/lib/tmdb_party/studio_spec.rb +20 -0
- data/spec/lib/tmdb_party_spec.rb +103 -0
- data/{test/test_helper.rb → spec/spec_helper.rb} +1 -9
- data/tmdb_party.gemspec +35 -14
- metadata +33 -12
data/README.rdoc
CHANGED
@@ -4,6 +4,7 @@ Simple ruby wrapper to themoviedb.org (http://api.themoviedb.org/2.0/docs/) usin
|
|
4
4
|
|
5
5
|
= usage:
|
6
6
|
sudo gem install tmdb_party -s http://gemcutter.org
|
7
|
+
require 'rubygems'
|
7
8
|
require 'tmdb_party'
|
8
9
|
|
9
10
|
= example:
|
@@ -14,7 +15,7 @@ Simple ruby wrapper to themoviedb.org (http://api.themoviedb.org/2.0/docs/) usin
|
|
14
15
|
results.length
|
15
16
|
# => 5
|
16
17
|
|
17
|
-
transformers = results.detect{|m| m.
|
18
|
+
transformers = results.detect{|m| m.name == "Transformers"}
|
18
19
|
|
19
20
|
transformers.popularity
|
20
21
|
# => 31
|
@@ -37,6 +38,7 @@ It's a movie database, kind of like IMDB except it's more of a community wiki. T
|
|
37
38
|
|
38
39
|
== Contributors
|
39
40
|
Jon Maddox (http://github.com/maddox)
|
41
|
+
Magnus Bergmark (http://github.com/Mange)
|
40
42
|
|
41
43
|
== Copyright
|
42
44
|
|
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
gem.add_dependency('httparty', '>= 0.4.3')
|
13
13
|
|
14
14
|
gem.add_development_dependency('fakeweb')
|
15
|
-
gem.add_development_dependency('
|
15
|
+
gem.add_development_dependency('rspec')
|
16
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
17
|
end
|
18
18
|
Jeweler::GemcutterTasks.new
|
@@ -20,28 +20,18 @@ rescue LoadError
|
|
20
20
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
21
|
end
|
22
22
|
|
23
|
-
require 'rake/
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
test.verbose = true
|
23
|
+
require 'spec/rake/spectask'
|
24
|
+
desc "Run all examples"
|
25
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
26
|
+
t.pattern = 'spec/**/*_spec.rb'
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
test.libs << 'test'
|
34
|
-
test.pattern = 'test/**/*_test.rb'
|
35
|
-
test.verbose = true
|
36
|
-
end
|
37
|
-
rescue LoadError
|
38
|
-
task :rcov do
|
39
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
40
|
-
end
|
29
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
30
|
+
t.pattern = 'spec/**/*_spec.rb'
|
31
|
+
t.rcov = true
|
41
32
|
end
|
42
33
|
|
43
|
-
|
44
|
-
task :default => :test
|
34
|
+
task :default => :spec
|
45
35
|
|
46
36
|
require 'rake/rdoctask'
|
47
37
|
Rake::RDocTask.new do |rdoc|
|
@@ -57,4 +47,3 @@ Rake::RDocTask.new do |rdoc|
|
|
57
47
|
rdoc.rdoc_files.include('README*')
|
58
48
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
59
49
|
end
|
60
|
-
|
data/VERSION.yml
CHANGED
data/lib/tmdb_party.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
# gem 'httparty'
|
2
2
|
require 'httparty'
|
3
|
-
|
4
|
-
|
5
|
-
require
|
6
|
-
|
7
|
-
require 'tmdb_party/genre'
|
8
|
-
require 'tmdb_party/person'
|
9
|
-
require 'tmdb_party/image'
|
10
|
-
require 'tmdb_party/movie'
|
3
|
+
|
4
|
+
%w[core_extensions httparty_icebox attributes video genre person image country studio cast_member movie].each do |class_name|
|
5
|
+
require "tmdb_party/#{class_name}"
|
6
|
+
end
|
11
7
|
|
12
8
|
module TMDBParty
|
13
9
|
class Base
|
@@ -18,18 +14,13 @@ module TMDBParty
|
|
18
14
|
base_uri 'http://api.themoviedb.org/2.1'
|
19
15
|
format :json
|
20
16
|
|
21
|
-
def initialize(key)
|
17
|
+
def initialize(key, lang = 'en')
|
22
18
|
@api_key = key
|
23
|
-
|
24
|
-
|
25
|
-
def default_path_items
|
26
|
-
path_items = ['en']
|
27
|
-
path_items << 'json'
|
28
|
-
path_items << @api_key
|
19
|
+
@lang = lang
|
29
20
|
end
|
30
21
|
|
31
22
|
def search(query)
|
32
|
-
data = self.class.get(
|
23
|
+
data = self.class.get(method_url('Movie.search', query))
|
33
24
|
if data.class != Array || data.first == "Nothing found."
|
34
25
|
[]
|
35
26
|
else
|
@@ -37,8 +28,17 @@ module TMDBParty
|
|
37
28
|
end
|
38
29
|
end
|
39
30
|
|
31
|
+
def search_person(query)
|
32
|
+
data = self.class.get(method_url('Person.search', query))
|
33
|
+
if data.class != Array || data.first == "Nothing found."
|
34
|
+
[]
|
35
|
+
else
|
36
|
+
data.collect { |person| Person.new(person, self) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
40
|
def imdb_lookup(imdb_id)
|
41
|
-
data = self.class.get(
|
41
|
+
data = self.class.get(method_url('Movie.imdbLookup', imdb_id))
|
42
42
|
if data.class != Array || data.first == "Nothing found."
|
43
43
|
nil
|
44
44
|
else
|
@@ -47,8 +47,22 @@ module TMDBParty
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def get_info(id)
|
50
|
-
data = self.class.get(
|
50
|
+
data = self.class.get(method_url('Movie.getInfo', id))
|
51
51
|
Movie.new(data.first, self)
|
52
52
|
end
|
53
|
+
|
54
|
+
def get_person(id)
|
55
|
+
data = self.class.get(method_url('Person.getInfo', id))
|
56
|
+
Person.new(data.first, self)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def default_path_items
|
61
|
+
[@lang, 'json', @api_key]
|
62
|
+
end
|
63
|
+
|
64
|
+
def method_url(method, value)
|
65
|
+
'/' + ([method] + default_path_items + [URI.escape(value.to_s)]).join('/')
|
66
|
+
end
|
53
67
|
end
|
54
68
|
end
|
@@ -20,15 +20,14 @@ module TMDBParty
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def attribute(name, options)
|
23
|
-
options
|
24
|
-
raise "Name can't be empty" if name.blank?
|
25
|
-
|
26
|
-
class_eval <<-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
EOS
|
23
|
+
options = {:type => 'nil', :lazy => false}.merge(options)
|
24
|
+
raise ArgumentError, "Name can't be empty" if name.blank?
|
25
|
+
|
26
|
+
class_eval <<-EVAL
|
27
|
+
def #{name}
|
28
|
+
read_or_load_attribute('#{name}', #{options[:type]}, #{options[:lazy].inspect})
|
29
|
+
end
|
30
|
+
EVAL
|
32
31
|
end
|
33
32
|
|
34
33
|
end
|
@@ -43,10 +42,27 @@ module TMDBParty
|
|
43
42
|
end
|
44
43
|
|
45
44
|
private
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def read_or_load_attribute(name, type, lazy_method)
|
46
|
+
if lazy_method.is_a?(Symbol) and raw_attribute_missing?(name) and not loaded?
|
47
|
+
self.send(lazy_method)
|
48
|
+
end
|
49
|
+
read_attribute(name, type)
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_attribute(name, type = nil)
|
53
|
+
@attributes_cache ||= {}
|
54
|
+
@attributes_cache[name] ||= decode_raw_attribute(@attributes[name], type) if @attributes
|
55
|
+
end
|
56
|
+
|
57
|
+
def raw_attribute_missing?(name)
|
58
|
+
not @attributes.has_key?(name.to_s)
|
59
|
+
end
|
60
|
+
|
61
|
+
def decode_raw_attribute(value, type)
|
62
|
+
return nil unless value
|
63
|
+
type.respond_to?(:parse) ? type.parse(value) : value
|
64
|
+
end
|
65
|
+
|
50
66
|
end
|
51
67
|
end
|
52
68
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module TMDBParty
|
2
|
+
class CastMember
|
3
|
+
include Attributes
|
4
|
+
attr_reader :tmdb
|
5
|
+
attributes :name, :url, :job, :department
|
6
|
+
attributes :id, :type => Integer
|
7
|
+
|
8
|
+
def initialize(values, tmdb)
|
9
|
+
@tmdb = tmdb
|
10
|
+
self.attributes = values
|
11
|
+
end
|
12
|
+
|
13
|
+
def character_name
|
14
|
+
read_attribute('character')
|
15
|
+
end
|
16
|
+
|
17
|
+
def image_url
|
18
|
+
read_attribute('profile')
|
19
|
+
end
|
20
|
+
|
21
|
+
def person
|
22
|
+
tmdb.get_person(id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse(data, tmdb)
|
26
|
+
return unless data
|
27
|
+
if data.is_a?(Array)
|
28
|
+
data.collect do |person|
|
29
|
+
CastMember.new(person, tmdb)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
[CastMember.new(data, tmdb)]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TMDBParty
|
2
|
+
class Country
|
3
|
+
include Attributes
|
4
|
+
attributes :name, :code, :url
|
5
|
+
alias_method :code_string, :code
|
6
|
+
|
7
|
+
def self.parse(data)
|
8
|
+
return unless data
|
9
|
+
if data.is_a?(Array)
|
10
|
+
data.map { |row| Country.new(row) }
|
11
|
+
else
|
12
|
+
[Country.new(data)]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(attributes)
|
17
|
+
self.attributes = attributes
|
18
|
+
end
|
19
|
+
|
20
|
+
def code
|
21
|
+
code_string.downcase.to_sym
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/tmdb_party/image.rb
CHANGED
@@ -1,24 +1,49 @@
|
|
1
1
|
module TMDBParty
|
2
2
|
class Image
|
3
|
-
|
3
|
+
def initialize(attributes)
|
4
|
+
@attributes = attributes
|
5
|
+
end
|
4
6
|
|
5
|
-
def
|
6
|
-
@
|
7
|
-
@type = options["type"]
|
8
|
-
@size = options["size"]
|
7
|
+
def id
|
8
|
+
@attributes['id']
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
def type
|
12
|
+
@attributes['type'].downcase.to_sym
|
13
|
+
end
|
14
|
+
|
15
|
+
def sizes
|
16
|
+
@attributes['sizes'].map { |size| size.downcase.to_sym }.to_set
|
17
|
+
end
|
18
|
+
|
19
|
+
def url
|
20
|
+
original_url
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(*args, &block)
|
24
|
+
if args.first.to_s =~ /\A(.*)_url\Z/
|
25
|
+
@attributes["#{$1}_url"]
|
19
26
|
else
|
20
|
-
|
27
|
+
super
|
21
28
|
end
|
22
29
|
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def parse(data)
|
33
|
+
data.map { |row| row['image'] }.group_by { |row| row['id'] }.map do |id, images|
|
34
|
+
Image.new(reduce_images(images))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
def reduce_images(images)
|
40
|
+
images.inject({'sizes' => []}) do |image, row|
|
41
|
+
image["#{row['size']}_url"] = row.delete('url')
|
42
|
+
image['sizes'] << row.delete('size')
|
43
|
+
image.merge(row)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
23
48
|
end
|
24
49
|
end
|
data/lib/tmdb_party/movie.rb
CHANGED
@@ -3,20 +3,21 @@ module TMDBParty
|
|
3
3
|
include Attributes
|
4
4
|
attr_reader :tmdb
|
5
5
|
|
6
|
-
attributes :name, :overview, :id, :
|
6
|
+
attributes :name, :overview, :id, :imdb_id, :movie_type, :url, :alternative_title, :translated, :certification
|
7
7
|
attributes :released
|
8
|
-
attributes :id, :type => Integer
|
9
|
-
attributes :
|
8
|
+
attributes :id, :popularity, :type => Integer
|
9
|
+
attributes :score, :type => Float
|
10
10
|
|
11
|
-
attributes :
|
11
|
+
attributes :tagline, :lazy => :get_info!
|
12
|
+
attributes :posters, :backdrops, :lazy => :get_info!, :type => Image
|
12
13
|
attributes :homepage, :lazy => :get_info!
|
13
14
|
attributes :trailer, :lazy => :get_info!
|
14
15
|
attributes :runtime, :lazy => :get_info!, :type => Integer
|
15
16
|
attributes :genres, :lazy => :get_info!, :type => Genre
|
16
|
-
attributes :
|
17
|
+
attributes :countries, :lazy => :get_info!, :type => Country
|
18
|
+
attributes :studios, :lazy => :get_info!, :type => Studio
|
17
19
|
|
18
|
-
alias_method :
|
19
|
-
alias_method :flattened_backdrops, :backdrops
|
20
|
+
alias_method :translated?, :translated
|
20
21
|
|
21
22
|
def initialize(values, tmdb)
|
22
23
|
@tmdb = tmdb
|
@@ -29,45 +30,41 @@ module TMDBParty
|
|
29
30
|
@loaded = true
|
30
31
|
end
|
31
32
|
|
33
|
+
def cast
|
34
|
+
# TODO: This needs refactoring
|
35
|
+
CastMember.parse(read_or_load_attribute('cast', nil, :get_info!), tmdb)
|
36
|
+
end
|
37
|
+
|
38
|
+
def language
|
39
|
+
read_attribute('language').downcase.to_sym
|
40
|
+
end
|
41
|
+
|
42
|
+
def last_modified_at
|
43
|
+
# Date from TMDB is always in MST, but no timezone is present in date string
|
44
|
+
Time.parse(read_attribute('last_modified_at') + ' MST')
|
45
|
+
end
|
46
|
+
|
32
47
|
def directors
|
33
|
-
find_cast('
|
48
|
+
find_cast('Directing')
|
34
49
|
end
|
35
50
|
|
36
51
|
def actors
|
37
|
-
find_cast('
|
52
|
+
find_cast('Actors')
|
38
53
|
end
|
39
54
|
|
40
55
|
def writers
|
41
|
-
find_cast('
|
42
|
-
end
|
43
|
-
|
44
|
-
def posters
|
45
|
-
process_art(flattened_posters)
|
56
|
+
find_cast('Writing')
|
46
57
|
end
|
47
58
|
|
48
|
-
def
|
49
|
-
|
59
|
+
def producers
|
60
|
+
find_cast('Production')
|
50
61
|
end
|
51
62
|
|
52
|
-
|
53
63
|
private
|
54
64
|
|
55
|
-
def process_art(art)
|
56
|
-
image_groups = {}
|
57
|
-
art.each do |image_hash|
|
58
|
-
the_image = image_hash["image"]
|
59
|
-
if image_groups[the_image["id"]]
|
60
|
-
image_groups[the_image["id"]][the_image["size"]] = the_image["url"]
|
61
|
-
else
|
62
|
-
image_groups[the_image["id"]] = {the_image["size"] => the_image["url"]}
|
63
|
-
end
|
64
|
-
end
|
65
|
-
image_groups.values
|
66
|
-
end
|
67
|
-
|
68
65
|
def find_cast(type)
|
69
66
|
return [] unless cast
|
70
|
-
guys = cast.select{|c| c.
|
67
|
+
guys = cast.select{|c| c.department == type}
|
71
68
|
end
|
72
69
|
|
73
70
|
end
|
data/lib/tmdb_party/person.rb
CHANGED
@@ -1,21 +1,29 @@
|
|
1
1
|
module TMDBParty
|
2
2
|
class Person
|
3
3
|
include Attributes
|
4
|
-
|
4
|
+
attr_reader :tmdb
|
5
|
+
attributes :id, :popularity, :type => Integer
|
6
|
+
attributes :score, :type => Float
|
7
|
+
attributes :name, :url, :biography
|
5
8
|
|
6
|
-
|
9
|
+
attributes :birthplace, :birthday, :lazy => :get_info!
|
10
|
+
|
11
|
+
def initialize(values, tmdb)
|
12
|
+
@tmdb = tmdb
|
7
13
|
self.attributes = values
|
8
14
|
end
|
9
15
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def biography
|
17
|
+
# HTTParty does not parse the encoded hexadecimal properly. It does not consider 000F to be a hex, but 000f is
|
18
|
+
# A bug has been submitted about this
|
19
|
+
read_attribute('biography').gsub("\\n", "\n").gsub(/\\u([0-9A-F]{4})/) { [$1.hex].pack("U") }
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def get_info!
|
24
|
+
person = tmdb.get_person(self.id)
|
25
|
+
@attributes.merge!(person.attributes) if person
|
26
|
+
@loaded = true
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|