tv-data-api-clients 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +11 -0
  4. data/lib/base.rb +2 -0
  5. data/lib/base/api/episode.rb +104 -0
  6. data/lib/base/api/show.rb +132 -0
  7. data/lib/core_ext/object.rb +15 -0
  8. data/lib/helpers.rb +22 -0
  9. data/lib/the_tv_db.rb +23 -0
  10. data/lib/the_tv_db/api/episode.rb +56 -0
  11. data/lib/the_tv_db/api/episode_list.rb +28 -0
  12. data/lib/the_tv_db/api/image.rb +114 -0
  13. data/lib/the_tv_db/api/image_list.rb +35 -0
  14. data/lib/the_tv_db/api/image_list_helpers.rb +32 -0
  15. data/lib/the_tv_db/api/mirror.rb +13 -0
  16. data/lib/the_tv_db/api/mirrors.rb +11 -0
  17. data/lib/the_tv_db/api/show.rb +125 -0
  18. data/lib/the_tv_db/configuration.rb +7 -0
  19. data/lib/tv_data_api_clients.rb +12 -0
  20. data/lib/tv_data_api_clients/version.rb +3 -0
  21. data/lib/tv_rage.rb +7 -0
  22. data/lib/tv_rage/show.rb +81 -0
  23. data/test/fixtures/example.gif +0 -0
  24. data/test/fixtures/the_tv_db/api_get_series_lost.xml +24 -0
  25. data/test/fixtures/the_tv_db/api_series_12345_all_en.xml +9 -0
  26. data/test/fixtures/the_tv_db/api_series_73739_banners.xml +157 -0
  27. data/test/fixtures/the_tv_db/api_series_73739_en.xml +30 -0
  28. data/test/fixtures/tv_rage/feeds_search_show.xml +11 -0
  29. data/test/fixtures/tv_rage/feeds_showinfo_sid_7926.xml +28 -0
  30. data/test/support/shared_episode_naming_tests.rb +90 -0
  31. data/test/support/shared_show_naming_tests.rb +29 -0
  32. data/test/test_helper.rb +28 -0
  33. data/test/unit/base/api/episode_test.rb +11 -0
  34. data/test/unit/base/api/show_test.rb +11 -0
  35. data/test/unit/the_tv_db/api/episode_list_test.rb +15 -0
  36. data/test/unit/the_tv_db/api/episode_test.rb +93 -0
  37. data/test/unit/the_tv_db/api/image_list_test.rb +42 -0
  38. data/test/unit/the_tv_db/api/image_test.rb +35 -0
  39. data/test/unit/the_tv_db/api/mirrors_test.rb +17 -0
  40. data/test/unit/the_tv_db/api/show_test.rb +57 -0
  41. data/test/unit/the_tv_db/configuration_test.rb +28 -0
  42. data/test/unit/tv_rage/show_test.rb +55 -0
  43. data/tv-data-api-clients.gemspec +29 -0
  44. 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,13 @@
1
+ module TheTvDb
2
+ module Api
3
+ class Mirror
4
+ attr_reader :url
5
+ def initialize(url, typemask)
6
+ @url, @typemask = url, typemask
7
+ end
8
+ def to_s
9
+ url
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module TheTvDb
2
+ module Api
3
+ class Mirrors
4
+ class << self
5
+ def all
6
+ [Mirror.new('http://thetvdb.com', 7)]
7
+ end
8
+ end
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,7 @@
1
+ module TheTvDb
2
+
3
+ class Configuration
4
+ attr_accessor :api_key
5
+ end
6
+
7
+ end
@@ -0,0 +1,12 @@
1
+ require 'core_ext/object'
2
+ require 'helpers'
3
+
4
+ require 'base'
5
+ require 'the_tv_db'
6
+ require 'tv_rage'
7
+
8
+ require 'tv_data_api_clients/version'
9
+
10
+ module TvDataApiClients
11
+
12
+ end
@@ -0,0 +1,3 @@
1
+ module TvDataApiClients
2
+ VERSION = "0.0.7"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'tv_rage/show'
2
+
3
+ module TvRage
4
+
5
+ # No Confg Here
6
+
7
+ end
@@ -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,9 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <Data>
3
+ <Episode>
4
+ <id>328099</id>
5
+ </Episode>
6
+ <Episode>
7
+ <id>2</id>
8
+ </Episode>
9
+ </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>