tvdb2 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: baf228f33001b998ffe4e51e2f5eb125e82207a9
4
+ data.tar.gz: ec4b8845798bc1479584c053eb8cf6ab5974fb37
5
+ SHA512:
6
+ metadata.gz: 011fa05b1d23010ee94b08900a036f5ee650d36b2d0505ee05a0f38c25947d939f5be036111d740dc99bde64c164d6fb1875e133aa1e36ade391f4523a21cd47
7
+ data.tar.gz: bd63f54b18a16de2c6deaeabe57ab1971b13566c7b536e2b88dd58ced9ad264ab9705e4638ec5d18f9f0434d52c4cd52389a226d247d5ec7aa7f3c25d6809b5b
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ main.rb
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tvdb2.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 pioz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # TVDB2 API for Ruby
2
+
3
+ Ruby wrapper for TVDB json api version 2.
4
+
5
+ The TVDB api version 2 documentation [can be found here](https://api.thetvdb.com/swagger).
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'tvdb2'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install tvdb2
23
+
24
+
25
+ ## Usage
26
+
27
+ First of all you need to get your API key:
28
+
29
+ * Register an account on http://thetvdb.com/?tab=register
30
+ * When you are logged register an api key on http://thetvdb.com/?tab=apiregister
31
+ * View your api keys on http://thetvdb.com/?tab=userinfo
32
+
33
+ ```
34
+ require 'tvdb2'
35
+
36
+ # Create a client object with your api key
37
+ client = TVDB.new(apikey: 'YOUR_API_KEY', language: 'en')
38
+
39
+ # Search series by name
40
+ results = client.search(name: 'Game of Thrones')
41
+ puts results.map(&:name).inspect
42
+ # Get best series result by name
43
+ got = best_result = client.best_search('Game of Thrones')
44
+ puts got.name
45
+
46
+ # Get list of actors
47
+ actors = got.actors
48
+ puts actors.first.name
49
+ puts actors.first.role
50
+ puts actors.first.image_url
51
+
52
+ # Print some info about all episodes
53
+ got.episodes.each do |episode|
54
+ puts episode.x
55
+ puts episode.absoluteNumber
56
+ puts episode.seasonNumber
57
+ puts episode.number
58
+ puts episode.overview
59
+ end
60
+ # Get only episodes from 101 and 200
61
+ episodes = got.episodes(page: 2)
62
+ # Get all episodes of season 1
63
+ episodes = got.episodes(airedSeason: 1)
64
+ # Get episode by index
65
+ puts got[3].name
66
+ # Get episode by x syntax (SEASON_NUMBERxEPISODE_NUMBER)
67
+ ep = got['3x9']
68
+ puts ep.name
69
+ puts ep.x # print '3x9'
70
+
71
+ # Get banner
72
+ url = got.banner_url
73
+ # Get random banner
74
+ url = got.banner_url(random: true)
75
+ # Get poster
76
+ url = got.poster_url
77
+ # Get random poster
78
+ url = got.poster_url(random: true)
79
+ # Get all posters
80
+ posters = got.posters
81
+ puts posters.first.url
82
+ # or
83
+ posters = got.images(keyType: 'poster')
84
+ # Get all season images
85
+ images = got.season_images
86
+ puts images.first.url
87
+ # Get all season images of season 2
88
+ images = got.season_images(season: 2)
89
+ puts images.first.url
90
+
91
+ # Switch language
92
+ client.language = 'it'
93
+ ep = got['3x9'] # retrieve the episodes with the new language
94
+ puts ep.name
95
+ client.language = 'en'
96
+ # or you can swith language only in a block
97
+ client.with_language(:it) do
98
+ ep = got['3x9']
99
+ puts ep.name
100
+ end
101
+ ```
102
+
103
+ The complete __documentation__ can be found [here](https://pioz.github.io/tvdb2).
104
+
105
+
106
+ ## Missing REST endpoints
107
+
108
+ This wrapper do not coverage all 100% api REST endpoints.
109
+ Missing methods are:
110
+
111
+ * __Series__
112
+ * filter: `GET /series/{id}/filter`
113
+ * __Updates__
114
+ * updadad: `GET /updated/query`
115
+ * __Users__
116
+ * user: `GET /user`
117
+ * favorites: `GET /user/favorites`
118
+ * delete favorites: `DELETE /user/favorites/{id}`
119
+ * add favorites: `PUT /user/favorites/{id}`
120
+ * ratings: `GET /user/ratings`
121
+ * ratings with query: `GET /user/ratings/query`
122
+ * delete rating: `DELETE /user/ratings/{itemType}/{itemId}`
123
+ * add rating: `PUT /user/ratings/{itemType}/{itemId}/{itemRating}`
124
+
125
+ ## Contributing
126
+
127
+ Bug reports and pull requests are welcome on GitHub at https://github.com/pioz/tvdb2.
128
+
129
+
130
+ ## License
131
+
132
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rdoc/task'
4
+ Rake::RDocTask.new do |rd|
5
+ rd.title = 'TVDB2'
6
+ rd.main = 'README.md'
7
+ rd.rdoc_dir = 'rdoc'
8
+ rd.rdoc_files.include('README.md', 'lib/**/*.rb')
9
+ rd.generator = 'darkfish'
10
+ rd.markup = 'markdown'
11
+ end
12
+
13
+ require 'yard'
14
+ YARD::Rake::YardocTask.new do |t|
15
+ t.files = ['lib/**/*.rb']
16
+ t.options << '-rREADME.md'
17
+ t.options << '--title=TVDB2'
18
+ t.options << '-mmarkdown'
19
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "tvdb2"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/tvdb2/api.rb ADDED
@@ -0,0 +1,153 @@
1
+ require 'tvdb2/series'
2
+ require 'tvdb2/episode'
3
+
4
+ module Tvdb2
5
+ # Methods in this module wrap the TVDB api endpoints.
6
+ #
7
+ # @todo Missing endpoints are:
8
+ #
9
+ # * __Series__
10
+ # * filter: `GET /series/{id}/filter`
11
+ # * __Updates__
12
+ # * updadad: `GET /updated/query`
13
+ # * __Users__
14
+ # * user: `GET /user`
15
+ # * favorites: `GET /user/favorites`
16
+ # * delete favorites: `DELETE /user/favorites/{id}`
17
+ # * add favorites: `PUT /user/favorites/{id}`
18
+ # * ratings: `GET /user/ratings`
19
+ # * ratings with query: `GET /user/ratings/query`
20
+ # * delete rating: `DELETE /user/ratings/{itemType}/{itemId}`
21
+ # * add rating: `PUT /user/ratings/{itemType}/{itemId}/{itemRating}`
22
+ module API
23
+
24
+ # Perform a request to the endpoint `GET /languages`.
25
+ #
26
+ # @return [Array<TvdbStruct>] all available languages. These language
27
+ # abbreviations can be used in the Accept-Language header for routes that
28
+ # return translation records.
29
+ # @raise [RequestError]
30
+ def languages
31
+ build_array_result('/languages')
32
+ end
33
+
34
+ # Perform a request to the endpoint `GET /languages/{id}`.
35
+ #
36
+ # @param [Integer] id language id.
37
+ # @return [TvdbStruct] Information about a particular language.
38
+ # @raise [RequestError]
39
+ def language(id)
40
+ build_object_result("/languages/#{id}")
41
+ end
42
+
43
+ # Perform a request to the endpoint `GET /search/series`.
44
+ #
45
+ # @param [Hash] params the params of the request.
46
+ # @option params [String] :name name of the series to search for;
47
+ # @option params [String] :imdbId IMDB id of the series;
48
+ # @option params [String] :zap2itId Zap2it id of the series to search for.
49
+ # @return [Array<Series>] list of series found.
50
+ # @raise [RequestError]
51
+ def search(params)
52
+ build_array_result('/search/series', params, Series)
53
+ end
54
+
55
+ # @param [String] name name of the series to search for.
56
+ # @return [Series] the series that best match the `name` passed as parameter.
57
+ # @raise [RequestError]
58
+ def best_search(name)
59
+ results = search(name: name)
60
+ chosen = results.select{|x| x.seriesName.downcase == name.downcase}.first
61
+ chosen ||= results.select{|x| x.aliases.map(&:downcase).include?(name.downcase)}.first
62
+ return chosen || results.first
63
+ end
64
+
65
+ # Perform a request to the endpoint `GET /series/{id}`.
66
+ #
67
+ # @param [Integer] id the id of the series.
68
+ # @return [Series] a series record that contains all information
69
+ # known about a particular series id.
70
+ # @raise [RequestError]
71
+ def series(id)
72
+ build_object_result("/series/#{id}", {}, Series)
73
+ end
74
+
75
+ # Perform a request to the endpoint `GET /series/{id}/episodes/summary`.
76
+ #
77
+ # @param [Integer] id the id of the series.
78
+ # @return [TvdbStruct] a summary of the episodes and seasons
79
+ # available for the series.
80
+ # @raise [RequestError]
81
+ def series_summary(id)
82
+ build_object_result("/series/#{id}/episodes/summary")
83
+ end
84
+
85
+ # Perform a request to the endpoint `GET /series/{id}/episodes`.
86
+ #
87
+ # @param [Integer] id the id of the series.
88
+ # @param [Hash] params the params of the request to retrieve the episodes of
89
+ # the series.
90
+ # @option params [String, Integer] :absoluteNumber absolute number of the
91
+ # episode;
92
+ # @option params [String, Integer] :airedSeason aired season number;
93
+ # @option params [String, Integer] :airedEpisode aired episode number;
94
+ # @option params [String, Integer] :dvdSeason DVD season number;
95
+ # @option params [String, Integer] :dvdEpisode DVD episode number;
96
+ # @option params [String, Integer] :imdbId IMDB id of the series;
97
+ # @option params [Integer] :page page of results to fetch (100
98
+ # episodes per page).
99
+ # @return [Array<Episode>] episodes found.
100
+ # @raise [RequestError]
101
+ def episodes(id, params = {})
102
+ if params.nil? || params.empty?
103
+ build_array_result("/series/#{id}/episodes", {}, Episode)
104
+ else
105
+ build_array_result("/series/#{id}/episodes/query", params, Episode)
106
+ end
107
+ end
108
+
109
+ # Perform a request to the endpoint `GET /series/{id}/actors`.
110
+ #
111
+ # @param [Integer] id the id of the series.
112
+ # @return [Array<TvdbStruct>] actors for the given series id.
113
+ # @raise [RequestError]
114
+ def actors(id)
115
+ build_array_result("/series/#{id}/actors")
116
+ end
117
+
118
+ # Perform a request to the endpoint `GET /episodes/{id}`.
119
+ #
120
+ # @param [Integer] id the id of the episode.
121
+ # @return [Episode] the full information for a given episode id.
122
+ # @raise [RequestError]
123
+ def episode(id)
124
+ build_object_result("/episodes/#{id}", {}, Episode)
125
+ end
126
+
127
+ # Perform a request to the endpoint `GET /series/{id}/images`.
128
+ #
129
+ # @param [Integer] id the id of the series.
130
+ # @return [Array<TvdbStruct>] a summary of the images for a
131
+ # particular series.
132
+ # @raise [RequestError]
133
+ def images_summary(id)
134
+ build_object_result("/series/#{id}/images")
135
+ end
136
+
137
+ # Perform a request to the endpoint `GET /series/{id}/images/query`.
138
+ #
139
+ # @param [Integer] id the id of the series.
140
+ # @param [Hash] params the params of the request to retrieve the images.
141
+ # @option params [String] :keyType type of image you're querying for
142
+ # (fanart, poster, season, seasonwide, series);
143
+ # @option params [String] :resolution resolution to filter by (1280x1024 for
144
+ # example);
145
+ # @option params [String] :subKey subkey for the above query keys.
146
+ # @return [Array<TvdbStruct>] the images for a particular series.
147
+ # @raise [RequestError]
148
+ def images(id, params)
149
+ build_array_result("/series/#{id}/images/query", params)
150
+ end
151
+
152
+ end
153
+ end
@@ -0,0 +1,151 @@
1
+ require 'httparty'
2
+ require 'uri'
3
+ require 'memoist'
4
+ require 'tvdb2/request_error'
5
+ require 'tvdb2/tvdb_struct'
6
+ require 'tvdb2/api'
7
+
8
+ # Module that works like a namespace of the library.
9
+ # @author Enrico Pilotto
10
+ module Tvdb2
11
+
12
+ # This class works as a client to retrieve data from TVDB json api version 2.
13
+ # Make http requests to
14
+ # [https://api.thetvdb.com](https://api.thetvdb.com/swagger).
15
+ #
16
+ # This class cache all http requests so only the first time a request is made
17
+ # ([Memoist gem](https://github.com/matthewrudy/memoist) is used).
18
+ # @see https://api.thetvdb.com/swagger TVDB api version 2 documentation
19
+ class Client
20
+
21
+ # The language in which you want get data.
22
+ # @example
23
+ # got = client.best_search('Game of Thrones')
24
+ # puts got.name # print 'Game of Thrones'
25
+ # client.language = :it # change language to italian
26
+ # got.series! # make a request to get new data
27
+ # puts got.name # print 'Il Trono di Spade'
28
+ attr_accessor :language
29
+
30
+ extend Memoist
31
+ include HTTParty
32
+ base_uri 'https://api.thetvdb.com'
33
+
34
+ include Tvdb2::API
35
+
36
+ # Create an object client. Take 2 keyword arguments:
37
+ #
38
+ # @param [String] apikey your tvdb apikey (you can get one at
39
+ # https://thetvdb.com/?tab=apiregister). Required.
40
+ # @param [Symbol, String] language the language in which you want get data.
41
+ # You can change later. Optional. Default is `nil` that is `EN`.
42
+ def initialize(apikey:, language: nil)
43
+ @language = language
44
+ response = post('/login', apikey: apikey)
45
+ raise RequestError.new(response) if response.code != 200
46
+ @token = response.parsed_response['token']
47
+ end
48
+
49
+ # Refresh your api token.
50
+ #
51
+ # @return [String] the new token
52
+ def refresh_token!
53
+ response = get('/refresh_token')
54
+ raise RequestError.new(response) if response.code != 200
55
+ @token = response['token']
56
+ return @token
57
+ end
58
+
59
+ # Inside the block change the language in which you want get data.
60
+ #
61
+ # @example
62
+ # got = client.best_search('Game of Thrones')
63
+ # client.with_language(:it) do |c|
64
+ # ep = got['1x1'] # Get episode data in italian
65
+ # puts ep.name # print the title of episode 1x1 in italian
66
+ # end
67
+ # ep = got['1x1'] # Get episode data in default language
68
+ # puts ep.name # print the title of episode 1x1 in english
69
+ #
70
+ # @param [Symbol, String] locale the language in which you want get data.
71
+ # @yield block called with the selected language.
72
+ def with_language(locale, &block)
73
+ tmp_language = @language
74
+ @language = locale.to_s
75
+ block.call(self)
76
+ @language = tmp_language
77
+ end
78
+
79
+
80
+ # Helper method to get the full url of an image from the relative path
81
+ # retrieved from api.
82
+ #
83
+ # @example
84
+ # got = client.best_search('Game of Thrones')
85
+ # puts got.posters.first.fileName # posters/121361-1.jpg
86
+ # puts TVDB.image_url(got.posters.first.fileName) # http://thetvdb.com/banners/posters/121361-1.jpg
87
+ # # or
88
+ # puts got.posters.first.fileName_url # http://thetvdb.com/banners/posters/121361-1.jpg
89
+ #
90
+ # @param [String] path the relative path of an image.
91
+ # @return [String] the complete url of the image.
92
+ def self.image_url(path)
93
+ URI::join("https://thetvdb.com/banners/", path).to_s
94
+ end
95
+
96
+ protected
97
+
98
+ # :nodoc:
99
+ # language param is required to invalidate memoist cache on different language
100
+ def get(path, params = {}, language = @language)
101
+ self.class.get(URI.escape(path), headers: build_headers, query: params)
102
+ end
103
+ memoize :get
104
+
105
+ # :nodoc:
106
+ def post(path, params = {}, language = @language)
107
+ self.class.post(URI.escape(path), headers: build_headers, body: params.to_json)
108
+ end
109
+ memoize :post
110
+
111
+ # :nodoc:
112
+ def build_result(path, params = {}, return_type = nil, &block)
113
+ response = get(path, params, @language)
114
+ if response.code === 200
115
+ return block.call(response['data'])
116
+ elsif response.code === 404
117
+ return return_type
118
+ else
119
+ raise RequestError.new(response)
120
+ end
121
+ end
122
+
123
+ # :nodoc:
124
+ def build_object_result(path, params = {}, klass = TvdbStruct)
125
+ build_result(path, params, nil) do |data|
126
+ klass.new(self, data)
127
+ end
128
+ end
129
+
130
+ # :nodoc:
131
+ def build_array_result(path, params = {}, klass = TvdbStruct)
132
+ build_result(path, params, []) do |data|
133
+ data.map{|x| klass.new(self, x)}
134
+ end
135
+ end
136
+
137
+ private
138
+
139
+ # :nodoc:
140
+ def build_headers
141
+ headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
142
+ headers.merge!('Accept-Language': @language.to_s) if @language
143
+ headers.merge!('Authorization': "Bearer #{@token}") if @token
144
+ return headers
145
+ end
146
+
147
+ end
148
+ end
149
+
150
+ # Alias of {Client}
151
+ TVDB = Tvdb2::Client
@@ -0,0 +1,62 @@
1
+ module Tvdb2
2
+
3
+ # This class rappresent a series episode retrieved from TVDB api.
4
+ class Episode
5
+
6
+ # All episode fields returned from TVDB api.
7
+ FIELDS = [
8
+ :absoluteNumber, :airedEpisodeNumber, :airedSeason,
9
+ :airsAfterSeason, :airsBeforeEpisode, :airsBeforeSeason, :direcotor,
10
+ :directors, :dvdChapter, :dvdDiscid, :dvdEpisodeNumber, :dvdSeason,
11
+ :episodeName, :filename, :firstAired, :guestStars, :id, :imdbId,
12
+ :lastUpdated, :lastUpdatedBy, :overview, :productionCode, :seriesId,
13
+ :showUrl, :siteRating, :siteRatingCount, :thumbAdded, :thumbAuthor,
14
+ :thumbHeight, :thumbWidth, :writers, :errors
15
+ ]
16
+
17
+ attr_reader *FIELDS
18
+
19
+ alias_method :name, :episodeName
20
+ alias_method :number, :airedEpisodeNumber
21
+ alias_method :seasonNumber, :airedSeason
22
+
23
+ # @param [Client] tvdb a TVDB api client.
24
+ # @param [Hash] data the data retrieved from api.
25
+ #
26
+ # @note The Episode object may not have all fields filled because it can be
27
+ # initialized from not completed data like when is build from a call like
28
+ # `series.episodes` (`GET /series/{id}/episodes`): in this case the api
29
+ # call return a subset of all avaiable data for the episodes. To get the
30
+ # complete data of a specific episode use `#episode!` method.
31
+ # @note You should never need to create this object manually.
32
+ def initialize(tvdb, data = {})
33
+ @tvdb = tvdb
34
+ FIELDS.each do |field|
35
+ instance_variable_set("@#{field}", data[field.to_s])
36
+ end
37
+ end
38
+
39
+ # Get all data for this episode. Calling api endpoint `GET /episodes/{id}`.
40
+ #
41
+ # @return [Episode] the episode object with all fields filled from
42
+ # the api response.
43
+ # @raise [RequestError]
44
+ def episode!
45
+ if self.lastUpdated.nil?
46
+ e = @tvdb.episode(self.id)
47
+ FIELDS.each do |field|
48
+ instance_variable_set("@#{field}", e.send(field))
49
+ end
50
+ end
51
+ return self
52
+ end
53
+ alias_method :get_data!, :episode!
54
+
55
+ # @return [String] the episode number with the "_x_" syntax:
56
+ # `"#{season_number}x#{episode_number}` (3x9)".
57
+ def x
58
+ "#{self.airedSeason}x#{self.airedEpisodeNumber}"
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,19 @@
1
+ module Tvdb2
2
+
3
+ # Exception raised when an http request to an endpoint return a status code
4
+ # different from 200 or 404.
5
+ class RequestError < StandardError
6
+
7
+ attr_reader :response, :code, :error
8
+
9
+ # @param [HTTParty::Response] response the HTTParty response object.
10
+ def initialize(response)
11
+ super(response['Error'] || response.message)
12
+ @response = response
13
+ @code = response.code
14
+ @error = response['Error']
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,188 @@
1
+ module Tvdb2
2
+
3
+ # This class rappresent a series retrieved from TVDB api.
4
+ class Series
5
+
6
+ # All series fields returned from TVDB api.
7
+ FIELDS = [
8
+ :added, :airsDayOfWeek, :airsTime, :aliases, :banner, :firstAired, :genre,
9
+ :id, :imdbId, :lastUpdated, :network, :networkId, :overview, :rating,
10
+ :runtime, :seriesId, :seriesName, :siteRating, :siteRatingCount, :status,
11
+ :zap2itId, :errors
12
+ ]
13
+
14
+ attr_reader *FIELDS
15
+
16
+ alias_method :name, :seriesName
17
+
18
+ # @param [Client] tvdb a TVDB api client.
19
+ # @param [Hash] data the data retrieved from api.
20
+ #
21
+ # @note The {Series} object may not have all fields filled because it
22
+ # can be initialized from not completed data like when is build from a
23
+ # call like {Client#search} (`GET /search/series`): in this case the api
24
+ # call return a subset of all avaiable data for the series. To get the
25
+ # complete data of a specific episode use {Series#series!} method.
26
+ # @note You should never need to create this object manually.
27
+ def initialize(tvdb, data = {})
28
+ @tvdb = tvdb
29
+ FIELDS.each do |field|
30
+ instance_variable_set("@#{field}", data[field.to_s])
31
+ end
32
+ end
33
+
34
+ # Get all data for this series. Calling api endpoint `GET /series/{id}`.
35
+ #
36
+ # @return [Series] the {Series} object with all fields filled
37
+ # from the api response.
38
+ # @raise [RequestError]
39
+ def series!
40
+ if self.added.nil?
41
+ s = @tvdb.series(self.id)
42
+ FIELDS.each do |field|
43
+ instance_variable_set("@#{field}", s.send(field))
44
+ end
45
+ end
46
+ return self
47
+ end
48
+ alias_method :get_data!, :series!
49
+
50
+ # @return [TvdbStruct] return the summary of the series.
51
+ # @raise [RequestError]
52
+ def series_summary
53
+ @tvdb.series_summary(self.id)
54
+ end
55
+
56
+ # Retrieve the episodes of the series.
57
+ #
58
+ # @param params (see API#episodes)
59
+ # @option params (see API#episodes)
60
+ # @return [Array<Episode>]
61
+ # @raise [RequestError]
62
+ def episodes(params = {})
63
+ return @tvdb.episodes(self.id, params) if params && params.key?(:page)
64
+ episodes = []
65
+ page = 1
66
+ loop do
67
+ params.merge!(page: page)
68
+ result = @tvdb.episodes(self.id, params)
69
+ episodes += result
70
+ page += 1
71
+ break if result.size < 100
72
+ end
73
+ return episodes.sort_by{|x| [x.airedSeason, x.airedEpisodeNumber]}
74
+ end
75
+
76
+ # @return [Array<TvdbStruct>] the list of actors in the series.
77
+ # @raise [RequestError]
78
+ def actors
79
+ @tvdb.actors(self.id)
80
+ end
81
+
82
+ # Get the episode of the series identified by the index.
83
+ # @param [String, Integer] index the index of the episode to retrieve. Can be and
84
+ # Integer (`absoluteNumber`) or a String
85
+ # `"#{season_number}x#{episode_number}"` (3x9).
86
+ # @return [Episode] the episode.
87
+ # @raise [RequestError]
88
+ #
89
+ # @example
90
+ # got = client.best_search('Game of Thrones')
91
+ # puts got[29].name
92
+ # puts got['3x9'].name
93
+ def [](index)
94
+ episodes = self.episodes
95
+ if index.is_a?(Integer)
96
+ return episodes.select{|e| e.absoluteNumber == index}.first
97
+ else
98
+ series, ep = index.split('x')
99
+ return episodes.select{|e| e.airedSeason == series.to_i && e.airedEpisodeNumber == ep.to_i}.first
100
+ end
101
+ end
102
+
103
+ # @!group Instance Method Summary to retrieve images
104
+
105
+ # @return [Array<TvdbStruct>] the image summary of the series.
106
+ # @raise [RequestError]
107
+ def images_summary
108
+ @tvdb.images_summary(self.id)
109
+ end
110
+
111
+ # Retrieve the images of the series.
112
+ #
113
+ # @param params (see API#images)
114
+ # @option params (see API#images)
115
+ # @return [Array<TvdbStruct>] the list of images.
116
+ # @raise [RequestError]
117
+ #
118
+ # @example
119
+ # got = client.best_search('Game of Thrones')
120
+ # puts got.images(keyType: 'poster').first.fileName_url # print the url of a poster of the series
121
+ def images(params)
122
+ @tvdb.images(self.id, params)
123
+ end
124
+
125
+ # @return [Array<TvdbStruct>] the list of fanart images.
126
+ # @raise [RequestError]
127
+ def fanarts
128
+ self.images(keyType: 'fanart')
129
+ end
130
+
131
+ # @return [Array<TvdbStruct>] the list of poster images.
132
+ # @raise [RequestError]
133
+ def posters
134
+ self.images(keyType: 'poster')
135
+ end
136
+
137
+ # @param [Integer] season If present return the images only for that
138
+ # `season` number.
139
+ # @return [Array<TvdbStruct>] the list of season images.
140
+ # @raise [RequestError]
141
+ def season_images(season: nil)
142
+ r = self.images(keyType: 'season')
143
+ r.select!{|x| x.subKey == season.to_s} if season
144
+ r.sort{|x,y| x.subKey <=> y.subKey}
145
+ end
146
+
147
+ # @param [Integer] season if present return the images only for that
148
+ # `season` number.
149
+ # @return [Array<TvdbStruct>] the list of season wide images.
150
+ # @raise [RequestError]
151
+ def seasonwide_images(season: nil)
152
+ r = self.images(keyType: 'seasonwide')
153
+ r.select!{|x| x.subKey == season.to_s} if season
154
+ r.sort{|x,y| x.subKey <=> y.subKey}
155
+ end
156
+
157
+ # @return [Array<TvdbStruct>] the list of banner images of the
158
+ # series.
159
+ # @raise [RequestError]
160
+ def banners
161
+ self.images(keyType: 'series')
162
+ end
163
+
164
+ # @param [Boolean] random If `true` return a random banner image url.
165
+ # @return [String] the banner image url of the series.
166
+ # @raise [RequestError]
167
+ def banner_url(random: false)
168
+ if random
169
+ b = self.banners.shuffle.first
170
+ b ? b.url : nil
171
+ else
172
+ @banner ? Client.image_url(@banner) : nil
173
+ end
174
+ end
175
+
176
+ # @param [Boolean] random If `true` return a random poster image url.
177
+ # @return [String] the poster image url of the series.
178
+ # @raise [RequestError]
179
+ def poster_url(random: false)
180
+ ps = self.posters
181
+ ps.shuffle! if random
182
+ ps.first ? ps.first.url : nil
183
+ end
184
+
185
+ # @!endgroup
186
+
187
+ end
188
+ end
@@ -0,0 +1,41 @@
1
+ require 'ostruct'
2
+
3
+ module Tvdb2
4
+ # OpenStruct that define `_url` methods to get url from images relative paths
5
+ # returned from api.
6
+ #
7
+ # @example
8
+ # got = client.best_search('Game of Thrones')
9
+ # puts got.posters.first.fileName # print relative path posters/121361-1.jpg
10
+ # puts got.posters.first.fileName_url # print url https://thetvdb.com/banners/posters/121361-1.jpg
11
+ class TvdbStruct < OpenStruct
12
+
13
+ # @param [Client] tvdb a TVDB api client. Only to compatibily with {Client}
14
+ # and {Episode} constructor.
15
+ # @param [Hash] hash the optional hash, if given, will generate attributes
16
+ # and values (can be a Hash, an OpenStruct or a Struct).
17
+ #
18
+ # @note You should never need to create this object manually.
19
+ def initialize(tvdb = nil, hash = {})
20
+ super(hash)
21
+ end
22
+
23
+ # @!parse
24
+ # # @return [String] the url string of relative image path stored in
25
+ # # `image` field. `nil` if `image` field is `nil`.
26
+ # def image_url; end
27
+ # # @return [String] the url string of relative image path stored in
28
+ # # `fileName` field. `nil` if `fileName` field is `nil`.
29
+ # def fileName_url; end
30
+ # # @return [String] the url string of relative image path stored in
31
+ # # `thumbnail` field. `nil` if `thumbnail` field is `nil`.
32
+ # def thumbnail_url; end
33
+ %w(image fileName thumbnail).each do |field|
34
+ define_method "#{field}_url" do
35
+ self.send(field) ? Client.image_url(self.send(field)) : nil
36
+ end
37
+ end
38
+ alias_method :url, :fileName_url
39
+
40
+ end
41
+ end
@@ -0,0 +1,4 @@
1
+ module Tvdb2
2
+ # The library version.
3
+ VERSION = '0.1.0'
4
+ end
data/lib/tvdb2.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'tvdb2/version'
2
+ require 'tvdb2/client'
data/test.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Ciccio
2
+
3
+ def pluto
4
+ puts 'ciccio'
5
+ end
6
+
7
+ end
8
+
9
+ Ciccio.pluto
data/tvdb2.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tvdb2/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tvdb2"
8
+ spec.version = Tvdb2::VERSION
9
+ spec.authors = ["pioz"]
10
+ spec.email = ["epilotto@gmx.com"]
11
+
12
+ spec.summary = %q{Ruby wrapper for TVDB api version 2}
13
+ spec.description = %q{Ruby wrapper for TVDB api version 2 (https://api.thetvdb.com/swagger).}
14
+ spec.homepage = "https://github.com/pioz/tvdb2"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.14"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "yard", "~> 0.9"
36
+
37
+ spec.add_runtime_dependency "httparty", "~> 0.15"
38
+ spec.add_runtime_dependency "memoist", "~> 0.16"
39
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tvdb2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - pioz
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-08-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: httparty
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.15'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.15'
69
+ - !ruby/object:Gem::Dependency
70
+ name: memoist
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.16'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.16'
83
+ description: Ruby wrapper for TVDB api version 2 (https://api.thetvdb.com/swagger).
84
+ email:
85
+ - epilotto@gmx.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - bin/console
96
+ - bin/setup
97
+ - lib/tvdb2.rb
98
+ - lib/tvdb2/api.rb
99
+ - lib/tvdb2/client.rb
100
+ - lib/tvdb2/episode.rb
101
+ - lib/tvdb2/request_error.rb
102
+ - lib/tvdb2/series.rb
103
+ - lib/tvdb2/tvdb_struct.rb
104
+ - lib/tvdb2/version.rb
105
+ - test.rb
106
+ - tvdb2.gemspec
107
+ homepage: https://github.com/pioz/tvdb2
108
+ licenses:
109
+ - MIT
110
+ metadata:
111
+ allowed_push_host: https://rubygems.org
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.6.12
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Ruby wrapper for TVDB api version 2
132
+ test_files: []