tv-data-api-clients 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Rakefile +11 -0
- data/lib/base.rb +2 -0
- data/lib/base/api/episode.rb +104 -0
- data/lib/base/api/show.rb +132 -0
- data/lib/core_ext/object.rb +15 -0
- data/lib/helpers.rb +22 -0
- data/lib/the_tv_db.rb +23 -0
- data/lib/the_tv_db/api/episode.rb +56 -0
- data/lib/the_tv_db/api/episode_list.rb +28 -0
- data/lib/the_tv_db/api/image.rb +114 -0
- data/lib/the_tv_db/api/image_list.rb +35 -0
- data/lib/the_tv_db/api/image_list_helpers.rb +32 -0
- data/lib/the_tv_db/api/mirror.rb +13 -0
- data/lib/the_tv_db/api/mirrors.rb +11 -0
- data/lib/the_tv_db/api/show.rb +125 -0
- data/lib/the_tv_db/configuration.rb +7 -0
- data/lib/tv_data_api_clients.rb +12 -0
- data/lib/tv_data_api_clients/version.rb +3 -0
- data/lib/tv_rage.rb +7 -0
- data/lib/tv_rage/show.rb +81 -0
- data/test/fixtures/example.gif +0 -0
- data/test/fixtures/the_tv_db/api_get_series_lost.xml +24 -0
- data/test/fixtures/the_tv_db/api_series_12345_all_en.xml +9 -0
- data/test/fixtures/the_tv_db/api_series_73739_banners.xml +157 -0
- data/test/fixtures/the_tv_db/api_series_73739_en.xml +30 -0
- data/test/fixtures/tv_rage/feeds_search_show.xml +11 -0
- data/test/fixtures/tv_rage/feeds_showinfo_sid_7926.xml +28 -0
- data/test/support/shared_episode_naming_tests.rb +90 -0
- data/test/support/shared_show_naming_tests.rb +29 -0
- data/test/test_helper.rb +28 -0
- data/test/unit/base/api/episode_test.rb +11 -0
- data/test/unit/base/api/show_test.rb +11 -0
- data/test/unit/the_tv_db/api/episode_list_test.rb +15 -0
- data/test/unit/the_tv_db/api/episode_test.rb +93 -0
- data/test/unit/the_tv_db/api/image_list_test.rb +42 -0
- data/test/unit/the_tv_db/api/image_test.rb +35 -0
- data/test/unit/the_tv_db/api/mirrors_test.rb +17 -0
- data/test/unit/the_tv_db/api/show_test.rb +57 -0
- data/test/unit/the_tv_db/configuration_test.rb +28 -0
- data/test/unit/tv_rage/show_test.rb +55 -0
- data/tv-data-api-clients.gemspec +29 -0
- metadata +238 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
module TheTvDb
|
2
|
+
module Api
|
3
|
+
class ImageList
|
4
|
+
include Helpers
|
5
|
+
extend Helpers
|
6
|
+
class << self
|
7
|
+
def for(show_id)
|
8
|
+
image_list = Array.new
|
9
|
+
image_list.extend(ImageListHelpers)
|
10
|
+
image_list_xml_document(show_id).xpath('/Banners/Banner/Language[text()="en"]/..').each do |node|
|
11
|
+
image_list.push Image.new(node.remove)
|
12
|
+
end
|
13
|
+
image_list
|
14
|
+
end
|
15
|
+
private
|
16
|
+
def image_list_xml_document(show_id)
|
17
|
+
if string = image_list_xml_string(show_id)
|
18
|
+
document = Nokogiri::XML(string, 'UTF-8')
|
19
|
+
if not document.root.nil?
|
20
|
+
return document
|
21
|
+
else
|
22
|
+
raise ::API::Base::UnprocessableXMLError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
def image_list_xml_string(show_id)
|
27
|
+
get_remote_file_as_string(image_list_url_for(show_id))
|
28
|
+
end
|
29
|
+
def image_list_url_for(show_id)
|
30
|
+
"#{Mirrors.all.first}/api/#{TheTvDb.configuration.api_key}/series/#{show_id}/banners.xml"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module TheTvDb
|
2
|
+
module Api
|
3
|
+
module ImageListHelpers
|
4
|
+
def highest_pixel_count
|
5
|
+
sort { |a,b| a.pixels <=> b.pixels }.last
|
6
|
+
end
|
7
|
+
def widescreen
|
8
|
+
select { |i| i.widescreen? }
|
9
|
+
end
|
10
|
+
def standard
|
11
|
+
select { |i| not i.widescreen? }
|
12
|
+
end
|
13
|
+
def season_banners
|
14
|
+
select do |i|
|
15
|
+
i.type == :season
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def banners
|
19
|
+
r = select do |i|
|
20
|
+
i.type == :fanart
|
21
|
+
end
|
22
|
+
r.extend(TheTvDb::Api::ImageListHelpers)
|
23
|
+
end
|
24
|
+
def posters
|
25
|
+
r = select do |i|
|
26
|
+
i.type == :poster
|
27
|
+
end
|
28
|
+
r.extend(TheTvDb::Api::ImageListHelpers)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module TheTvDb
|
4
|
+
module Api
|
5
|
+
class Show < Base::Api::Show
|
6
|
+
|
7
|
+
def network_id
|
8
|
+
xpath('/Data/Series/id').to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
def original_name
|
12
|
+
xpath('/Data/Series/SeriesName')
|
13
|
+
end
|
14
|
+
|
15
|
+
def language
|
16
|
+
xpath('/Data/Series/Language').try(:downcase)
|
17
|
+
end
|
18
|
+
|
19
|
+
def air_dates
|
20
|
+
if air_date = xpath('/Data/Series/FirstAired')
|
21
|
+
[safely_parse_date(air_date)]
|
22
|
+
else
|
23
|
+
[]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def started
|
28
|
+
air_dates.try(:first).try(:year)
|
29
|
+
end
|
30
|
+
|
31
|
+
def genres
|
32
|
+
(xpath('/Data/Series/Genre').try(:split, '|') || []).reject { |g| g.blank? }
|
33
|
+
end
|
34
|
+
|
35
|
+
def actors
|
36
|
+
(xpath('/Data/Series/Actors').try(:split, '|') || []).reject { |a| a.blank? }
|
37
|
+
end
|
38
|
+
|
39
|
+
def status
|
40
|
+
xpath('/Data/Series/Status').try(:downcase).try(:to_sym)
|
41
|
+
end
|
42
|
+
|
43
|
+
def runtime
|
44
|
+
xpath('/Data/Series/Runtime').try(:downcase).try(:to_i).try(:*, 60)
|
45
|
+
end
|
46
|
+
|
47
|
+
def overview
|
48
|
+
xpath('/Data/Series/Overview')
|
49
|
+
end
|
50
|
+
|
51
|
+
def network
|
52
|
+
xpath('/Data/Series/Network')
|
53
|
+
end
|
54
|
+
|
55
|
+
def remote_ids
|
56
|
+
remote_ids = []
|
57
|
+
if imdb_id = xpath('/Data/Series/IMDB_ID')
|
58
|
+
remote_ids.push [:imdb, imdb_id]
|
59
|
+
end
|
60
|
+
if zap2it_id = xpath('/Data/Series/zap2it_id')
|
61
|
+
remote_ids.push [:zap2it, zap2it_id]
|
62
|
+
end
|
63
|
+
remote_ids
|
64
|
+
end
|
65
|
+
|
66
|
+
def rating
|
67
|
+
r = xpath('/Data/Series/Rating')
|
68
|
+
if r.to_f > 0
|
69
|
+
return (r.to_f * 10).to_i
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def number_of_ratings
|
74
|
+
xpath('/Data/Series/RatingCount').try(:to_i)
|
75
|
+
end
|
76
|
+
|
77
|
+
class << self
|
78
|
+
|
79
|
+
def find_by_name(series_name)
|
80
|
+
if doc = search_xml_document(series_name)
|
81
|
+
if doc.xpath('//SeriesName').try(:first).try(:content).try(:downcase) == series_name.downcase
|
82
|
+
show = find_by_id(doc.xpath('//seriesid').first.content.to_i)
|
83
|
+
return show
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def find_by_id(series_id)
|
89
|
+
if doc = xml_document(series_id)
|
90
|
+
return Show.new(doc)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Escapes the series name, and does the lookup
|
96
|
+
#
|
97
|
+
def search_url_for(series_name)
|
98
|
+
"#{Mirrors.all.first}/api/GetSeries.php?seriesname=#{CGI.escape(series_name)}"
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Banner list URL
|
103
|
+
#
|
104
|
+
def banner_list_url_for(series_id)
|
105
|
+
"#{Mirrors.all.first}/api/#{TheTvDb.configuration.api_key}/series/#{series_id}/banners.xml"
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Banner list XML string
|
110
|
+
#
|
111
|
+
def banner_list_xml_string(series_id)
|
112
|
+
get_remote_file_as_string(banner_list_url_for(series_id))
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# Wheee
|
117
|
+
#
|
118
|
+
def url_for(series_id)
|
119
|
+
"#{Mirrors.all.first}/api/#{TheTvDb.configuration.api_key}/series/#{series_id}/en.xml"
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/lib/tv_rage.rb
ADDED
data/lib/tv_rage/show.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module TvRage
|
4
|
+
module Api
|
5
|
+
class Show < Base::Api::Show
|
6
|
+
|
7
|
+
@find_by_id_mutex = Mutex.new
|
8
|
+
@find_by_name_mutex = Mutex.new
|
9
|
+
|
10
|
+
def original_name
|
11
|
+
xpath('//showname')
|
12
|
+
end
|
13
|
+
|
14
|
+
def started
|
15
|
+
xpath('//started').try(:to_i)
|
16
|
+
end
|
17
|
+
|
18
|
+
def status
|
19
|
+
xpath('//status').try(:downcase).try(:gsub, /\W/, '_').try(:to_sym)
|
20
|
+
end
|
21
|
+
|
22
|
+
def country
|
23
|
+
xml_doc.xpath('//network').try(:attr, "country").try(:value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def network_id
|
27
|
+
xpath('//showid').try(:to_i)
|
28
|
+
end
|
29
|
+
|
30
|
+
def genres
|
31
|
+
xml_doc.xpath('//genres/genre').collect do |genre|
|
32
|
+
genre.content.strip
|
33
|
+
end.reject { |g| g.nil? }
|
34
|
+
end
|
35
|
+
|
36
|
+
def classification
|
37
|
+
xpath('//classification').try(:downcase).try(:to_sym)
|
38
|
+
end
|
39
|
+
|
40
|
+
def network
|
41
|
+
xpath('//network')
|
42
|
+
end
|
43
|
+
|
44
|
+
def runtime
|
45
|
+
xpath('//runtime').try(:to_i).try(:*, 60)
|
46
|
+
end
|
47
|
+
|
48
|
+
def aliases
|
49
|
+
xml_doc.xpath('//akas/aka').collect do |aka|
|
50
|
+
if country = aka.attr("country")
|
51
|
+
[country.upcase.to_sym, aka.content.strip]
|
52
|
+
end
|
53
|
+
end.reject { |a| a.nil? }
|
54
|
+
end
|
55
|
+
|
56
|
+
class << self
|
57
|
+
private
|
58
|
+
def find_by_name(show_name)
|
59
|
+
if doc = search_xml_document(show_name)
|
60
|
+
if doc.xpath('//Results/show/name').try(:first).try(:content).try(:downcase) == show_name.downcase
|
61
|
+
show = find_by_id(doc.xpath('//Results/show/showid').first.content.to_i)
|
62
|
+
return show
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
def find_by_id(series_id)
|
67
|
+
if doc = xml_document(series_id)
|
68
|
+
return Show.new(doc)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
def search_url_for(show_name)
|
72
|
+
'http://services.tvrage.com/feeds/search.php?show=' + CGI.escape(show_name)
|
73
|
+
end
|
74
|
+
def url_for(show_id)
|
75
|
+
'http://services.tvrage.com/feeds/showinfo.php?sid=' + show_id.to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
Binary file
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<Data>
|
3
|
+
<Series>
|
4
|
+
<seriesid>73739</seriesid>
|
5
|
+
<language>en</language>
|
6
|
+
<SeriesName>Lost</SeriesName>
|
7
|
+
<banner>graphical/73739-g4.jpg</banner>
|
8
|
+
<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>
|
9
|
+
<FirstAired>2004-09-22</FirstAired>
|
10
|
+
<IMDB_ID>tt0411008</IMDB_ID>
|
11
|
+
<zap2it_id>SH672362</zap2it_id>
|
12
|
+
<id>73739</id>
|
13
|
+
</Series>
|
14
|
+
<Series>
|
15
|
+
<seriesid>80525</seriesid>
|
16
|
+
<language>en</language>
|
17
|
+
<SeriesName>Lost Civilizations</SeriesName>
|
18
|
+
<banner>graphical/80525-g.jpg</banner>
|
19
|
+
<Overview>The secrets of lives once lived. Never before could you get so close to 7000 years of history! From the bloodletting of Maya kings and a pharaoh's last journey to the secret pleasures of a Roman empress. Original location cinematography in 25 countries takes you from Cuzco in Peru to Petra in Jordan. From ancient Mesopotamia to modern Tibet, lost worlds live again on these must-have DVDs!</Overview>
|
20
|
+
<FirstAired>1995-06-25</FirstAired>
|
21
|
+
<IMDB_ID>tt0112054</IMDB_ID>
|
22
|
+
<id>80525</id>
|
23
|
+
</Series>
|
24
|
+
</Data>
|
@@ -0,0 +1,157 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Banners>
|
3
|
+
<Banner>
|
4
|
+
<id>23089</id>
|
5
|
+
<BannerPath>fanart/original/73739-First.jpg</BannerPath>
|
6
|
+
<BannerType>fanart</BannerType>
|
7
|
+
<BannerType2>1920x1080</BannerType2>
|
8
|
+
<Colors>|255,255,255|0,0,0|181,199,209|</Colors>
|
9
|
+
<Language>en</Language>
|
10
|
+
<Rating>6.8889</Rating>
|
11
|
+
<RatingCount>27</RatingCount>
|
12
|
+
<SeriesName>false</SeriesName>
|
13
|
+
<ThumbnailPath>_cache/fanart/original/73739-15.jpg</ThumbnailPath>
|
14
|
+
<VignettePath>fanart/vignette/73739-15.jpg</VignettePath>
|
15
|
+
</Banner>
|
16
|
+
<Banner>
|
17
|
+
<id>20709</id>
|
18
|
+
<BannerPath>fanart/original/73739-9.jpg</BannerPath>
|
19
|
+
<BannerType>fanart</BannerType>
|
20
|
+
<BannerType2>1280x720</BannerType2>
|
21
|
+
<Colors>|233,219,190|55,19,7|102,95,111|</Colors>
|
22
|
+
<Language>en</Language>
|
23
|
+
<Rating>6.8889</Rating>
|
24
|
+
<RatingCount>18</RatingCount>
|
25
|
+
<SeriesName>false</SeriesName>
|
26
|
+
<ThumbnailPath>_cache/fanart/original/73739-9.jpg</ThumbnailPath>
|
27
|
+
<VignettePath>fanart/vignette/73739-9.jpg</VignettePath>
|
28
|
+
</Banner>
|
29
|
+
<Banner>
|
30
|
+
<id>423861</id>
|
31
|
+
<BannerPath>fanart/original/73739-46.jpg</BannerPath>
|
32
|
+
<BannerType>fanart</BannerType>
|
33
|
+
<BannerType2>1280x720</BannerType2>
|
34
|
+
<Colors/>
|
35
|
+
<Language>en</Language>
|
36
|
+
<Rating>6.5000</Rating>
|
37
|
+
<RatingCount>6</RatingCount>
|
38
|
+
<SeriesName>false</SeriesName>
|
39
|
+
<ThumbnailPath>_cache/fanart/original/73739-46.jpg</ThumbnailPath>
|
40
|
+
<VignettePath>fanart/vignette/73739-46.jpg</VignettePath>
|
41
|
+
</Banner>
|
42
|
+
<Banner>
|
43
|
+
<id>40330</id>
|
44
|
+
<BannerPath>posters/73739-7.jpg</BannerPath>
|
45
|
+
<BannerType>poster</BannerType>
|
46
|
+
<BannerType2>680x1000</BannerType2>
|
47
|
+
<Language>en</Language>
|
48
|
+
<Rating>8.5000</Rating>
|
49
|
+
<RatingCount>16</RatingCount>
|
50
|
+
</Banner>
|
51
|
+
<Banner>
|
52
|
+
<id>25884</id>
|
53
|
+
<BannerPath>posters/73739-1.jpg</BannerPath>
|
54
|
+
<BannerType>poster</BannerType>
|
55
|
+
<BannerType2>680x1000</BannerType2>
|
56
|
+
<Language>en</Language>
|
57
|
+
<Rating>7.6429</Rating>
|
58
|
+
<RatingCount>14</RatingCount>
|
59
|
+
</Banner>
|
60
|
+
<Banner>
|
61
|
+
<id>122621</id>
|
62
|
+
<BannerPath>seasons/73739-5-3.jpg</BannerPath>
|
63
|
+
<BannerType>season</BannerType>
|
64
|
+
<BannerType2>season</BannerType2>
|
65
|
+
<Language>en</Language>
|
66
|
+
<Rating>10.0000</Rating>
|
67
|
+
<RatingCount>3</RatingCount>
|
68
|
+
<Season>5</Season>
|
69
|
+
</Banner>
|
70
|
+
<Banner>
|
71
|
+
<id>17936</id>
|
72
|
+
<BannerPath>seasons/73739-0.jpg</BannerPath>
|
73
|
+
<BannerType>season</BannerType>
|
74
|
+
<BannerType2>season</BannerType2>
|
75
|
+
<Language>en</Language>
|
76
|
+
<Rating>9.0000</Rating>
|
77
|
+
<RatingCount>1</RatingCount>
|
78
|
+
<Season>0</Season>
|
79
|
+
</Banner>
|
80
|
+
<Banner>
|
81
|
+
<id>27457</id>
|
82
|
+
<BannerPath>seasons/73739-4-6.jpg</BannerPath>
|
83
|
+
<BannerType>season</BannerType>
|
84
|
+
<BannerType2>season</BannerType2>
|
85
|
+
<Language>es</Language>
|
86
|
+
<Rating>7.5000</Rating>
|
87
|
+
<RatingCount>2</RatingCount>
|
88
|
+
<Season>4</Season>
|
89
|
+
</Banner>
|
90
|
+
<Banner>
|
91
|
+
<id>27406</id>
|
92
|
+
<BannerPath>seasons/73739-3-3.jpg</BannerPath>
|
93
|
+
<BannerType>season</BannerType>
|
94
|
+
<BannerType2>season</BannerType2>
|
95
|
+
<Language>es</Language>
|
96
|
+
<Rating>6.5000</Rating>
|
97
|
+
<RatingCount>2</RatingCount>
|
98
|
+
<Season>3</Season>
|
99
|
+
</Banner>
|
100
|
+
<Banner>
|
101
|
+
<id>402891</id>
|
102
|
+
<BannerPath>seasons/73739-5-4.jpg</BannerPath>
|
103
|
+
<BannerType>season</BannerType>
|
104
|
+
<BannerType2>season</BannerType2>
|
105
|
+
<Language>es</Language>
|
106
|
+
<Rating>6.5000</Rating>
|
107
|
+
<RatingCount>2</RatingCount>
|
108
|
+
<Season>5</Season>
|
109
|
+
</Banner>
|
110
|
+
<Banner>
|
111
|
+
<id>31261</id>
|
112
|
+
<BannerPath>seasons/73739-3-6.jpg</BannerPath>
|
113
|
+
<BannerType>season</BannerType>
|
114
|
+
<BannerType2>season</BannerType2>
|
115
|
+
<Language>en</Language>
|
116
|
+
<Rating>6.5000</Rating>
|
117
|
+
<RatingCount>4</RatingCount>
|
118
|
+
<Season>3</Season>
|
119
|
+
</Banner>
|
120
|
+
<Banner>
|
121
|
+
<id>18105</id>
|
122
|
+
<BannerPath>seasonswide/73739-3.jpg</BannerPath>
|
123
|
+
<BannerType>season</BannerType>
|
124
|
+
<BannerType2>seasonwide</BannerType2>
|
125
|
+
<Language>en</Language>
|
126
|
+
<Rating/>
|
127
|
+
<RatingCount>0</RatingCount>
|
128
|
+
<Season>3</Season>
|
129
|
+
</Banner>
|
130
|
+
<Banner>
|
131
|
+
<id>410681</id>
|
132
|
+
<BannerPath>graphical/73739-g12.jpg</BannerPath>
|
133
|
+
<BannerType>series</BannerType>
|
134
|
+
<BannerType2>graphical</BannerType2>
|
135
|
+
<Language>en</Language>
|
136
|
+
<Rating>4.4000</Rating>
|
137
|
+
<RatingCount>5</RatingCount>
|
138
|
+
</Banner>
|
139
|
+
<Banner>
|
140
|
+
<id>498351</id>
|
141
|
+
<BannerPath>graphical/73739-g14.jpg</BannerPath>
|
142
|
+
<BannerType>series</BannerType>
|
143
|
+
<BannerType2>graphical</BannerType2>
|
144
|
+
<Language>fr</Language>
|
145
|
+
<Rating>1.0000</Rating>
|
146
|
+
<RatingCount>1</RatingCount>
|
147
|
+
</Banner>
|
148
|
+
<Banner>
|
149
|
+
<id>34607</id>
|
150
|
+
<BannerPath>graphical/73739-g9.jpg</BannerPath>
|
151
|
+
<BannerType>series</BannerType>
|
152
|
+
<BannerType2>graphical</BannerType2>
|
153
|
+
<Language>hu</Language>
|
154
|
+
<Rating>1.0000</Rating>
|
155
|
+
<RatingCount>5</RatingCount>
|
156
|
+
</Banner>
|
157
|
+
</Banners>
|