tvdb 0.0.2
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 +21 -0
- data/LICENSE +20 -0
- data/README.markdown +14 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/lib/tvdb.rb +14 -0
- data/lib/tvdb/client.rb +65 -0
- data/lib/tvdb/element.rb +40 -0
- data/lib/tvdb/serie.rb +16 -0
- data/lib/tvdb/urls.rb +40 -0
- data/spec/data/serie1.xml +26 -0
- data/spec/data/serie1.zip +0 -0
- data/spec/data/serie2.xml +26 -0
- data/spec/data/serie2.zip +0 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/tvdb/client_spec.rb +133 -0
- data/spec/tvdb/element_spec.rb +49 -0
- data/spec/tvdb/serie_spec.rb +39 -0
- data/spec/tvdb/urls_spec.rb +50 -0
- data/tvdb.gemspec +74 -0
- metadata +128 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Álvaro Bautista
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# tvdb
|
2
|
+
|
3
|
+
Ruby wrapper for accessing TV shows information from the [TheTVDB](http://www.thetvdb.com) API.
|
4
|
+
|
5
|
+
## Example
|
6
|
+
|
7
|
+
require 'tvdb'
|
8
|
+
client = TVdb::Client.new('my_api_key')
|
9
|
+
results = client.search('The Big Bang Theory')
|
10
|
+
client.serie_in_language(results.first, 'fr')
|
11
|
+
|
12
|
+
## Copyright
|
13
|
+
|
14
|
+
Copyright (c) 2009 Álvaro Bautista, released under MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "tvdb"
|
8
|
+
gem.summary = %Q{Ruby wrapper for TheTVDB}
|
9
|
+
gem.description = %Q{Ruby wrapper for accessing TV shows information from the TheTVDB API}
|
10
|
+
gem.email = "alvarobp@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/alvarobp/tvdb"
|
12
|
+
gem.authors = ["Álvaro Bautista"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
gem.add_dependency "hpricot", ">= 0.8.1"
|
15
|
+
gem.add_dependency "rubyzip", ">= 0.9.1"
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
32
|
+
end
|
33
|
+
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "tvdb #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/lib/tvdb.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'hpricot'
|
4
|
+
require 'zip/zip'
|
5
|
+
|
6
|
+
# OpenURI by default returns StringIO objects for responses up to 10K
|
7
|
+
# and creates temporary files for greater responses, so we force it to
|
8
|
+
# always create temporary files since ZipFile only accepts filenames
|
9
|
+
OpenURI::Buffer::StringMax = 0
|
10
|
+
|
11
|
+
require File.dirname(__FILE__) + '/tvdb/urls'
|
12
|
+
require File.dirname(__FILE__) + '/tvdb/client'
|
13
|
+
require File.dirname(__FILE__) + '/tvdb/element'
|
14
|
+
require File.dirname(__FILE__) + '/tvdb/serie'
|
data/lib/tvdb/client.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module TVdb
|
2
|
+
class Client
|
3
|
+
attr_reader :api_key, :urls
|
4
|
+
|
5
|
+
def initialize(api_key)
|
6
|
+
@api_key = api_key
|
7
|
+
@urls = Urls.new(api_key)
|
8
|
+
end
|
9
|
+
|
10
|
+
def search(name, options={})
|
11
|
+
default_options = {:lang => 'en', :match_mode => :all}
|
12
|
+
options = default_options.merge(options)
|
13
|
+
|
14
|
+
search_url = @urls[:get_series] % {:name => URI.escape(name), :language => options[:lang]}
|
15
|
+
|
16
|
+
doc = Hpricot(OpenURI.open_uri(search_url).read)
|
17
|
+
|
18
|
+
ids = if options[:match_mode] == :exact
|
19
|
+
doc.search('series').select{|s| s.search('seriesname').inner_text == name }.collect{|e| e.search('id')}.map(&:inner_text)
|
20
|
+
else
|
21
|
+
doc.search('series').search('id').map(&:inner_text)
|
22
|
+
end
|
23
|
+
|
24
|
+
ids.map do |sid|
|
25
|
+
get_serie_from_zip(sid, options[:lang])
|
26
|
+
end.compact
|
27
|
+
end
|
28
|
+
|
29
|
+
def serie_in_language(serie, lang)
|
30
|
+
return nil if !serie.respond_to?(:tvdb_id)
|
31
|
+
return serie if lang == serie.language
|
32
|
+
|
33
|
+
get_serie_from_zip(serie.tvdb_id, lang)
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_serie_zip(id, lang='en')
|
37
|
+
zip_file = open_or_rescue(@urls[:serie_zip] % {:serie_id => id, :language => lang})
|
38
|
+
zip_file.nil? ? nil : Zip::ZipFile.new(zip_file.path)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def open_or_rescue(url)
|
44
|
+
begin
|
45
|
+
return OpenURI.open_uri(url)
|
46
|
+
rescue OpenURI::HTTPError # 404 errors for some of the ids returned in search
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_serie_from_zip(sid, lang='en')
|
52
|
+
zip = get_serie_zip(sid, lang)
|
53
|
+
return nil if zip.nil?
|
54
|
+
|
55
|
+
xml = read_serie_xml_from_zip(zip, lang)
|
56
|
+
return xml ? Serie.new(xml) : nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def read_serie_xml_from_zip(zip, lang='en')
|
60
|
+
if entry = zip.find_entry("#{lang}.xml")
|
61
|
+
entry.get_input_stream.read
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/tvdb/element.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module TVdb
|
2
|
+
class Element < OpenStruct
|
3
|
+
def initialize(xml, root_name=nil)
|
4
|
+
@root_name = root_name
|
5
|
+
|
6
|
+
atts = attributes_from_xml(xml)
|
7
|
+
|
8
|
+
# Downcase the keys
|
9
|
+
atts = atts.inject({}){|options, (k,v)| options[k.downcase] = v; options}
|
10
|
+
|
11
|
+
# Don't mess with Object.id
|
12
|
+
if atts.has_key?('id')
|
13
|
+
sid = atts.delete('id')
|
14
|
+
atts[:tvdb_id] = sid
|
15
|
+
end
|
16
|
+
|
17
|
+
yield(atts) if block_given?
|
18
|
+
|
19
|
+
super(atts)
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def attributes_from_xml(xml)
|
25
|
+
return {} if xml.nil? || xml.empty?
|
26
|
+
doc = Hpricot(xml)
|
27
|
+
|
28
|
+
attributes = {}
|
29
|
+
|
30
|
+
element_root = @root_name.nil? ? doc.root : doc.search(@root_name).first
|
31
|
+
|
32
|
+
element_root.children.map do |child|
|
33
|
+
unless child.is_a?(Hpricot::Text)
|
34
|
+
attributes[child.name] = child.inner_text
|
35
|
+
end
|
36
|
+
end
|
37
|
+
attributes
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/tvdb/serie.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module TVdb
|
2
|
+
class Serie < Element
|
3
|
+
def initialize(xml)
|
4
|
+
super(xml, 'series') do |atts|
|
5
|
+
# Turn into arrays
|
6
|
+
atts["actors"] = atts["actors"].split('|').select{|a| !a.nil? && !a.empty?} if atts["actors"] && atts["actors"].is_a?(String) && !atts["actors"].empty?
|
7
|
+
genres = atts.delete("genre")
|
8
|
+
atts["genres"] = genres.split('|').select{|a| !a.nil? && !a.empty?} if genres && genres.is_a?(String) && !genres.empty?
|
9
|
+
|
10
|
+
atts["poster"] = BANNER_URL % atts["poster"] unless atts["poster"].nil?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
BANNER_URL = "http://www.thetvdb.com/banners/_cache/%s"
|
16
|
+
end
|
data/lib/tvdb/urls.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module TVdb
|
2
|
+
class Urls
|
3
|
+
BASE_URL = "http://www.thetvdb.com"
|
4
|
+
URLS = {
|
5
|
+
:get_series => "%s/api/GetSeries.php?seriesname={{name}}&language={{language}}",
|
6
|
+
:serie_xml => "%s/api/%s/series/{{serie_id}}/{{language}}.xml",
|
7
|
+
:serie_full_xml => "%s/api/%s/series/{{serie_id}}/all/{{language}}.xml",
|
8
|
+
:serie_banners_xml => "%s/api/%s/series/{{serie_id}}/banners.xml",
|
9
|
+
:serie_zip => "%s/api/%s/series/{{serie_id}}/all/{{language}}.zip",
|
10
|
+
:episode_xml => "%s/api/%s/episodes/{{episode_id}}/{{language}}.xml"
|
11
|
+
}
|
12
|
+
|
13
|
+
attr_reader :api_key, :templates
|
14
|
+
|
15
|
+
def initialize(api_key, base_url=BASE_URL)
|
16
|
+
@api_key = api_key
|
17
|
+
@templates = URLS.inject({}){|object, (k,v)| object[k] = Template.new(v % [base_url, @api_key]); object}
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](key)
|
21
|
+
@templates[key]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Template
|
26
|
+
attr_reader :template
|
27
|
+
|
28
|
+
def initialize(template)
|
29
|
+
@template = template
|
30
|
+
end
|
31
|
+
|
32
|
+
def %(values)
|
33
|
+
@template.gsub(/\{\{(.*?)\}\}/ ){
|
34
|
+
value = values[$1] || values[$1.to_sym]
|
35
|
+
raise "Value for #{$1} not found" if value.nil?
|
36
|
+
value.to_s
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<Series>
|
2
|
+
<id>80379</id>
|
3
|
+
<Actors>|Johnny Galecki|Kaley Cuoco|Jim Parsons|Sara Gilbert|Kunal Nayyar|Simon Helberg|</Actors>
|
4
|
+
<Airs_DayOfWeek>Monday</Airs_DayOfWeek>
|
5
|
+
<Airs_Time>9:30 PM</Airs_Time>
|
6
|
+
<ContentRating>TV-PG</ContentRating>
|
7
|
+
<FirstAired>2007-09-01</FirstAired>
|
8
|
+
<Genre>|Comedy|</Genre>
|
9
|
+
<IMDB_ID>tt0898266</IMDB_ID>
|
10
|
+
<Language>en</Language>
|
11
|
+
<Network>CBS</Network>
|
12
|
+
<NetworkID></NetworkID>
|
13
|
+
<Overview>A woman who moves into an apartment next door to two brilliant but socially awkward physicists shows them how little they know about life outside of the laboratory</Overview>
|
14
|
+
<Rating>8.9</Rating>
|
15
|
+
<Runtime>30</Runtime>
|
16
|
+
<SeriesID>58056</SeriesID>
|
17
|
+
<SeriesName>The Big Bang Theory</SeriesName>
|
18
|
+
<Status>Continuing</Status>
|
19
|
+
<added></added>
|
20
|
+
<addedBy></addedBy>
|
21
|
+
<banner>graphical/80379-g5.jpg</banner>
|
22
|
+
<fanart>fanart/original/80379-2.jpg</fanart>
|
23
|
+
<lastupdated>1258740481</lastupdated>
|
24
|
+
<poster>posters/80379-1.jpg</poster>
|
25
|
+
<zap2it_id>SH931182</zap2it_id>
|
26
|
+
</Series>
|
Binary file
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<Series>
|
2
|
+
<id>73739</id>
|
3
|
+
<Actors>|Matthew Fox|Evangeline Lilly|Naveen Andrews|Terry O'Quinn|Daniel Dae Kim|Yunjin Kim|Josh Holloway|John Terry|Andrew Divoff|Sam Anderson|L. Scott Caldwell|Nestor Carbonell|Kevin Durand|Jeff Fahey|Tania Raymonde|Mira Furlan|Alan Dale|Sonya Walger|Rebecca Mader|Ken Leung|Jeremy Davies|Elizabeth Mitchell|Kiele Sanchez|Rodrigo Santoro|Cynthia Watros|Adewale Akinnuoye-Agbaje|Henry Ian Cusick|Michael Emerson|Michelle Rodriguez|Dominic Monaghan|Emilie de Ravin|Harold Perrineau Jr.|Ian Somerhalder|Maggie Grace|Jorge Garcia|Malcolm David Kelley|M.C. Gainey|Zuleikha Robinson|</Actors>
|
4
|
+
<Airs_DayOfWeek>Wednesday</Airs_DayOfWeek>
|
5
|
+
<Airs_Time>9:00 PM</Airs_Time>
|
6
|
+
<ContentRating>TV-14</ContentRating>
|
7
|
+
<FirstAired>2004-09-22</FirstAired>
|
8
|
+
<Genre>|Action and Adventure|Drama|Science-Fiction|</Genre>
|
9
|
+
<IMDB_ID>tt0411008</IMDB_ID>
|
10
|
+
<Language>en</Language>
|
11
|
+
<Network>ABC</Network>
|
12
|
+
<NetworkID></NetworkID>
|
13
|
+
<Overview>After their plane, Oceanic Air flight 815, tore apart whilst thousands of miles off course, the survivors find themselves on a mysterious deserted island where they soon find out they are not alone.</Overview>
|
14
|
+
<Rating>9.1</Rating>
|
15
|
+
<Runtime>60</Runtime>
|
16
|
+
<SeriesID>24313</SeriesID>
|
17
|
+
<SeriesName>Lost</SeriesName>
|
18
|
+
<Status>Continuing</Status>
|
19
|
+
<added></added>
|
20
|
+
<addedBy></addedBy>
|
21
|
+
<banner>graphical/73739-g4.jpg</banner>
|
22
|
+
<fanart>fanart/original/73739-34.jpg</fanart>
|
23
|
+
<lastupdated>1258670676</lastupdated>
|
24
|
+
<poster>posters/73739-7.jpg</poster>
|
25
|
+
<zap2it_id>SH672362</zap2it_id>
|
26
|
+
</Series>
|
Binary file
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
require 'tvdb'
|
6
|
+
require 'spec'
|
7
|
+
require 'spec/autorun'
|
8
|
+
|
9
|
+
def load_example_data
|
10
|
+
@serie1_xml = File.read(File.dirname(__FILE__) + "/data/serie1.xml")
|
11
|
+
@serie2_xml = File.read(File.dirname(__FILE__) + "/data/serie2.xml")
|
12
|
+
@series_xml = @serie1_xml + @serie2_xml
|
13
|
+
@serie1_zip = File.open(File.dirname(__FILE__) + "/data/serie1.zip")
|
14
|
+
@serie2_zip = File.open(File.dirname(__FILE__) + "/data/serie2.zip")
|
15
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
module TVdb
|
4
|
+
describe Client do
|
5
|
+
before(:each) do
|
6
|
+
@client = Client.new("api_key")
|
7
|
+
load_example_data
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have an api_key" do
|
11
|
+
@client.api_key.should == "api_key"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have an Urls instance for the given api_key" do
|
15
|
+
@client.urls.should be_an_instance_of Urls
|
16
|
+
@client.urls[:serie_xml].template.should match /^http:\/\/www\.thetvdb\.com\/api\/api_key/
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "get serie full data on zip" do
|
20
|
+
it "should request the TheTVDB serie zip url" do
|
21
|
+
OpenURI.should_receive(:open_uri).with(@client.urls[:serie_zip] % {:serie_id => "123987", :language => "en"}).and_return(@serie1_zip)
|
22
|
+
@client.get_serie_zip("123987")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should request the TheTVDB serie zip url in given language" do
|
26
|
+
OpenURI.should_receive(:open_uri).with(@client.urls[:serie_zip] % {:serie_id => "123987", :language => "de"}).and_return(@serie1_zip)
|
27
|
+
@client.get_serie_zip("123987", 'de')
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should avoid OpenURI::HTTPError exceptions" do
|
31
|
+
# Trying the TheTVDB API I have experienced that search return some
|
32
|
+
# invalid records which lead to 404 errors when requesting their info
|
33
|
+
OpenURI.stub!(:open_uri).and_raise(OpenURI::HTTPError.new("", "a"))
|
34
|
+
lambda {@client.get_serie_zip("123987")}.should_not raise_error
|
35
|
+
@client.get_serie_zip("123987").should be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "search" do
|
40
|
+
it "should request the TheTVDB search uri with given name" do
|
41
|
+
OpenURI.should_receive(:open_uri).with(@client.urls[:get_series] % {:name => URI.escape("Best show"), :language => "en"}).and_return(@serie1_zip)
|
42
|
+
@client.search("Best show")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should request the TheTVDB search uri with given name and language" do
|
46
|
+
OpenURI.should_receive(:open_uri).with(@client.urls[:get_series] % {:name => URI.escape("Best show"), :language => "de"}).and_return(@serie1_zip)
|
47
|
+
@client.search("Best show", {:lang => "de"})
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should get the zips of returned results" do
|
51
|
+
OpenURI.should_receive(:open_uri).and_return(StringIO.new(@series_xml))
|
52
|
+
|
53
|
+
@client.should_receive(:get_serie_zip).with("80379", "en").and_return(nil)
|
54
|
+
@client.should_receive(:get_serie_zip).with("73739", "en").and_return(nil)
|
55
|
+
@client.search("something")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should get the info for each return result in given language" do
|
59
|
+
OpenURI.should_receive(:open_uri).and_return(StringIO.new(@series_xml))
|
60
|
+
|
61
|
+
@client.should_receive(:get_serie_zip).with("80379", "de").and_return(nil)
|
62
|
+
@client.should_receive(:get_serie_zip).with("73739", "de").and_return(nil)
|
63
|
+
@client.search("something", :lang => "de")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return the Series corresponding to each response" do
|
67
|
+
OpenURI.should_receive(:open_uri).and_return(StringIO.new(@series_xml))
|
68
|
+
|
69
|
+
@client.should_receive(:get_serie_zip).with("80379", "en").and_return(Zip::ZipFile.new(@serie1_zip.path))
|
70
|
+
@client.should_receive(:get_serie_zip).with("73739", "en").and_return(Zip::ZipFile.new(@serie2_zip.path))
|
71
|
+
|
72
|
+
results = @client.search("something")
|
73
|
+
results.size.should == 2
|
74
|
+
results.each{|r| r.class.should == TVdb::Serie}
|
75
|
+
results.map(&:seriesname).sort.should == ["Lost", "The Big Bang Theory"]
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should give just the results with exact name" do
|
79
|
+
OpenURI.should_receive(:open_uri).and_return(StringIO.new(<<-XML
|
80
|
+
<Series><id>73739</id><SeriesName>Lost</SeriesName></Series>
|
81
|
+
<Series><id>73420</id><SeriesName>Finder of Lost Loves</SeriesName></Series>
|
82
|
+
<Series><id>98261</id><SeriesName>Lost Evidence</SeriesName></Series>
|
83
|
+
XML
|
84
|
+
))
|
85
|
+
|
86
|
+
@client.should_receive(:get_serie_zip).once.with("73739", "en").and_return(Zip::ZipFile.new(@serie2_zip.path))
|
87
|
+
results = @client.search("Lost", :match_mode => :exact)
|
88
|
+
results.size.should == 1
|
89
|
+
results.first.seriesname.should == "Lost"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should skip unreachable results" do
|
93
|
+
OpenURI.should_receive(:open_uri).and_return(StringIO.new(@series_xml))
|
94
|
+
|
95
|
+
@client.should_receive(:get_serie_zip).with("80379", "en").and_return(Zip::ZipFile.new(@serie1_zip.path))
|
96
|
+
@client.should_receive(:get_serie_zip).with("73739", "en").and_return(nil)
|
97
|
+
|
98
|
+
results = @client.search("something")
|
99
|
+
results.size.should == 1
|
100
|
+
results.first.seriesname.should == "The Big Bang Theory"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "get serie in other language" do
|
105
|
+
it "should avoid empty series" do
|
106
|
+
@client.serie_in_language(Serie.new(""), "es").should be_nil
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should give the serie itself when language is the same" do
|
110
|
+
serie = Serie.new(@serie1_xml)
|
111
|
+
@client.serie_in_language(serie, "en").should == serie
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should get the serie with information in the given language" do
|
115
|
+
original = Serie.new("<Series><id>4815162342</id></Series>")
|
116
|
+
zip_mock = mock "ZipFile"
|
117
|
+
|
118
|
+
@client.stub!(:get_serie_zip).and_return(zip_mock)
|
119
|
+
@client.stub!(:read_serie_xml_from_zip).with(zip_mock, 'es').and_return("<Series><id>4815162342</id><Overview>¿Qué quieren decir esos números?</Overview></Series>")
|
120
|
+
|
121
|
+
translated = @client.serie_in_language(original, "es")
|
122
|
+
translated.tvdb_id.should == "4815162342"
|
123
|
+
translated.overview.should == "¿Qué quieren decir esos números?"
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should return nil if there is no serie info" do
|
127
|
+
original = Serie.new("<Series><id>4815162342</id></Series>")
|
128
|
+
@client.should_receive(:get_serie_zip).with("4815162342", "es").and_return(nil)
|
129
|
+
@client.serie_in_language(original, "es").should be_nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
module TVdb
|
4
|
+
describe Element do
|
5
|
+
before(:each) do
|
6
|
+
load_example_data
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should map id attribute to tvdb_id serie method" do
|
10
|
+
element = Element.new("<Element><id>4815162342</id></Element>")
|
11
|
+
element.tvdb_id.should == "4815162342"
|
12
|
+
|
13
|
+
element = Element.new("<Wadus><id>3210</id></Wadus>")
|
14
|
+
element.tvdb_id.should == "3210"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have a method returning each root children by default" do
|
18
|
+
element = Element.new('<Element><attribute1>The one</attribute1><second>2</second><last>inphinity</last></Element>')
|
19
|
+
element.attribute1.should == "The one"
|
20
|
+
element.second.should == "2"
|
21
|
+
element.last.should == "inphinity"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have a method returning each children of the first element of the given name" do
|
25
|
+
element = Element.new('<Data><List><Element><attribute1>The one</attribute1><second>2</second><last>inphinity</last></Element></List></Data>', 'element')
|
26
|
+
element.attribute1.should == "The one"
|
27
|
+
element.second.should == "2"
|
28
|
+
element.last.should == "inphinity"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should accept a block that takes an attributes hash parameter to process elements" do
|
32
|
+
element = Element.new('<Element><attribute1>The one</attribute1><second>2</second></Element>') do |attributes|
|
33
|
+
attributes['attribute1'] += " and only"
|
34
|
+
attributes['attribute2'] = attributes['second']
|
35
|
+
attributes.delete('second')
|
36
|
+
end
|
37
|
+
|
38
|
+
element.attribute1.should == "The one and only"
|
39
|
+
element.attribute2.should == "2"
|
40
|
+
element.second.should be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should behave with empty xml" do
|
44
|
+
element = Element.new("")
|
45
|
+
|
46
|
+
element.wadus.should be_nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
module TVdb
|
4
|
+
describe Serie do
|
5
|
+
before(:each) do
|
6
|
+
load_example_data
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should build from TheTVDB serie xml" do
|
10
|
+
serie = Serie.new(@serie1_xml)
|
11
|
+
serie.seriesname = "The Big Bang Theory"
|
12
|
+
serie.firstaired = "2007-09-01"
|
13
|
+
serie.imdb_id = "tt0898266"
|
14
|
+
serie.status = "Continuing"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should map actors field to an array" do
|
18
|
+
serie = Serie.new("<Series><actors>|Humphrey Bogart|</actors></Series>")
|
19
|
+
serie.actors.should == ["Humphrey Bogart"]
|
20
|
+
|
21
|
+
serie = Serie.new("<Series><actors>|Humphrey Bogart|Ingrid Bergman|Paul Henreid|</actors></Series>")
|
22
|
+
serie.actors.should == ["Humphrey Bogart", "Ingrid Bergman", "Paul Henreid"]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should map genre field to field genres as an array" do
|
26
|
+
serie = Serie.new("<Series><genre>|Comedy|</genre></Series>")
|
27
|
+
serie.genres.should == ["Comedy"]
|
28
|
+
|
29
|
+
serie = Serie.new("<Series><genre>|Comedy|Romance|</genre></Series>")
|
30
|
+
serie.genres.should == ["Comedy", "Romance"]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should convert poster attribute to a TheTVDB banner url" do
|
34
|
+
serie = Serie.new("<Series><poster>posters/80379-1.jpg</poster></Series>")
|
35
|
+
serie.poster.should == TVdb::BANNER_URL % "posters/80379-1.jpg"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
module TVdb
|
4
|
+
describe Urls do
|
5
|
+
before(:each) do
|
6
|
+
@urls = Urls.new("api_key")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have an api_key" do
|
10
|
+
@urls.api_key.should == "api_key"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have templates for default urls with base url and api key on their template value" do
|
14
|
+
@urls.templates.size.should == Urls::URLS.size
|
15
|
+
Urls::URLS.each do |k,v|
|
16
|
+
@urls.templates[k].template.should == v % [Urls::BASE_URL, "api_key"]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should support different base urls" do
|
21
|
+
urls = Urls.new("api_key", "http://www.wadus.org")
|
22
|
+
Urls::URLS.each do |k,v|
|
23
|
+
urls.templates[k].template.should == v % ["http://www.wadus.org", "api_key"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should reference its templates" do
|
28
|
+
@urls[:serie_url].should == @urls.templates[:serie_url]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe Template do
|
33
|
+
before(:each) do
|
34
|
+
@template_string = "Hello my name is {{name}} and I am from {{country}}."
|
35
|
+
@template = Template.new(@template_string)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have a template" do
|
39
|
+
@template.template.should == @template_string
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should substitute its pattern using keys and values" do
|
43
|
+
(@template % {:name => "Alvaro", :country => "Spain"}).should == "Hello my name is Alvaro and I am from Spain."
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise error if any value is missing" do
|
47
|
+
lambda {@template % {:name => "Alvaro"}}.should raise_error("Value for country not found")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/tvdb.gemspec
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{tvdb}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["\303\201lvaro Bautista"]
|
12
|
+
s.date = %q{2010-08-29}
|
13
|
+
s.description = %q{Ruby wrapper for accessing TV shows information from the TheTVDB API}
|
14
|
+
s.email = %q{alvarobp@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README.markdown",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"lib/tvdb.rb",
|
26
|
+
"lib/tvdb/client.rb",
|
27
|
+
"lib/tvdb/element.rb",
|
28
|
+
"lib/tvdb/serie.rb",
|
29
|
+
"lib/tvdb/urls.rb",
|
30
|
+
"spec/data/serie1.xml",
|
31
|
+
"spec/data/serie1.zip",
|
32
|
+
"spec/data/serie2.xml",
|
33
|
+
"spec/data/serie2.zip",
|
34
|
+
"spec/spec.opts",
|
35
|
+
"spec/spec_helper.rb",
|
36
|
+
"spec/tvdb/client_spec.rb",
|
37
|
+
"spec/tvdb/element_spec.rb",
|
38
|
+
"spec/tvdb/serie_spec.rb",
|
39
|
+
"spec/tvdb/urls_spec.rb",
|
40
|
+
"tvdb.gemspec"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://github.com/alvarobp/tvdb}
|
43
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = %q{1.3.6}
|
46
|
+
s.summary = %q{Ruby wrapper for TheTVDB}
|
47
|
+
s.test_files = [
|
48
|
+
"spec/spec_helper.rb",
|
49
|
+
"spec/tvdb/client_spec.rb",
|
50
|
+
"spec/tvdb/element_spec.rb",
|
51
|
+
"spec/tvdb/serie_spec.rb",
|
52
|
+
"spec/tvdb/urls_spec.rb"
|
53
|
+
]
|
54
|
+
|
55
|
+
if s.respond_to? :specification_version then
|
56
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
57
|
+
s.specification_version = 3
|
58
|
+
|
59
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
60
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
61
|
+
s.add_runtime_dependency(%q<hpricot>, [">= 0.8.1"])
|
62
|
+
s.add_runtime_dependency(%q<rubyzip>, [">= 0.9.1"])
|
63
|
+
else
|
64
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
65
|
+
s.add_dependency(%q<hpricot>, [">= 0.8.1"])
|
66
|
+
s.add_dependency(%q<rubyzip>, [">= 0.9.1"])
|
67
|
+
end
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
70
|
+
s.add_dependency(%q<hpricot>, [">= 0.8.1"])
|
71
|
+
s.add_dependency(%q<rubyzip>, [">= 0.9.1"])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tvdb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- "\xC3\x81lvaro Bautista"
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-08-29 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 2
|
30
|
+
- 9
|
31
|
+
version: 1.2.9
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: hpricot
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 8
|
44
|
+
- 1
|
45
|
+
version: 0.8.1
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rubyzip
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
- 9
|
58
|
+
- 1
|
59
|
+
version: 0.9.1
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
description: Ruby wrapper for accessing TV shows information from the TheTVDB API
|
63
|
+
email: alvarobp@gmail.com
|
64
|
+
executables: []
|
65
|
+
|
66
|
+
extensions: []
|
67
|
+
|
68
|
+
extra_rdoc_files:
|
69
|
+
- LICENSE
|
70
|
+
- README.markdown
|
71
|
+
files:
|
72
|
+
- .gitignore
|
73
|
+
- LICENSE
|
74
|
+
- README.markdown
|
75
|
+
- Rakefile
|
76
|
+
- VERSION
|
77
|
+
- lib/tvdb.rb
|
78
|
+
- lib/tvdb/client.rb
|
79
|
+
- lib/tvdb/element.rb
|
80
|
+
- lib/tvdb/serie.rb
|
81
|
+
- lib/tvdb/urls.rb
|
82
|
+
- spec/data/serie1.xml
|
83
|
+
- spec/data/serie1.zip
|
84
|
+
- spec/data/serie2.xml
|
85
|
+
- spec/data/serie2.zip
|
86
|
+
- spec/spec.opts
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
- spec/tvdb/client_spec.rb
|
89
|
+
- spec/tvdb/element_spec.rb
|
90
|
+
- spec/tvdb/serie_spec.rb
|
91
|
+
- spec/tvdb/urls_spec.rb
|
92
|
+
- tvdb.gemspec
|
93
|
+
has_rdoc: true
|
94
|
+
homepage: http://github.com/alvarobp/tvdb
|
95
|
+
licenses: []
|
96
|
+
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options:
|
99
|
+
- --charset=UTF-8
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
version: "0"
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
segments:
|
114
|
+
- 0
|
115
|
+
version: "0"
|
116
|
+
requirements: []
|
117
|
+
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 1.3.6
|
120
|
+
signing_key:
|
121
|
+
specification_version: 3
|
122
|
+
summary: Ruby wrapper for TheTVDB
|
123
|
+
test_files:
|
124
|
+
- spec/spec_helper.rb
|
125
|
+
- spec/tvdb/client_spec.rb
|
126
|
+
- spec/tvdb/element_spec.rb
|
127
|
+
- spec/tvdb/serie_spec.rb
|
128
|
+
- spec/tvdb/urls_spec.rb
|