tvdb_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +2 -0
  4. data/.rubyversion +1 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +2 -0
  7. data/Guardfile +20 -0
  8. data/README.md +43 -0
  9. data/Rakefile +9 -0
  10. data/conf/settings.example.yml +7 -0
  11. data/lib/tvdb_client.rb +13 -0
  12. data/lib/tvdb_client/authorization.rb +46 -0
  13. data/lib/tvdb_client/client.rb +30 -0
  14. data/lib/tvdb_client/connection.rb +98 -0
  15. data/lib/tvdb_client/series.rb +54 -0
  16. data/lib/tvdb_client/series/base.rb +32 -0
  17. data/lib/tvdb_client/series/series_episodes.rb +18 -0
  18. data/lib/tvdb_client/series/series_filter.rb +21 -0
  19. data/lib/tvdb_client/series/series_images.rb +14 -0
  20. data/lib/tvdb_client/service/threading.rb +8 -0
  21. data/lib/tvdb_client/service/threading/threaded_request.rb +51 -0
  22. data/lib/tvdb_client/settings.rb +10 -0
  23. data/lib/tvdb_client/version.rb +3 -0
  24. data/spec/spec_helper.rb +53 -0
  25. data/spec/support/fake_TVDB.rb +118 -0
  26. data/spec/support/fixtures/responses/login.json +3 -0
  27. data/spec/support/fixtures/responses/refresh_token.json +3 -0
  28. data/spec/support/fixtures/responses/series.json +33 -0
  29. data/spec/support/fixtures/responses/series_episodes_page_1.json +56 -0
  30. data/spec/support/fixtures/responses/series_episodes_page_2.json +56 -0
  31. data/spec/support/fixtures/responses/series_episodes_page_n.json +41 -0
  32. data/spec/support/fixtures/responses/series_episodes_query_airedSeason.json +41 -0
  33. data/spec/support/fixtures/responses/series_episodes_query_params.json +12 -0
  34. data/spec/support/fixtures/responses/series_episodes_summary.json +26 -0
  35. data/spec/support/fixtures/responses/series_filter.json +5 -0
  36. data/spec/support/fixtures/responses/series_filter_params.json +27 -0
  37. data/spec/support/fixtures/responses/series_images.json +9 -0
  38. data/spec/support/fixtures/responses/series_images_query.json +35 -0
  39. data/spec/support/fixtures/responses/series_images_query_params.json +60 -0
  40. data/spec/support/fixtures/settings.example.yml +6 -0
  41. data/spec/support/shared_contexts/authentication.rb +13 -0
  42. data/spec/support/shared_contexts/connection.rb +20 -0
  43. data/spec/support/shared_contexts/credentials.rb +20 -0
  44. data/spec/support/shared_contexts/series_subclass.rb +19 -0
  45. data/spec/tvdb_client/authorization_spec.rb +69 -0
  46. data/spec/tvdb_client/client_spec.rb +45 -0
  47. data/spec/tvdb_client/connection_spec.rb +159 -0
  48. data/spec/tvdb_client/series/base_spec.rb +13 -0
  49. data/spec/tvdb_client/series/series_episodes_spec.rb +55 -0
  50. data/spec/tvdb_client/series/series_filter_spec.rb +45 -0
  51. data/spec/tvdb_client/series/series_images_spec.rb +43 -0
  52. data/spec/tvdb_client/series_spec.rb +69 -0
  53. data/spec/tvdb_client/service/threading/threaded_request_spec.rb +54 -0
  54. data/spec/tvdb_client/version_spec.rb +12 -0
  55. data/tasks/version_bump.rake +102 -0
  56. data/templates/changelog_entry_template.md.erb +3 -0
  57. data/templates/version.rb.erb +3 -0
  58. data/tvdb_client.gemspec +41 -0
  59. metadata +412 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9d967e40fe2780d81db44abf2f4c5569e57c7e60
4
+ data.tar.gz: 26a36dc25cfab7e293a0c80047be339ef68eea7a
5
+ SHA512:
6
+ metadata.gz: bffccb169a9e9d98f4f14e41a366c1fd6f029080523deb9ec4fd3861139cd754142998a7ee953b195dbbf972a79e47515681418f6c51fb10cbc0bd67e938c576
7
+ data.tar.gz: 4f3d0b9b1d232427f98c9b2fb0c385aa345c7f101610f67d1f1e67052fe18808a9f9d3d67b9c23162e22f14e91b5772b11ccdfe8e3a9c0310d8edd0cc32219a5
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.sw[a-p]
3
+ .Trashes
4
+ ._*
5
+ .bundle
6
+ .config
7
+ .yardoc
8
+ bundle/
9
+ Desktop.ini
10
+ Gemfile.lock
11
+ Session.vim
12
+ _yardoc
13
+ auto-save-list
14
+ coverage
15
+ doc
16
+ lib/bundler/man
17
+ pkg
18
+ pkg/*
19
+ rdoc
20
+ spec/reports
21
+ test/tmp
22
+ test/version_tmp
23
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.rubyversion ADDED
@@ -0,0 +1 @@
1
+ 2.2.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+ Initial release of the `tvdb_client` rubygem.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,20 @@
1
+ notification :terminal_notifier
2
+
3
+ guard 'spork' do
4
+ watch('Gemfile')
5
+ watch('Gemfile.lock')
6
+ watch('spec/spec_helper.rb') { :rspec }
7
+ end
8
+
9
+ params = {
10
+ wait: 60,
11
+ all_after_pass: false,
12
+ all_on_start: true,
13
+ cmd: "bundle exec rspec"
14
+ }
15
+
16
+ guard 'rspec', cmd: 'bundle exec rspec' do
17
+ watch(%r{^spec/.+_spec\.rb$})
18
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
19
+ watch('spec/spec_helper.rb') { "spec" }
20
+ end
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # tvdb_client
2
+
3
+ `tvdb_client` is a rubygem to interface with The TVDB's REST API.
4
+
5
+ ## Installation
6
+
7
+ This gem has not yet been published on rubygems.org. For now, you will have to
8
+ download and build the gem from source. I will publish the gem once it is in
9
+ a releaseable state.
10
+
11
+ ```sh
12
+ $ git clone git@github.com:awlunsfo/tvdb_client.git
13
+ $ cd tvdb_client
14
+ $ gem build tvdb_client.gemspec
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ See the Wiki for usage details.
20
+
21
+ ## License
22
+
23
+ The MIT License (MIT)
24
+
25
+ Copyright (c) [year] [fullname]
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining a copy
28
+ of this software and associated documentation files (the "Software"), to deal
29
+ in the Software without restriction, including without limitation the rights
30
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31
+ copies of the Software, and to permit persons to whom the Software is
32
+ furnished to do so, subject to the following conditions:
33
+
34
+ The above copyright notice and this permission notice shall be included in all
35
+ copies or substantial portions of the Software.
36
+
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'semantic'
3
+ require 'highline/import'
4
+ require 'settingslogic'
5
+
6
+ require_relative 'lib/tvdb_client'
7
+ require_relative "lib/tvdb_client/settings"
8
+
9
+ Dir.glob('tasks/*.rake').each { |r| load r}
@@ -0,0 +1,7 @@
1
+ ---
2
+ tvdb:
3
+ apikey: 123abc
4
+ username: biz
5
+ userpass: baz
6
+ host_url: https://api.thetvdb.localhost.com
7
+ api_version: 1.2.0
@@ -0,0 +1,13 @@
1
+ require_relative "tvdb_client/authorization"
2
+ require_relative "tvdb_client/client"
3
+ require_relative "tvdb_client/connection"
4
+ require_relative "tvdb_client/settings"
5
+ require_relative "tvdb_client/series"
6
+ require_relative "tvdb_client/series/base"
7
+ require_relative "tvdb_client/series/series_episodes"
8
+ require_relative "tvdb_client/series/series_images"
9
+ require_relative "tvdb_client/series/series_filter"
10
+ require_relative "tvdb_client/version"
11
+
12
+ module TVDB
13
+ end
@@ -0,0 +1,46 @@
1
+ module TVDB
2
+
3
+ class Authorization
4
+
5
+ attr_reader :username, :password, :api_key
6
+ attr_accessor :connection
7
+
8
+ def initialize( options )
9
+ @username = options.fetch( :username ) { nil }
10
+ @password = options.fetch( :userpass ) { nil }
11
+ @api_key = options.fetch( :apikey ) { Settings.tvdb.apikey }
12
+ @connection = options.fetch( :connection )
13
+ end
14
+
15
+ def login
16
+ credentials = {
17
+ :username => username,
18
+ :userpass => password,
19
+ :apikey => api_key
20
+ }
21
+
22
+ response = connection.post( "/login", body: credentials )
23
+
24
+ handle_response( response )
25
+ end
26
+
27
+ def refresh_token
28
+ response = connection.get( '/refresh_token' )
29
+
30
+ handle_response( response )
31
+ end
32
+
33
+ private
34
+
35
+ def handle_response( response )
36
+ if response.code != 200
37
+ connection.token = ""
38
+ else
39
+ connection.token = response.body["token"]
40
+ end
41
+
42
+ return response
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ module TVDB
2
+ class Client
3
+ attr_accessor :connection
4
+ attr_reader :auth
5
+
6
+ def initialize( options )
7
+ authenticate( options )
8
+ end
9
+
10
+ def refresh_token
11
+ auth.refresh_token
12
+ end
13
+
14
+ def series( series_id, options = {} )
15
+ TVDB::Series.new( connection, series_id, options )
16
+ end
17
+
18
+ private
19
+
20
+ def authenticate( options )
21
+ @connection = TVDB::Connection.new( options )
22
+ options[:connection] = connection
23
+ @auth = TVDB::Authorization.new( options )
24
+
25
+ login = auth.login
26
+
27
+ raise "#{login}" if login.code == 401
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,98 @@
1
+ module TVDB
2
+ class Connection
3
+ require "faraday"
4
+ require "json"
5
+
6
+ attr_accessor :token, :response_struct, :language, :version, :modified_since
7
+ attr_reader :connection, :host_url
8
+
9
+ def initialize( options = {} )
10
+ @token = ""
11
+
12
+ @host_url = options.fetch( :host_url ) { Settings.tvdb.host_url }
13
+ @language = options[:language]
14
+ @version = options[:version]
15
+ @modified_since = options[:modified_since]
16
+
17
+ @connection = Faraday.new( :url => host_url, :ssl => { :verify => false } )
18
+ @response_struct = Struct.new( :request_url, :code, :body, :headers )
19
+ end
20
+
21
+ def post( route, options )
22
+ request_body = options.fetch( :body )
23
+
24
+ response = connection.post do |req|
25
+ req.url( route )
26
+ req.headers = set_default_headers( options )
27
+ req.body = request_body.to_json
28
+ end
29
+
30
+ return parsed_response( response )
31
+ end
32
+
33
+ def get( route, options = {} )
34
+ params, headers = parse_options( options )
35
+
36
+ response = connection.get do |req|
37
+ req.url( route )
38
+ req.headers = headers
39
+ req.params = params
40
+ end
41
+
42
+ return parsed_response( response )
43
+ end
44
+
45
+ def parse_options( options )
46
+ headers = set_default_headers( options )
47
+ params = set_params( options )
48
+
49
+ return params, headers
50
+ end
51
+
52
+ def set_params( options )
53
+ [:language, :version, :modified_since, :headers].each do |param|
54
+ options.delete_if { |key, value| key == param }
55
+ end
56
+
57
+ return options
58
+ end
59
+
60
+ def set_default_headers( options )
61
+ set_convenience_headers( options )
62
+
63
+ headers = options[:headers] if options
64
+ headers ||= {}
65
+
66
+ headers["Authorization"] ||= "Bearer #{token}"
67
+ headers["Content-Type"] ||= "application/json"
68
+ headers["Accept-Language"] ||= "#{language}"
69
+ headers["Accept"] ||= "application/vnd.thetvdb.v#{version}"
70
+ headers["If-Modified-Since"] ||= "#{modified_since}"
71
+
72
+ return headers
73
+ end
74
+
75
+ def set_convenience_headers( options )
76
+ if options
77
+ @language = options[:language]
78
+ @version = options[:version]
79
+ @modified_since = options[:modified_since]
80
+ end
81
+ end
82
+
83
+ def parsed_response( response )
84
+ unless response.body.empty?
85
+ body = JSON.parse( response.body )
86
+ else
87
+ body = nil
88
+ end
89
+
90
+ response_struct.new(
91
+ "#{host_url}#{response.env.url.request_uri}",
92
+ response.status,
93
+ body,
94
+ response.env.response_headers
95
+ )
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,54 @@
1
+ module TVDB
2
+ class Series
3
+ attr_accessor :connection
4
+ attr_reader :data, :route, :series_id, :code, :params
5
+
6
+ def initialize( connection, series_id, options = {} )
7
+ @connection = connection
8
+ @series_id = series_id
9
+ @route = "/series/#{series_id}"
10
+
11
+ set_subtype_parameters
12
+ get_series( series_id, options )
13
+ end
14
+
15
+ def episodes( options = {} )
16
+ set_subtype_parameters( options )
17
+
18
+ TVDB::Series::Episodes.new( params )
19
+ end
20
+
21
+ def images( options = {} )
22
+ set_subtype_parameters( options )
23
+
24
+ TVDB::Series::Images.new( params )
25
+ end
26
+
27
+ def filter( options = {} )
28
+ set_subtype_parameters( options )
29
+
30
+ TVDB::Series::Filter.new( params )
31
+ end
32
+
33
+ def all_episodes
34
+ tr = TVDB::Service::Threading::ThreadedRequest.new( connection: connection )
35
+ tr.make_request( "#{route}/episodes" )
36
+ end
37
+
38
+ private
39
+
40
+ def get_series( series_id, options = {} )
41
+ series = connection.get( route, options )
42
+ @data = series.body
43
+ @code = series.code
44
+ end
45
+
46
+ def set_subtype_parameters( options = {} )
47
+ @params = {
48
+ connection: connection,
49
+ series_id: series_id,
50
+ params: options
51
+ }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,32 @@
1
+ module TVDB
2
+ class Series
3
+ class Base
4
+
5
+ attr_reader :series_id, :data, :route
6
+ attr_accessor :connection, :parameters
7
+
8
+ def initialize
9
+ abstract_method
10
+ end
11
+
12
+ def list
13
+ connection.get( route, parameters ).body
14
+ end
15
+
16
+ def query( options )
17
+ connection.get( "#{route}/query", options ).body
18
+ end
19
+
20
+ def query_params
21
+ connection.get( "#{route}/query/params" ).body
22
+ end
23
+
24
+ private
25
+
26
+ def abstract_method
27
+ raise Exception, "#{self.class}: This method needs to be implemented in the concrete class"
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ module TVDB
2
+ class Series
3
+ class Episodes < TVDB::Series::Base
4
+
5
+ def initialize( options )
6
+ @connection = options.fetch( :connection )
7
+ @series_id = options.fetch( :series_id )
8
+ @parameters = options.fetch( :params ) { {} }
9
+ @route = "/series/#{series_id}/episodes"
10
+ end
11
+
12
+ def summary
13
+ connection.get( "#{route}/summary" ).body
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module TVDB
2
+ class Series
3
+ class Filter < TVDB::Series::Base
4
+
5
+ def initialize( options )
6
+ @connection = options.fetch( :connection )
7
+ @series_id = options.fetch( :series_id )
8
+ @parameters = options.fetch( :params ) { {} }
9
+ @route = "/series/#{series_id}/filter"
10
+ end
11
+
12
+ def params
13
+ connection.get( "#{route}/params" ).body
14
+ end
15
+
16
+ def query_params
17
+ raise NotImplementedError, "'.query_params' not implemented for #{self.class}. Please use '.params'"
18
+ end
19
+ end
20
+ end
21
+ end