tvdb 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|