viki 0.0.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -7,23 +7,30 @@ Installation
7
7
  ----------
8
8
  Manually `gem install viki` or add `gem 'viki'` to Gemfile
9
9
 
10
- How to use
11
- ----------
12
- Add to your .rb
10
+ Usage
11
+ -----
12
+ Add where necessary
13
13
 
14
14
  require 'viki'
15
15
 
16
16
  Initialization
17
17
 
18
- viki = Viki.new('your_client_id', 'your_client_secret')
18
+ client = Viki.new('your_client_id', 'your_client_secret')
19
+
20
+ Client is a `Viki::Client` object. When you make a method call, for example `client.movies`, the client will return a `Viki::Request` object - which you will be using to make requests. You may chain methods on the request object. The actual call to the API will only be made when you call `.get` on the request object.
19
21
 
22
+ viki = client.movies #returns a Viki::Request object
23
+ results = viki.get #hits the API and returns a Viki::APIObject
20
24
 
21
- Responses will be returned in a `Viki::APIObject`.
25
+ APIObject Methods
26
+ -----------------
22
27
 
23
- For results that are paginated. You can use the `APIObject`'s `next` and `prev` methods to retrieve the next and previous 25 records respectively.
28
+ Responses will be returned in a `Viki::APIObject`. See below
29
+
30
+ For results that are paginated, you may use the `APIObject`'s `next` and `prev` methods to retrieve the next and previous 25 records respectively.
24
31
 
25
32
  ```
26
- viki.movies
33
+ viki = client.movies #returns a Viki::Request
27
34
  movies = viki.get #return records in a Viki::APIObject
28
35
 
29
36
  movies.content #content of the API call in JSON format
@@ -37,8 +44,9 @@ For results that are paginated. You can use the `APIObject`'s `next` and `prev`
37
44
  Examples
38
45
  ----------
39
46
  * Results will always be returned in JSON format.
47
+ * This gem simply converts Ruby methods to API endpoints. Each URL namespace is a method. This means that if there is a `/series/` url namespace, the gem's request object will have an equivalent `.series` method. See examples below for an illustration of this behaviour.
48
+ * Refer to the [API V3 documentation](http://dev.viki.com/api "Viki API V3 Docs") for complete documentation for all Viki API endpoints.
40
49
  * All URL endpoints in the following examples should include an `access_token` parameter.
41
- * Refer to the [API V3 documentation](http://dev.viki.com/api "Viki API V3 Docs") for all endpoints.
42
50
 
43
51
  ### List Movies
44
52
  URL
@@ -51,8 +59,8 @@ URL
51
59
 
52
60
  Your ruby application
53
61
 
54
- viki.movies.get #without parameter filters
55
- viki.movies(genre: 2).get #with parameter filters
62
+ client.movies.get #without parameter filters
63
+ client.movies(genre: 2).get #with parameter filters
56
64
 
57
65
  ### Show Movie
58
66
  URL
@@ -61,7 +69,7 @@ URL
61
69
 
62
70
  Your ruby application
63
71
 
64
- viki.movies(71459).get
72
+ client.movies(71459).get
65
73
 
66
74
  ### Subtitles
67
75
  URL
@@ -70,7 +78,7 @@ URL
70
78
 
71
79
  Your ruby application
72
80
 
73
- viki.movies(71459).subtitles('en').get
81
+ client.movies(71459).subtitles('en').get
74
82
 
75
83
  ### Show Episode
76
84
  URL
@@ -79,7 +87,7 @@ URL
79
87
 
80
88
  Your ruby application
81
89
 
82
- viki.series(6004).episodes(61168).get
90
+ client.series(6004).episodes(61168).get
83
91
 
84
92
  ### List Newscasts
85
93
 
@@ -93,11 +101,11 @@ URL
93
101
 
94
102
  Your ruby application
95
103
 
96
- viki.newscasts.get #without parameter filter
97
- viki.newscasts(language: 'ko').get #with parameter filter
104
+ client.newscasts.get #without parameter filter
105
+ client.newscasts(language: 'ko').get #with parameter filter
98
106
 
99
107
  RSpec Testing
100
- ----------
108
+ -------------
101
109
  To run the tests, create a spec_config.rb file from the sample file.
102
110
 
103
- Add your client id and client secret into the file.
111
+ Add your client id and client secret into this file.
data/lib/viki/client.rb CHANGED
@@ -1,14 +1,12 @@
1
1
  require 'httparty'
2
2
  require 'viki/api_object'
3
+ require 'viki/transport'
3
4
  require 'viki/request'
4
5
  require 'multi_json'
5
6
 
6
7
  module Viki
7
8
  class Client
8
- Dir[File.expand_path('../client/*.rb', __FILE__)].each { |f| require f }
9
- URL_NAMESPACES = [:movies, :series, :episodes, :music_videos, :newscasts, :newsclips,
10
- :artists, :featured, :coming_soon, :subtitles, :hardsubs, :genres, :countries,
11
- :search, :languages]
9
+ include Viki::Transport
12
10
 
13
11
  def initialize(client_id, client_secret)
14
12
  @client_id = client_id
@@ -18,36 +16,12 @@ module Viki
18
16
 
19
17
  attr_reader :access_token
20
18
 
21
- include Viki::Request
22
-
23
- def get
24
- current_chain = @call_chain
25
- @call_chain = []
26
- request(current_chain)
27
- end
28
-
29
- def reset_access_token
30
- @access_token = auth_request(@client_id, @client_secret)
31
- end
32
-
33
19
  private
34
20
  def method_missing(name, *args)
35
- @call_chain ||= []
36
- raise NoMethodError if not URL_NAMESPACES.include? name
37
-
38
- curr_call = { name: name }
39
-
40
- first_arg, second_arg = args[0], args[1]
41
-
42
- if args.length == 1
43
- first_arg.is_a?(Hash) ? curr_call.merge!({ params: first_arg }) : curr_call.merge!({ resource: first_arg })
44
- elsif args.length == 2
45
- curr_call.merge!({ resource: first_arg })
46
- curr_call.merge!({ params: second_arg })
47
- end
48
-
49
- @call_chain.push(curr_call)
50
- self
21
+ raise NoMethodError if not URL_NAMESPACES.include? name
22
+ Viki::Request.new({client_id: @client_id,
23
+ client_secret: @client_secret,
24
+ access_token: @access_token}, name, *args)
51
25
  end
52
26
 
53
27
  end
data/lib/viki/request.rb CHANGED
@@ -1,57 +1,51 @@
1
- require 'uri'
2
- require 'httparty'
3
- require 'multi_json'
4
- require 'viki/utilities'
5
-
6
1
  module Viki
7
- module Request
8
- include Viki::Utilities
2
+ class Request
3
+ def initialize(auth_data, name, *args)
4
+ @access_token = auth_data[:access_token]
5
+ @client_id = auth_data[:client_id]
6
+ @client_secret = auth_data[:client_secret]
9
7
 
10
- private
11
- HOST = "http://www.viki.com/api/v3/"
12
-
13
- def auth_request(client_id, client_secret)
14
- params = {
15
- :grant_type => 'client_credentials',
16
- :client_id => client_id,
17
- :client_secret => client_secret
18
- }
19
- response = HTTParty.post('http://viki.com/oauth/token', query: params)
20
- json = MultiJson.load(response.body)
21
- raise Viki::Error.new(response.header.code, json["error_description"]) if response.header.code != "200"
22
- json["access_token"]
8
+ build_call_chain(name, *args)
23
9
  end
24
10
 
25
- def request(call_chain)
26
- path, params = build_url(call_chain)
27
- request_url = HOST + path.chop + ".json"
11
+ attr_reader :access_token
28
12
 
29
- response = HTTParty.get(request_url, :query => params)
13
+ include Viki::Transport
30
14
 
31
- if response.header.code == "401"
32
- self.reset_access_token
33
- params.merge!({ access_token: self.access_token })
34
- response = HTTParty.get(request_url, :query => params)
35
- end
36
-
37
- capture response
15
+ def get
16
+ current_chain = @call_chain
17
+ @call_chain = []
18
+ request(current_chain)
19
+ end
38
20
 
39
- APIObject.new(response.body, self.access_token)
21
+ def reset_access_token
22
+ @access_token = auth_request(@client_id, @client_secret)
40
23
  end
41
24
 
42
25
  private
26
+ def method_missing(name, *args)
27
+ build_call_chain(name, *args)
28
+ self
29
+ end
30
+
31
+ def build_call_chain(name, *args)
32
+ @call_chain ||= []
33
+ raise NoMethodError if not URL_NAMESPACES.include? name
34
+
35
+ curr_call = { name: name }
43
36
 
44
- def build_url(call_chain)
45
- path = ""
46
- params = { access_token: self.access_token }
37
+ first_arg, second_arg = args[0], args[1]
47
38
 
48
- call_chain.each do |c|
49
- path += "#{c[:name]}/"
50
- path += "#{c[:resource]}/" if c.has_key?(:resource)
51
- params.merge!(c[:params]) if c.has_key?(:params)
39
+ if args.length == 1
40
+ first_arg.is_a?(Hash) ? curr_call.merge!({ params: first_arg }) : curr_call.merge!({ resource: first_arg })
41
+ elsif args.length == 2
42
+ curr_call.merge!({ resource: first_arg })
43
+ curr_call.merge!({ params: second_arg })
52
44
  end
53
45
 
54
- return path, params
46
+ @call_chain.push(curr_call)
55
47
  end
48
+
56
49
  end
57
50
  end
51
+
@@ -0,0 +1,55 @@
1
+ require 'uri'
2
+ require 'httparty'
3
+ require 'multi_json'
4
+ require 'viki/utilities'
5
+
6
+ module Viki
7
+ module Transport
8
+ include Viki::Utilities
9
+
10
+ private
11
+ HOST = "http://www.viki.com/api/v3/"
12
+
13
+ def auth_request(client_id, client_secret)
14
+ params = {
15
+ :grant_type => 'client_credentials',
16
+ :client_id => client_id,
17
+ :client_secret => client_secret
18
+ }
19
+ response = HTTParty.post('http://viki.com/oauth/token', query: params)
20
+ json = MultiJson.load(response.body)
21
+ raise Viki::Error.new(response.header.code, json["error_description"]) if response.header.code != "200"
22
+ json["access_token"]
23
+ end
24
+
25
+ def request(call_chain)
26
+ path, params = build_url(call_chain)
27
+ request_url = HOST + path.chop + ".json"
28
+
29
+ response = HTTParty.get(request_url, :query => params)
30
+
31
+ if response.header.code == "401"
32
+ self.reset_access_token
33
+ params.merge!({ access_token: self.access_token })
34
+ response = HTTParty.get(request_url, :query => params)
35
+ end
36
+
37
+ capture response
38
+
39
+ APIObject.new(response.body, self.access_token)
40
+ end
41
+
42
+ def build_url(call_chain)
43
+ path = ""
44
+ params = { access_token: self.access_token }
45
+
46
+ call_chain.each do |c|
47
+ path += "#{c[:name]}/"
48
+ path += "#{c[:resource]}/" if c.has_key?(:resource)
49
+ params.merge!(c[:params]) if c.has_key?(:params)
50
+ end
51
+
52
+ return path, params
53
+ end
54
+ end
55
+ end
@@ -1,5 +1,8 @@
1
1
  module Viki
2
2
  module Utilities
3
+ URL_NAMESPACES = [:movies, :series, :episodes, :music_videos, :newscasts, :newsclips,
4
+ :artists, :featured, :coming_soon, :subtitles, :hardsubs, :genres, :countries,
5
+ :search, :languages]
3
6
  private
4
7
 
5
8
  def capture(response)
data/lib/viki/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Viki
2
- VERSION = "0.0.5"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -2,25 +2,19 @@ require 'spec_helper'
2
2
 
3
3
  describe Viki::Client do
4
4
 
5
- describe "#get" do
5
+ describe "method delegation" do
6
6
  before { Viki::Client.any_instance.stub(:auth_request) }
7
- subject { Viki::Client.new('chickenrice', 'soronerychickenrice') }
8
7
 
9
- it "should perform a request to the right url given a call chain" do
10
- subject.movies(1234).subtitles('en')
11
- subject.should_receive(:request).with([{ :name => :movies, :resource => 1234 },
12
- { :name => :subtitles, :resource => "en" }])
13
- subject.get
8
+ def client
9
+ Viki::Client.new('chickenrice', 'soronerychickenrice')
14
10
  end
15
11
 
16
- it "should perform a request with the right params given a call chain" do
17
- subject.movies(1234, {genre: 2})
18
- subject.should_receive(:request).with([{ :name => :movies, :resource => 1234, :params => {genre: 2}}])
19
- subject.get
12
+ it "should raise NoMethodError error if part of the call chain is not part of the URL_NAMESPACES list" do
13
+ expect { client.methodwrong.subtitles('en') }.to raise_error(NoMethodError)
20
14
  end
21
15
 
22
- it "should raise NoMethodError error if part of the call chain is not part of the URL_NAMESPACES list" do
23
- expect { subject.methodwrong.subtitles('en') }.to raise_error(NoMethodError)
16
+ it "should return a request object when method_missing is called" do
17
+ client.movies(1234).should be_an_instance_of(Viki::Request)
24
18
  end
25
19
  end
26
20
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Viki::Request do
4
+ describe "#get" do
5
+ before do
6
+ Viki::Client.any_instance.stub(:auth_request)
7
+ Viki::Request.any_instance.stub(:request) { Viki::APIObject }
8
+ end
9
+
10
+ def client
11
+ Viki.new('chickenrice', 'soronerychickenrice')
12
+ end
13
+
14
+ it "should perform a request to the right url given a call chain" do
15
+ req = client.movies(1234).subtitles('en')
16
+ req.should_receive(:request).with([{ :name => :movies, :resource => 1234 },
17
+ { :name => :subtitles, :resource => "en" }])
18
+ req.get
19
+ end
20
+
21
+ it "should perform a request with the right params given a call chain" do
22
+ req = client.movies(1234, { genre: 2 })
23
+ req.should_receive(:request).with([{ :name => :movies, :resource => 1234, :params => { genre: 2 } }])
24
+ req.get
25
+ end
26
+
27
+ it "should raise NoMethodError error if part of the call chain is not part of the URL_NAMESPACES list" do
28
+ expect { client.methodwrong.subtitles('en') }.to raise_error(NoMethodError)
29
+ end
30
+ end
31
+ end
@@ -128,7 +128,7 @@ describe "Viki" do
128
128
  end
129
129
  end
130
130
 
131
- describe "Renew Expired Access Token" do
131
+ describe "Access token renewal" do
132
132
  it "should request a new access token when an endpoint returns 401 and client currently has an access_token" do
133
133
  VCR.use_cassette "auth/expired_access_token" do
134
134
  client.access_token.should_not be_empty
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: viki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-07-04 00:00:00.000000000Z
14
+ date: 2012-07-10 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
18
- requirement: &70100608348400 !ruby/object:Gem::Requirement
18
+ requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
@@ -23,10 +23,15 @@ dependencies:
23
23
  version: 2.10.0
24
24
  type: :development
25
25
  prerelease: false
26
- version_requirements: *70100608348400
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: 2.10.0
27
32
  - !ruby/object:Gem::Dependency
28
33
  name: vcr
29
- requirement: &70100608347900 !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
30
35
  none: false
31
36
  requirements:
32
37
  - - ~>
@@ -34,10 +39,15 @@ dependencies:
34
39
  version: 2.2.2
35
40
  type: :development
36
41
  prerelease: false
37
- version_requirements: *70100608347900
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 2.2.2
38
48
  - !ruby/object:Gem::Dependency
39
49
  name: webmock
40
- requirement: &70100608347440 !ruby/object:Gem::Requirement
50
+ requirement: !ruby/object:Gem::Requirement
41
51
  none: false
42
52
  requirements:
43
53
  - - ~>
@@ -45,10 +55,15 @@ dependencies:
45
55
  version: 1.8.7
46
56
  type: :development
47
57
  prerelease: false
48
- version_requirements: *70100608347440
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: 1.8.7
49
64
  - !ruby/object:Gem::Dependency
50
65
  name: excon
51
- requirement: &70100608346980 !ruby/object:Gem::Requirement
66
+ requirement: !ruby/object:Gem::Requirement
52
67
  none: false
53
68
  requirements:
54
69
  - - ~>
@@ -56,10 +71,15 @@ dependencies:
56
71
  version: 0.9.6
57
72
  type: :development
58
73
  prerelease: false
59
- version_requirements: *70100608346980
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: 0.9.6
60
80
  - !ruby/object:Gem::Dependency
61
81
  name: httparty
62
- requirement: &70100608346520 !ruby/object:Gem::Requirement
82
+ requirement: !ruby/object:Gem::Requirement
63
83
  none: false
64
84
  requirements:
65
85
  - - ~>
@@ -67,10 +87,15 @@ dependencies:
67
87
  version: 0.8.3
68
88
  type: :runtime
69
89
  prerelease: false
70
- version_requirements: *70100608346520
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ version: 0.8.3
71
96
  - !ruby/object:Gem::Dependency
72
97
  name: multi_json
73
- requirement: &70100608346060 !ruby/object:Gem::Requirement
98
+ requirement: !ruby/object:Gem::Requirement
74
99
  none: false
75
100
  requirements:
76
101
  - - ~>
@@ -78,7 +103,12 @@ dependencies:
78
103
  version: 1.3.6
79
104
  type: :runtime
80
105
  prerelease: false
81
- version_requirements: *70100608346060
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ version: 1.3.6
82
112
  description: Viki-gem is an official wrapper gem for the Viki V3 API.
83
113
  email:
84
114
  - engineering@viki.com
@@ -97,11 +127,13 @@ files:
97
127
  - lib/viki/client.rb
98
128
  - lib/viki/error.rb
99
129
  - lib/viki/request.rb
130
+ - lib/viki/transport.rb
100
131
  - lib/viki/utilities.rb
101
132
  - lib/viki/version.rb
102
133
  - spec/lib/client_spec.rb
103
134
  - spec/lib/error_spec.rb
104
- - spec/requests/request_spec.rb
135
+ - spec/lib/request_spec.rb
136
+ - spec/requests/request_integration_spec.rb
105
137
  - spec/spec_config.rb.sample
106
138
  - spec/spec_helper.rb
107
139
  - spec/support/filter_shared_examples_spec.rb
@@ -127,14 +159,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
159
  version: '0'
128
160
  requirements: []
129
161
  rubyforge_project: viki
130
- rubygems_version: 1.8.6
162
+ rubygems_version: 1.8.24
131
163
  signing_key:
132
164
  specification_version: 3
133
165
  summary: A thin wrapper around the Viki V3 API
134
166
  test_files:
135
167
  - spec/lib/client_spec.rb
136
168
  - spec/lib/error_spec.rb
137
- - spec/requests/request_spec.rb
169
+ - spec/lib/request_spec.rb
170
+ - spec/requests/request_integration_spec.rb
138
171
  - spec/spec_config.rb.sample
139
172
  - spec/spec_helper.rb
140
173
  - spec/support/filter_shared_examples_spec.rb