jtv 0.0.3 → 1.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,3 +6,8 @@
6
6
 
7
7
  # v0.0.3
8
8
  * Added JtvSearch
9
+
10
+ # v1.0.0.alpha1
11
+ * Complete rework of the public interface
12
+ * Includes access to Stream API
13
+
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Mockra
1
+ Copyright (c) 2012 David Ratajczak
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Jtv
2
2
 
3
- This gem allows you to quickly add Justin.TV integration to your Ruby applications. Jtv is a useful tool for providing a list of livestreams, as well as embedding Justin.TV streams and clips.
3
+ This library provides a complete wrapper for the Justin.TV and Twitch.TV APIs.
4
4
 
5
5
  ## Installation
6
6
 
@@ -21,127 +21,79 @@ Or install it yourself as:
21
21
  If you want access to higher rate limits for your application, then you
22
22
  need to sign up for a [Justin.TV developer account](http://www.justin.tv/developer/activate).
23
23
 
24
- Once you have your API Keys, you'll need to set them up as environment
25
- variables for them to work with this gem. A great article on environment
26
- variables can be found at [Heroku](https://devcenter.heroku.com/articles/config-vars).
24
+ Once you have your API Keys, you can set them up using the configuration guide
25
+ below.
27
26
 
28
- ``` ruby
29
- ENV['JTV_CONSUMER_KEY']
30
- ENV['JTV_CONSUMER_SECRET']
31
- ```
32
-
33
- ## Usage
34
-
35
- The Jtv gem offers various classes depending on the type of information
36
- you're looking for. JtvChannel and JtvClip should be used for creating records.
37
- Jtv methods should be used for updating records.
38
-
39
- It's reccomended to cache your requests, and to always keep your
40
- account's rate limit in mind.
41
-
42
- Check out the [RDOC](http://rubydoc.info/github/Mockra/Jtv/).
43
-
44
- ### Jtv
27
+ ## Configuration
45
28
 
46
29
  ```ruby
47
- Jtv.channel_viewers( 'channel_handle' )
30
+ Jtv.configure do |config|
31
+ config.consumer_key = YOUR_CONSUMER_KEY
32
+ config.consumer_secret = YOUR_CONSUMER_SECRET
33
+ end
48
34
  ```
49
35
 
50
- This method will return nil if the stream is offline. Use this
51
- method for providing realtime viewer numbers and stream status.
52
-
53
- ### JtvSearch
54
-
55
- The JtvSearch provides access to the search api. If you pass
56
- JtvSearch.get a search query, it will return an array of channels.
57
- This class makes it easy to include a generic livestream list for your
58
- website.
36
+ If you want to make requests on behalf of a specific user, then you need to
37
+ instantiate a client.
59
38
 
60
39
  ```ruby
61
- streams = JtvSearch.get( 'league of legends', 50 )
62
- # You can pass the get method a search query, as well as
63
- # an optional stream limit that goes up to 100 and defaults to 20
40
+ @client = Jtv::Client.new oauth_token: 'users_token',
41
+ oauth_secret: 'users_secret'
42
+ ```
64
43
 
65
- streams.each do |stream|
44
+ ## Usage
66
45
 
67
- stream.id
68
- stream.title
69
- stream.url
70
- stream.viewers
71
- stream.image_huge
72
- stream.screen_cap_huge
46
+ The Jtv gem offers various methods depending on the type of information
47
+ you're looking for.
73
48
 
74
- end
75
- ```
49
+ It's recommended to cache your requests, and to always keep your
50
+ account's rate limit in mind.
76
51
 
77
- ### JtvChannel
52
+ Check out the [RDOC](http://rubydoc.info/github/Mockra/Jtv/).
78
53
 
79
- The JtvChannel class provides access to stream information for a
80
- specific channel. You'll need to pass the channel handle when you
81
- initialize your object.
54
+ ### Stream
82
55
 
83
- ```ruby
84
- channel = JtvChannel.new( 'channel_handle' )
85
- ```
56
+ #### Summary
86
57
 
87
- You'll then have access to the following information.
58
+ Returns aggregate stream information for all live channels (possibly scoped by
59
+ category).
88
60
 
89
61
  ```ruby
90
- channel.viewers
91
- # Number of current viewers on the stream, requires a second API call
92
- # If the stream is offline, this will return nil
62
+ Jtv.summary
63
+ # {"average_bitrate"=>0, "streams_count"=>4346, "viewers_count"=>"142733"}
93
64
 
94
- Jtv.channel_viewers( 'channel_handle' )
95
- # This will return nil for offline streams.
96
- # Use this method for updating current viewers
97
-
98
- channel.image_huge
99
- # 320x240 Image URL
100
-
101
- channel.screen_cap_huge
102
- # 320x240 Screen Capture URL
65
+ Jtv.summary channel: 'mockra'
66
+ # {"average_bitrate"=>0, "streams_count"=>0, "viewers_count"=>0}
67
+ ```
103
68
 
104
- channel.id
105
- # The channel handle
69
+ You can include a channel, language, or category in your search params.
106
70
 
107
- channel.embed
108
- #Code required to embed the Justin.TV Player, response looks like:
109
- ```
71
+ #### List
110
72
 
111
- ```
112
- <object type="application/x-shockwave-flash" height="295" width="353" id="jtv_player_flash" data="http://www.justin.tv/widgets/jtv_player.swf?channel=apidemo&quot; bgcolor="#000000"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://www.justin.tv/widgets/jtv_player.swf&quot; /><param name="flashvars" value="channel=apidemo&auto_play=false&start_volume=25" /></object>
113
- ```
73
+ Returns stream information for all live channels. The results are sorted by the
74
+ current number of viewers, with the most popular channels first.
114
75
 
115
76
  ```ruby
116
- channel.title
117
- channel.url
118
- channel.about
119
- channel.description
77
+ Jtv.list category: 'gaming', limit: 1
78
+ # [{'name' => 'live_user_wingsofdeath'...}]
120
79
  ```
121
80
 
122
- ### JtvClip
81
+ You can include a channel, category, title, language, limit, and offset.
123
82
 
124
- The JtvClip class provides access to specific clip information. To
125
- create a clip object, simply pass the clip id when you initialize the
126
- object.
83
+ #### Search
127
84
 
128
- ```ruby
129
- clip = JtvClip.new( 1278312 )
130
- ```
131
-
132
- The following method calls are available through the Clip class.
85
+ Returns stream information for the live channels that match a search query. The
86
+ results are sorted by the current number of viewers, with the most popular
87
+ channels first.
133
88
 
134
89
  ```ruby
135
- clip.description
136
- clip.title
137
- clip.id
138
- clip.tags
139
- clip.embed
140
- clip.image_huge
141
- clip.length
142
- clip.created_on
90
+ Jtv.search 'gaming', limit: 1
91
+ # [{'name' => 'live_user_steven_bonnell_ii'...}]
143
92
  ```
144
93
 
94
+ The first argument is your search query, and you can also pass limit and offset
95
+ as params.
96
+
145
97
  ## Contributing
146
98
 
147
99
  Contributions and feedback are more than welcome and highly encouraged.
@@ -2,11 +2,11 @@
2
2
  require File.expand_path('../lib/jtv/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["Mockra"]
5
+ gem.authors = ["David Ratajczak"]
6
6
  gem.email = ["david@mockra.com"]
7
- gem.description = %q{Gem for quickly accessing the Justin.TV API}
8
- gem.summary = %q{This tool provides simple Rails integration for common Justin.TV API calls.}
9
- gem.homepage = ""
7
+ gem.description = %q{Ruby wrapper for the Justin.tv and Twitch.tv API}
8
+ gem.summary = %q{Justin.tv and Twitch.tv API library}
9
+ gem.homepage = "http://mockra.com"
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
12
12
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -15,7 +15,12 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Jtv::VERSION
17
17
 
18
+ gem.license = 'MIT'
19
+
18
20
  gem.add_development_dependency 'rspec'
21
+ gem.add_development_dependency 'vcr'
22
+ gem.add_development_dependency 'fakeweb'
23
+ gem.add_dependency 'faraday'
19
24
  gem.add_dependency 'json'
20
- gem.add_dependency 'oauth'
25
+ gem.add_dependency 'simple_oauth'
21
26
  end
data/lib/jtv.rb CHANGED
@@ -1,61 +1,24 @@
1
1
  require "jtv/version"
2
- require 'jtv/jtv_channel'
3
- require 'jtv/jtv_clip'
4
- require 'jtv/jtv_search'
5
-
6
- require 'json'
2
+ require 'jtv/configuration'
3
+ require 'jtv/client'
7
4
 
8
5
  module Jtv
6
+ class << self
7
+ include Jtv::Configuration
9
8
 
10
- require 'oauth'
11
-
12
- # Get current viewers for a specific channel
13
- def self.channel_viewers( channel )
14
- client = Jtv::JtvClient.new
15
- json_data = client.get( "/stream/list.json?channel=#{channel}" )
16
- if json_data.body == "[]"
17
- return nil
18
- else
19
- data = JSON.parse( json_data.body )
9
+ def client
10
+ @client ||= Jtv::Client.new
20
11
  end
21
- data[0]['stream_count'].to_i
22
- end
23
-
24
- class JtvClient
25
12
 
26
- # Set API Keys through environment variables.
27
- CONSUMER_KEY = ENV['JTV_CONSUMER_KEY']
28
- CONSUMER_SECRET = ENV['JTV_CONSUMER_SECRET']
29
-
30
- def initialize
31
- @consumer = OAuth::Consumer.new(
32
- CONSUMER_KEY,
33
- CONSUMER_SECRET,
34
- :site => "http://api.justin.tv",
35
- :http_method => :get
36
- )
13
+ def respond_to_missing?(method_name, include_private=false)
14
+ client.respond_to?(method_name, include_private) || super
37
15
  end
38
16
 
39
- def get(path, access_token=nil)
40
- (access_token || default_token).get("/api#{path}")
41
- end
17
+ private
42
18
 
43
- def post(path, post_params, access_token=nil)
44
- (access_token || default_token).post("/api#{path}", post_params)
45
- end
46
-
47
- def make_request_token
48
- @consumer.get_request_token
49
- end
50
-
51
- def exchange_request_token_for_access_token(request_token)
52
- request_token.get_access_token
53
- end
54
-
55
- private
56
- def default_token
57
- OAuth::AccessToken.new @consumer
19
+ def method_missing method_name, *args, &block
20
+ return super unless client.respond_to?(method_name)
21
+ client.send(method_name, *args, &block)
58
22
  end
59
23
  end
60
-
61
24
  end
@@ -0,0 +1,44 @@
1
+ require 'simple_oauth'
2
+ require 'json'
3
+ require 'faraday'
4
+ require 'jtv/defaults'
5
+ require 'jtv/stream'
6
+
7
+ module Jtv
8
+ class Client
9
+ include Jtv::Defaults
10
+ include Jtv::Stream
11
+
12
+ def initialize args = {}
13
+ args.each do |key, value|
14
+ send "#{key}=", value
15
+ end
16
+ end
17
+
18
+ def get path, params = {}
19
+ get_json :get, path, params
20
+ end
21
+
22
+ private
23
+
24
+ def get_json method, path, params
25
+ response = request(method, path, params)
26
+ JSON.parse response[:body]
27
+ end
28
+
29
+ def request method, path, params
30
+ connection.send method, path, params do |req|
31
+ req.headers[:authorization] = req_header(method, path, params).to_s
32
+ end.env
33
+ end
34
+
35
+ def connection
36
+ @connection ||= Faraday.new 'http://api.justin.tv', options
37
+ end
38
+
39
+ def req_header method, path, params
40
+ uri = URI "http://api.justin.tv#{path}"
41
+ SimpleOAuth::Header.new method, uri, params, credentials
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ module Jtv
2
+ module Configuration
3
+ attr_accessor :consumer_key, :consumer_secret
4
+
5
+ def configure
6
+ yield self
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ module Jtv
2
+ module Defaults
3
+ attr_accessor :oauth_token, :oauth_secret
4
+
5
+ def credentials
6
+ { consumer_key: Jtv.consumer_key,
7
+ consumer_secret: Jtv.consumer_secret,
8
+ token: oauth_token || Jtv.oauth_token,
9
+ token_secret: oauth_secret || Jtv.oauth_secret }
10
+ end
11
+
12
+ private
13
+
14
+ def options
15
+ { headers: {
16
+ accept: 'application/json',
17
+ user_agent: 'Jtv Gem' },
18
+ request: {
19
+ open_timeout: 2,
20
+ timeout: 5 } }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ require 'uri'
2
+
3
+ module Jtv
4
+ module Stream
5
+ def summary params = {}
6
+ get 'stream/summary', params
7
+ end
8
+
9
+ def list params = {}
10
+ get 'stream/list', params
11
+ end
12
+
13
+ def search query, params = {}
14
+ query = URI.escape query
15
+ get "stream/search/#{query}.json", params
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Jtv
2
- VERSION = "0.0.3"
2
+ VERSION = "1.0.0.alpha1"
3
3
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ require 'vcr_config'
3
+
4
+ describe Jtv::Stream do
5
+ describe '#summary' do
6
+ use_vcr_cassette
7
+
8
+ it 'fetches a live channel' do
9
+ summary = Jtv.summary channel: 'wingsofdeath'
10
+ expect(summary['viewers_count']).to eq '14175'
11
+ end
12
+ end
13
+
14
+ describe '#list' do
15
+ use_vcr_cassette
16
+
17
+ it 'returns a list of streams for a category' do
18
+ list = Jtv.list category: 'gaming'
19
+ expect(list.count).to eq 50
20
+ expect(list.first['title']).to match(/wingsofdeath/i)
21
+ end
22
+ end
23
+
24
+ describe '#search' do
25
+ use_vcr_cassette
26
+
27
+ it 'returns streams based on search query' do
28
+ search = Jtv.search 'league of legends', limit: 10
29
+ expect(search.count).to eq 10
30
+ expect(search.first['category']).to eq 'gaming'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ require_relative '../../lib/jtv/client'
2
+
3
+ describe Jtv::Client do
4
+ let(:client) { Jtv::Client.new }
5
+ let(:request) { Object.new }
6
+
7
+ describe '#get' do
8
+ it 'fetches JSON based on method, path, and params' do
9
+ client.should_receive(:get_json).with(:get, '/test/', {})
10
+ client.get '/test/'
11
+ end
12
+ end
13
+
14
+ context 'when including defaults' do
15
+ it 'has access to oauth details' do
16
+ expect(client).to respond_to :oauth_token
17
+ end
18
+ end
19
+
20
+ context 'when including stream' do
21
+ it 'has access to summary, list, and search' do
22
+ expect(client).to respond_to :summary
23
+ expect(client).to respond_to :list
24
+ expect(client).to respond_to :search
25
+ end
26
+
27
+ end
28
+ end