royw-tmdb 0.0.1
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/LICENSE +22 -0
- data/README.rdoc +9 -0
- data/Rakefile +48 -0
- data/VERSION.yml +4 -0
- data/lib/file_extensions.rb +14 -0
- data/lib/object_extensions.rb +19 -0
- data/lib/string_extensions.rb +16 -0
- data/lib/tmdb.rb +11 -0
- data/lib/tmdb/optional_logger.rb +31 -0
- data/lib/tmdb/tmdb_movie.rb +136 -0
- data/lib/tmdb/tmdb_profile.rb +112 -0
- data/spec/cache_extensions.rb +91 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/tmdb_movie_spec.rb +74 -0
- data/spec/tmdb_profile_spec.rb +140 -0
- metadata +71 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2009 Roy Wright
|
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 NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "tmdb"
|
8
|
+
gem.summary = %Q{TODO}
|
9
|
+
gem.email = "roy@wright.org"
|
10
|
+
gem.homepage = "http://github.com/royw/tmdb"
|
11
|
+
gem.authors = ["Roy Wright"]
|
12
|
+
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'spec/rake/spectask'
|
20
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
21
|
+
spec.libs << 'lib' << 'spec'
|
22
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
28
|
+
spec.rcov = true
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task :default => :spec
|
33
|
+
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
if File.exist?('VERSION.yml')
|
37
|
+
config = YAML.load(File.read('VERSION.yml'))
|
38
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
39
|
+
else
|
40
|
+
version = ""
|
41
|
+
end
|
42
|
+
|
43
|
+
rdoc.rdoc_dir = 'rdoc'
|
44
|
+
rdoc.title = "tmdb #{version}"
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
48
|
+
|
data/VERSION.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# == Synopsis
|
2
|
+
# add a mkdirs method to the File class
|
3
|
+
class File
|
4
|
+
##
|
5
|
+
# make directories including any missing in the path
|
6
|
+
#
|
7
|
+
# @param [String] dirspec the path to make sure exists
|
8
|
+
def File.mkdirs(dirspec)
|
9
|
+
unless File.exists?(dirspec)
|
10
|
+
mkdirs(File.dirname(dirspec))
|
11
|
+
Dir.mkdir(dirspec)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# == Synopsis
|
2
|
+
# add a blank? method to all Objects
|
3
|
+
class Object
|
4
|
+
# return asserted if object is nil or empty
|
5
|
+
# TODO: not the safest coding, probably should dup before stripping. Maybe should also compact
|
6
|
+
def blank?
|
7
|
+
result = nil?
|
8
|
+
unless result
|
9
|
+
if respond_to? 'empty?'
|
10
|
+
if respond_to? 'strip'
|
11
|
+
result = strip.empty?
|
12
|
+
else
|
13
|
+
result = empty?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
result
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'iconv'
|
3
|
+
|
4
|
+
module ImdbStringExtensions
|
5
|
+
|
6
|
+
def unescape_html
|
7
|
+
Iconv.conv("UTF-8", 'ISO-8859-1', CGI::unescapeHTML(self))
|
8
|
+
end
|
9
|
+
|
10
|
+
def strip_tags
|
11
|
+
gsub(/<\/?[^>]*>/, "")
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
String.send :include, ImdbStringExtensions
|
data/lib/tmdb.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'date'
|
4
|
+
require 'xmlsimple'
|
5
|
+
|
6
|
+
require File.dirname(__FILE__) + '/tmdb/optional_logger'
|
7
|
+
require File.dirname(__FILE__) + '/tmdb/tmdb_movie'
|
8
|
+
require File.dirname(__FILE__) + '/tmdb/tmdb_profile'
|
9
|
+
require File.dirname(__FILE__) + '/string_extensions'
|
10
|
+
require File.dirname(__FILE__) + '/file_extensions'
|
11
|
+
require File.dirname(__FILE__) + '/object_extensions'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# An optional logger.
|
2
|
+
# If initialized with a logger instance, uses the logger
|
3
|
+
# otherwise doesn't do anything.
|
4
|
+
# Basically trying to not require a particular logger class.
|
5
|
+
class OptionalLogger
|
6
|
+
# logger may be nil or a logger instance
|
7
|
+
def initialize(logger)
|
8
|
+
@logger = logger
|
9
|
+
end
|
10
|
+
|
11
|
+
# debug {...}
|
12
|
+
def debug(&blk)
|
13
|
+
@logger.debug(blk.call) unless @logger.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
# info {...}
|
17
|
+
def info(&blk)
|
18
|
+
@logger.info(blk.call) unless @logger.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
# warn {...}
|
22
|
+
def warn(&blk)
|
23
|
+
@logger.warn(blk.call) unless @logger.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
# error {...}
|
27
|
+
def error(&blk)
|
28
|
+
@logger.error(blk.call) unless @logger.nil?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,136 @@
|
|
1
|
+
class TmdbMovie
|
2
|
+
|
3
|
+
attr_reader :query, :document
|
4
|
+
|
5
|
+
API_KEY = '7a2f6eb9b6aa01651000f0a9324db835'
|
6
|
+
|
7
|
+
def initialize(ident)
|
8
|
+
@imdb_id = 'tt' + ident.gsub(/^tt/, '') unless ident.blank?
|
9
|
+
@query = "http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=#{@imdb_id}&api_key=#{API_KEY}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def fanarts
|
13
|
+
result = []
|
14
|
+
begin
|
15
|
+
document['moviematches'].each do |moviematches|
|
16
|
+
moviematches['movie'].each do |movie|
|
17
|
+
backdrop = movie['backdrop']
|
18
|
+
unless backdrop.blank?
|
19
|
+
result += backdrop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
rescue
|
24
|
+
end
|
25
|
+
result
|
26
|
+
end
|
27
|
+
|
28
|
+
def posters
|
29
|
+
result = []
|
30
|
+
begin
|
31
|
+
document['moviematches'].each do |moviematches|
|
32
|
+
moviematches['movie'].each do |movie|
|
33
|
+
result += movie['poster']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
rescue
|
37
|
+
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
def idents
|
42
|
+
document['moviematches'].first['movie'].first['id'] rescue nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def urls
|
46
|
+
document['moviematches'].first['movie'].first['url'] rescue nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def imdb_ids
|
50
|
+
document['moviematches'].first['movie'].first['imdb'] rescue nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def titles
|
54
|
+
document['moviematches'].first['movie'].first['title'] rescue nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def short_overviews
|
58
|
+
document['moviematches'].first['movie'].first['short_overview'] rescue nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def types
|
62
|
+
document['moviematches'].first['movie'].first['type'] rescue nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def alternative_titles
|
66
|
+
document['moviematches'].first['movie'].first['alternative_title'] rescue nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def releases
|
70
|
+
document['moviematches'].first['movie'].first['release'] rescue nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def scores
|
74
|
+
document['moviematches'].first['movie'].first['score'] rescue nil
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_hash
|
78
|
+
hash = {}
|
79
|
+
[:fanarts, :posters, :idents, :urls, :imdb_ids, :titles, :short_overviews,
|
80
|
+
:types, :alternative_titles, :releases, :scores
|
81
|
+
].each do |sym|
|
82
|
+
begin
|
83
|
+
value = send(sym.to_s)
|
84
|
+
hash[sym.to_s] = value unless value.nil?
|
85
|
+
rescue Exception => e
|
86
|
+
puts "Error getting data for hash for #{sym} - #{e.to_s}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
hash
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_xml
|
93
|
+
XmlSimple.xml_out(document, 'NoAttr' => true, 'RootName' => 'movie')
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_yaml
|
97
|
+
YAML.dump(document)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
# Fetch the document with retry to handle the occasional glitches
|
103
|
+
def document
|
104
|
+
if @document.nil?
|
105
|
+
html = fetch(self.query)
|
106
|
+
@document = XmlSimple.xml_in(html)
|
107
|
+
@document = nil if @document['totalResults'] == ['0']
|
108
|
+
end
|
109
|
+
@document
|
110
|
+
end
|
111
|
+
|
112
|
+
MAX_ATTEMPTS = 3
|
113
|
+
SECONDS_BETWEEN_RETRIES = 1.0
|
114
|
+
|
115
|
+
def fetch(page)
|
116
|
+
doc = nil
|
117
|
+
attempts = 0
|
118
|
+
begin
|
119
|
+
doc = read_page(page)
|
120
|
+
rescue Exception => e
|
121
|
+
attempts += 1
|
122
|
+
if attempts > MAX_ATTEMPTS
|
123
|
+
raise
|
124
|
+
else
|
125
|
+
sleep SECONDS_BETWEEN_RETRIES
|
126
|
+
retry
|
127
|
+
end
|
128
|
+
end
|
129
|
+
doc
|
130
|
+
end
|
131
|
+
|
132
|
+
def read_page(page)
|
133
|
+
open(page).read
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# This is the model for the themovieDb profile which is used
|
2
|
+
# to find TmdbMovie meta data from either online or from
|
3
|
+
# a cached file.
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
#
|
7
|
+
# profile = TmdbProfile.first(:imdb_id => 'tt0123456')
|
8
|
+
#
|
9
|
+
# puts profile.movie['key'].first
|
10
|
+
# puts profile.to_xml
|
11
|
+
# puts profile.imdb_id
|
12
|
+
#
|
13
|
+
class TmdbProfile
|
14
|
+
|
15
|
+
# options:
|
16
|
+
# :imdb_id => String (either with or without leading 'tt')
|
17
|
+
# :filespec => nil or a valid pathspec
|
18
|
+
# :logger => nil or a logger instance
|
19
|
+
def self.all(options={})
|
20
|
+
result = []
|
21
|
+
if has_option?(options, :imdb_id) || (has_option?(options, :filespec) && File.exist?(options[:filespec]))
|
22
|
+
result << TmdbProfile.new(options[:imdb_id], options[:filespec], options[:logger])
|
23
|
+
end
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
# see TmdbProfile.all for description of options
|
28
|
+
def self.first(options={})
|
29
|
+
self.all(options).first
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def self.has_option?(options, key)
|
35
|
+
options.has_key?(key) && !options[key].blank?
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(ident, filespec, logger)
|
39
|
+
@imdb_id = ident
|
40
|
+
@filespec = filespec
|
41
|
+
@logger = OptionalLogger.new(logger)
|
42
|
+
load
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
public
|
47
|
+
|
48
|
+
attr_reader :imdb_id, :movie
|
49
|
+
|
50
|
+
def to_xml
|
51
|
+
xml = ''
|
52
|
+
unless @movie.blank?
|
53
|
+
@movie.delete_if { |key, value| value.nil? }
|
54
|
+
xml = XmlSimple.xml_out(@movie, 'NoAttr' => true, 'RootName' => 'movie')
|
55
|
+
end
|
56
|
+
xml
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def load
|
62
|
+
@movie = nil
|
63
|
+
if !@filespec.blank? && File.exist?(@filespec)
|
64
|
+
@logger.debug { "loading movie filespec=> #{@filespec.inspect}" }
|
65
|
+
@movie = from_xml(open(@filespec).read)
|
66
|
+
elsif !@imdb_id.blank?
|
67
|
+
@logger.debug { "loading movie from tmdb.com, filespec=> #{@filespec.inspect}" }
|
68
|
+
@movie = TmdbMovie.new(@imdb_id.gsub(/^tt/, '')).to_hash
|
69
|
+
save(@filespec) unless @filespec.blank?
|
70
|
+
end
|
71
|
+
unless @movie.blank?
|
72
|
+
@imdb_id = @movie['imdb_ids']
|
73
|
+
@imdb_id = @imdb_id.first if @imdb_id.respond_to?('[]') && @imdb_id.length == 1
|
74
|
+
else
|
75
|
+
@movie = nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def from_xml(xml)
|
80
|
+
begin
|
81
|
+
movie = XmlSimple.xml_in(xml)
|
82
|
+
rescue Exception => e
|
83
|
+
@logger.warn { "Error converting from xml: #{e.to_s}" }
|
84
|
+
movie = nil
|
85
|
+
end
|
86
|
+
movie
|
87
|
+
end
|
88
|
+
|
89
|
+
def save(filespec)
|
90
|
+
begin
|
91
|
+
xml = self.to_xml
|
92
|
+
unless xml.blank?
|
93
|
+
@logger.debug { "saving #{filespec}" }
|
94
|
+
save_to_file(filespec, xml)
|
95
|
+
end
|
96
|
+
rescue Exception => e
|
97
|
+
@logger.error { "Unable to save tmdb profile to #{filespec} - #{e.to_s}" }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def save_to_file(filespec, data)
|
102
|
+
new_filespec = filespec + '.new'
|
103
|
+
File.open(new_filespec, "w") do |file|
|
104
|
+
file.puts(data)
|
105
|
+
end
|
106
|
+
backup_filespec = filespec + '~'
|
107
|
+
File.delete(backup_filespec) if File.exist?(backup_filespec)
|
108
|
+
File.rename(filespec, backup_filespec) if File.exist?(filespec)
|
109
|
+
File.rename(new_filespec, filespec)
|
110
|
+
File.delete(new_filespec) if File.exist?(new_filespec)
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# NOTE extremely ugly and non-DRY. Probably good candidate for meta programming.
|
2
|
+
|
3
|
+
# override the classes' read_page method and replace with one
|
4
|
+
# that will cache pages in spec/samples/{url}
|
5
|
+
|
6
|
+
class ImdbMovie
|
7
|
+
private
|
8
|
+
def read_page(page)
|
9
|
+
html = nil
|
10
|
+
filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
|
11
|
+
if File.exist?(filespec)
|
12
|
+
html = open(filespec).read
|
13
|
+
else
|
14
|
+
html = open(page).read
|
15
|
+
cache_html_files(page, html)
|
16
|
+
end
|
17
|
+
html
|
18
|
+
end
|
19
|
+
|
20
|
+
# this is used to save imdb pages so they may be used by rspec
|
21
|
+
def cache_html_files(page, html)
|
22
|
+
begin
|
23
|
+
filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
|
24
|
+
unless File.exist?(filespec)
|
25
|
+
puts "caching #{filespec}"
|
26
|
+
File.mkdirs(File.dirname(filespec))
|
27
|
+
File.open(filespec, 'w') { |f| f.puts html }
|
28
|
+
end
|
29
|
+
rescue Exception => eMsg
|
30
|
+
puts eMsg.to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class ImdbSearch
|
36
|
+
private
|
37
|
+
def read_page(page)
|
38
|
+
html = nil
|
39
|
+
filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
|
40
|
+
if File.exist?(filespec)
|
41
|
+
html = open(filespec).read
|
42
|
+
else
|
43
|
+
html = open(page).read
|
44
|
+
cache_html_files(page, html)
|
45
|
+
end
|
46
|
+
html
|
47
|
+
end
|
48
|
+
|
49
|
+
# this is used to save imdb pages so they may be used by rspec
|
50
|
+
def cache_html_files(page, html)
|
51
|
+
begin
|
52
|
+
filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
|
53
|
+
unless File.exist?(filespec)
|
54
|
+
puts "caching #{filespec}"
|
55
|
+
File.mkdirs(File.dirname(filespec))
|
56
|
+
File.open(filespec, 'w') { |f| f.puts html }
|
57
|
+
end
|
58
|
+
rescue Exception => eMsg
|
59
|
+
puts eMsg.to_s
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class ImdbImage
|
65
|
+
private
|
66
|
+
def read_page(page)
|
67
|
+
html = nil
|
68
|
+
filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
|
69
|
+
if File.exist?(filespec)
|
70
|
+
html = open(filespec).read
|
71
|
+
else
|
72
|
+
html = open(page).read
|
73
|
+
cache_html_files(page, html)
|
74
|
+
end
|
75
|
+
html
|
76
|
+
end
|
77
|
+
|
78
|
+
# this is used to save imdb pages so they may be used by rspec
|
79
|
+
def cache_html_files(page, html)
|
80
|
+
begin
|
81
|
+
filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
|
82
|
+
unless File.exist?(filespec)
|
83
|
+
puts "caching #{filespec}"
|
84
|
+
File.mkdirs(File.dirname(filespec))
|
85
|
+
File.open(filespec, 'w') { |f| f.puts html }
|
86
|
+
end
|
87
|
+
rescue Exception => eMsg
|
88
|
+
puts eMsg.to_s
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
require 'tmdb'
|
6
|
+
|
7
|
+
require 'cache_extensions'
|
8
|
+
|
9
|
+
$samples_dir = File.dirname(__FILE__) + '/samples'
|
10
|
+
|
11
|
+
TMPDIR = File.join(File.dirname(__FILE__), '../tmp')
|
12
|
+
|
13
|
+
Spec::Runner.configure do |config|
|
14
|
+
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Time to add your specs!
|
4
|
+
# http://rspec.info/
|
5
|
+
|
6
|
+
describe "TmdbMovie" do
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
File.mkdirs(TMPDIR)
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@profile = TmdbMovie.new('tt0465234')
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:each) do
|
17
|
+
Dir.glob(File.join(TMPDIR,'tmdb_movie_spec*')).each { |filename| File.delete(filename) }
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should find by imdb_id" do
|
21
|
+
@profile.should_not == nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should find tmdb id" do
|
25
|
+
@profile.idents.first.should == '6637'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should find fanarts" do
|
29
|
+
@profile.fanarts.size.should == 3
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should find posters" do
|
33
|
+
@profile.posters.size.should == 4
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should find the tmdb url" do
|
37
|
+
@profile.urls.first.should == 'http://www.themoviedb.org/movie/6637'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should find the imdb_id" do
|
41
|
+
@profile.imdb_ids.first.should == 'tt0465234'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should find the title" do
|
45
|
+
@profile.titles.first.should == 'National Treasure: Book of Secrets'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should find the short_overview" do
|
49
|
+
@profile.short_overviews.first.should =~ /Benjamin Franklin Gates/
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should find the type" do
|
53
|
+
@profile.types.first.should == 'movie'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should find the alternative_titles" do
|
57
|
+
@profile.alternative_titles.first.should == 'National Treasure 2'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should find the release" do
|
61
|
+
@profile.releases.first.should == '2007-12-13'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should find the score" do
|
65
|
+
@profile.scores.first.should == '1.0'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should handle The Sand Pebble" do
|
69
|
+
profile = TmdbMovie.new('tt0060934')
|
70
|
+
profile.idents.should be_nil
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
# Time to add your specs!
|
5
|
+
# http://rspec.info/
|
6
|
+
|
7
|
+
describe "TmdbProfile" do
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
File.mkdirs(TMPDIR)
|
11
|
+
end
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
# tt0465234 => National Treasure: Book of Secrets
|
15
|
+
@profile = TmdbProfile.first(:imdb_id => 'tt0465234')
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
Dir.glob(File.join(TMPDIR,'tmdb_profile_spec*')).each { |filename| File.delete(filename) }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should find by imdb_id" do
|
23
|
+
@profile.should_not == nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should save the profile to a file" do
|
27
|
+
filespec = get_temp_filename
|
28
|
+
profile = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => filespec)
|
29
|
+
(File.exist?(filespec).should be_true) && (File.size(filespec).should > 0)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be able to convert to xml" do
|
33
|
+
xml = @profile.to_xml
|
34
|
+
(xml.should_not be_nil) && (xml.length.should > 0)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should be able to convert to xml and then from xml" do
|
38
|
+
hash = nil
|
39
|
+
begin
|
40
|
+
xml = @profile.to_xml
|
41
|
+
hash = XmlSimple.xml_in(xml)
|
42
|
+
rescue
|
43
|
+
hash = nil
|
44
|
+
end
|
45
|
+
hash.should_not be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should find tmdb id" do
|
49
|
+
@profile.movie['idents'].first.should == '6637'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should find fanarts" do
|
53
|
+
@profile.movie['fanarts'].size.should == 3
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should find posters" do
|
57
|
+
@profile.movie['posters'].size.should == 4
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should find the tmdb url" do
|
61
|
+
@profile.movie['urls'].first.should == 'http://www.themoviedb.org/movie/6637'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should find the imdb_id" do
|
65
|
+
@profile.movie['imdb_ids'].first.should == 'tt0465234'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should find the title" do
|
69
|
+
@profile.movie['titles'].first.should == 'National Treasure: Book of Secrets'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should find the short_overview" do
|
73
|
+
@profile.movie['short_overviews'].first.should =~ /Benjamin Franklin Gates/
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should find the type" do
|
77
|
+
@profile.movie['types'].first.should == 'movie'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should find the alternative_titles" do
|
81
|
+
@profile.movie['alternative_titles'].first.should == 'National Treasure 2'
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should find the release" do
|
85
|
+
@profile.movie['releases'].first.should == '2007-12-13'
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should find the score" do
|
89
|
+
@profile.movie['scores'].first.should == '1.0'
|
90
|
+
end
|
91
|
+
|
92
|
+
# let's make sure the generated xml from to_xml() is valid
|
93
|
+
|
94
|
+
it "should be able to convert to xml and then from xml" do
|
95
|
+
hash = nil
|
96
|
+
begin
|
97
|
+
profile = TmdbProfile.first(:imdb_id => 'tt0465234')
|
98
|
+
xml = profile.to_xml
|
99
|
+
hash = XmlSimple.xml_in(xml)
|
100
|
+
rescue
|
101
|
+
hash = nil
|
102
|
+
end
|
103
|
+
hash.should_not be_nil
|
104
|
+
end
|
105
|
+
|
106
|
+
# now let's test caching the profile to/from a file
|
107
|
+
|
108
|
+
it "should not create a file if a :filespec option is passed that is nil" do
|
109
|
+
profile = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => nil)
|
110
|
+
Dir.glob(File.join(TMPDIR, "imdb_profile_spec*")).empty?.should be_true
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should create a file if a :filespec option is passed" do
|
114
|
+
filespec = get_temp_filename
|
115
|
+
profile = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => filespec)
|
116
|
+
(File.exist?(filespec) && (File.size(filespec) > 0)).should be_true
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should load from a file if a :filespec option is passed and the file exists" do
|
120
|
+
filespec = get_temp_filename
|
121
|
+
profile1 = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => filespec)
|
122
|
+
profile2 = TmdbProfile.first(:filespec => filespec)
|
123
|
+
profile1.imdb_id.should == profile2.imdb_id
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not load from a file if a :filespec option is passed and the file does not exists" do
|
127
|
+
filespec = get_temp_filename
|
128
|
+
profile = TmdbProfile.first(:filespec => filespec)
|
129
|
+
profile.should be_nil
|
130
|
+
end
|
131
|
+
|
132
|
+
def get_temp_filename
|
133
|
+
outfile = Tempfile.new('tmdb_profile_spec', TMPDIR)
|
134
|
+
filespec = outfile.path
|
135
|
+
outfile.unlink
|
136
|
+
filespec
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: royw-tmdb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roy Wright
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-15 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: roy@wright.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- LICENSE
|
27
|
+
- README.rdoc
|
28
|
+
- Rakefile
|
29
|
+
- VERSION.yml
|
30
|
+
- lib/file_extensions.rb
|
31
|
+
- lib/object_extensions.rb
|
32
|
+
- lib/string_extensions.rb
|
33
|
+
- lib/tmdb.rb
|
34
|
+
- lib/tmdb/optional_logger.rb
|
35
|
+
- lib/tmdb/tmdb_movie.rb
|
36
|
+
- lib/tmdb/tmdb_profile.rb
|
37
|
+
- spec/cache_extensions.rb
|
38
|
+
- spec/spec_helper.rb
|
39
|
+
- spec/tmdb_movie_spec.rb
|
40
|
+
- spec/tmdb_profile_spec.rb
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/royw/tmdb
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.2.0
|
64
|
+
signing_key:
|
65
|
+
specification_version: 2
|
66
|
+
summary: TODO
|
67
|
+
test_files:
|
68
|
+
- spec/cache_extensions.rb
|
69
|
+
- spec/tmdb_profile_spec.rb
|
70
|
+
- spec/spec_helper.rb
|
71
|
+
- spec/tmdb_movie_spec.rb
|