kappa 0.1.3.pre → 0.1.4.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +62 -7
- data/lib/kappa.rb +0 -1
- data/lib/kappa/channel.rb +90 -64
- data/lib/kappa/connection.rb +54 -17
- data/lib/kappa/game.rb +34 -52
- data/lib/kappa/id_equality.rb +1 -0
- data/lib/kappa/images.rb +8 -22
- data/lib/kappa/stream.rb +41 -80
- data/lib/kappa/team.rb +40 -48
- data/lib/kappa/user.rb +31 -43
- data/lib/kappa/version.rb +1 -1
- data/lib/kappa/video.rb +19 -32
- metadata +19 -3
- data/lib/kappa/base.rb +0 -9
data/README.md
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
-
# <img src="
|
1
|
+
# <img src="https://raw.github.com/schmich/kappa/master/assets/kappa.png" /> Kappa
|
2
2
|
|
3
|
-
Kappa is a Ruby library for interfacing with the [Twitch.tv
|
3
|
+
Kappa is a Ruby library for interfacing with the [Twitch.tv API](https://github.com/justintv/Twitch-API).
|
4
|
+
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/kappa.png)](https://badge.fury.io/rb/kappa.png)
|
6
|
+
[![Build Status](https://secure.travis-ci.org/schmich/tome.png)](http://travis-ci.org/schmich/tome)
|
7
|
+
[![Dependency Status](https://gemnasium.com/schmich/kappa.png)](https://gemnasium.com/schmich/kappa)
|
8
|
+
[![Coverage Status](https://coveralls.io/repos/schmich/kappa/badge.png?branch=master)](https://coveralls.io/r/schmich/kappa?branch=master)
|
9
|
+
[![Code Climate](https://codeclimate.com/github/schmich/kappa.png)](https://codeclimate.com/github/schmich/kappa)
|
4
10
|
|
5
11
|
## Getting Started
|
6
|
-
============
|
7
12
|
|
8
13
|
`gem install kappa --pre`
|
9
14
|
|
@@ -12,15 +17,65 @@ require 'kappa'
|
|
12
17
|
|
13
18
|
include Kappa::V2
|
14
19
|
|
15
|
-
grubby = Channel.
|
20
|
+
grubby = Channel.get('followgrubby')
|
16
21
|
puts grubby.streaming?
|
17
22
|
```
|
18
23
|
|
19
|
-
##
|
20
|
-
|
24
|
+
## Examples
|
25
|
+
|
26
|
+
### Channels
|
27
|
+
|
28
|
+
Channels serve as the home location for a [user's](#users) content. Channels have a [stream](#streams), can run commercials, store [videos](#videos), display information and status, and have a customized page including banners and backgrounds.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
c = Channel.get('destiny')
|
32
|
+
|
33
|
+
c.nil? # Does the requested channel not exist? (ex: false)
|
34
|
+
c.name # Unique Twitch name (ex: "destiny")
|
35
|
+
c.display_name # Display name, e.g. name used for page title (ex: "Destiny")
|
36
|
+
c.stream # The currently live stream for this channel (ex: #<Kappa::V2::Stream> object)
|
37
|
+
c.url # The URL for the channel's main page (ex: "http://www.twitch.tv/destiny")
|
38
|
+
c.status # Current status (ex: "Destiny - Diamond I ADC - Number 1 Draven player in the entire Omaha (NE) metro area -watch from http://www.destiny.gg")
|
39
|
+
c.streaming? # Is the channel currently streaming? (ex: true)
|
40
|
+
c.game_name # Name of the primary game for this channel (ex: "League of Legends")
|
41
|
+
c.mature? # Does the channel have mature content? (ex: true)
|
42
|
+
c.id # Unique Twitch ID (ex: 18074328)
|
43
|
+
c.created_at # When the channel was created (ex: #<DateTime: 2010-11-22T04:14:56+00:00 ((2455523j,15296s,0n),+0s,2299161j)>)
|
44
|
+
c.updated_at # When the channel was last updated, e.g. last stream time (ex: #<DateTime: 2013-05-11T19:57:29+00:00 ((2456424j,71849s,0n),+0s,2299161j)>)
|
45
|
+
c.background_url # URL for background image (ex: "http://static-cdn.jtvnw.net/jtv_user_pictures/destiny-channel_background_image-ab706db77853e079.jpeg")
|
46
|
+
c.banner_url # URL for banner image (ex: "http://static-cdn.jtvnw.net/jtv_user_pictures/destiny-channel_header_image-d2b9b2452f67ec00-640x125.jpeg")
|
47
|
+
c.logo_url # URL for logo image (ex: "http://static-cdn.jtvnw.net/jtv_user_pictures/destiny-profile_image-168e66661c484c5e-300x300.jpeg")
|
48
|
+
c.video_banner_url # URL for the image shown when the stream is offline (ex: "http://static-cdn.jtvnw.net/jtv_user_pictures/destiny-channel_offline_image-7a21fd1bd88c4ac3-640x360.jpeg")
|
49
|
+
|
50
|
+
c.videos
|
51
|
+
c.teams
|
52
|
+
c.subscribers
|
53
|
+
c.editors
|
54
|
+
c.followers
|
55
|
+
c.has_subscriber?
|
56
|
+
```
|
57
|
+
|
58
|
+
### Streams
|
59
|
+
|
60
|
+
Streams are video broadcasts that are currently live. They have a [broadcaster](#users) and are part of a [channel](#channels).
|
61
|
+
|
62
|
+
### Users
|
63
|
+
|
64
|
+
These are members of the Twitch community who have a Twitch account. If broadcasting, they can own a [stream](#streams) that they can broadcast on their [channel](#channels). If mainly viewing, they might follow or subscribe to channels.
|
65
|
+
|
66
|
+
### Videos
|
67
|
+
|
68
|
+
Videos are broadcasts or highlights owned by a [channel](#channels). Broadcasts are unedited videos that are saved after a streaming session. Highlights are videos edited from broadcasts by the channel's owner.
|
69
|
+
|
70
|
+
### Teams
|
71
|
+
|
72
|
+
Teams are an organization of [channels](#channels).
|
73
|
+
|
74
|
+
### Games
|
75
|
+
|
76
|
+
Games are categories (e.g. League of Legends, Diablo 3) used by [streams](#streams) and [channels](#channels). Games can be searched for by query.
|
21
77
|
|
22
78
|
## Contributing
|
23
|
-
============
|
24
79
|
|
25
80
|
## License
|
26
81
|
|
data/lib/kappa.rb
CHANGED
data/lib/kappa/channel.rb
CHANGED
@@ -1,49 +1,73 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
1
3
|
module Kappa
|
4
|
+
# @private
|
2
5
|
class ChannelBase
|
3
6
|
include IdEquality
|
4
7
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
json = @connection.get("channels/#{arg}")
|
13
|
-
parse(json)
|
14
|
-
else
|
15
|
-
raise ArgumentError
|
8
|
+
def self.get(channel_name)
|
9
|
+
encoded_name = CGI.escape(channel_name)
|
10
|
+
json = connection.get("channels/#{encoded_name}")
|
11
|
+
if !json || json['status'] == 404
|
12
|
+
nil
|
13
|
+
else
|
14
|
+
new(json)
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
20
|
module Kappa::V2
|
22
|
-
# TODO:
|
23
|
-
# c.subscriptions
|
24
|
-
# c.start_commercial
|
25
|
-
# c.reset_stream_key
|
26
|
-
# c.foo = 'bar' ; c.save!
|
27
|
-
# Current user's channel
|
28
21
|
class Channel < Kappa::ChannelBase
|
29
|
-
|
30
|
-
|
22
|
+
# TODO:
|
23
|
+
# c.subscriptions
|
24
|
+
# c.start_commercial
|
25
|
+
# c.reset_stream_key
|
26
|
+
# c.foo = 'bar' ; c.save!
|
27
|
+
# Current user's channel
|
28
|
+
include Connection
|
29
|
+
|
30
|
+
def initialize(hash)
|
31
|
+
@id = hash['_id']
|
32
|
+
@background_url = hash['background']
|
33
|
+
@banner_url = hash['banner']
|
34
|
+
@created_at = DateTime.parse(hash['created_at'])
|
35
|
+
@display_name = hash['display_name']
|
36
|
+
@game_name = hash['game']
|
37
|
+
@logo_url = hash['logo']
|
38
|
+
@mature = hash['mature'] || false
|
39
|
+
@name = hash['name']
|
40
|
+
@status = hash['status']
|
41
|
+
@updated_at = DateTime.parse(hash['updated_at'])
|
42
|
+
@url = hash['url']
|
43
|
+
@video_banner_url = hash['video_banner']
|
44
|
+
|
45
|
+
@teams = []
|
46
|
+
teams = hash['teams']
|
47
|
+
teams.each do |team_json|
|
48
|
+
@teams << Team.new(team_json)
|
49
|
+
end
|
31
50
|
end
|
32
51
|
|
52
|
+
# This flag is specified by the owner of the channel.
|
53
|
+
# @return [Boolean] `true` if the channel has mature content, `false` otherwise.
|
33
54
|
def mature?
|
34
55
|
@mature
|
35
56
|
end
|
36
57
|
|
37
|
-
#
|
58
|
+
# Get the live stream associated with this channel.
|
59
|
+
# @return [Stream] Live stream object for this channel, or `nil` if the channel is not currently streaming.
|
60
|
+
# @see #streaming?
|
38
61
|
def stream
|
39
|
-
|
40
|
-
json = @connection.get("streams/#{@name}")
|
41
|
-
stream_json = json['stream']
|
42
|
-
Stream.new(stream_json, @connection)
|
62
|
+
Stream.get(@name)
|
43
63
|
end
|
44
64
|
|
65
|
+
# This makes a separate request to get the channel's stream. If you want to actually use
|
66
|
+
# the stream object, you should call `#stream` instead.
|
67
|
+
# @return [Boolean] `true` if the channel currently has a live stream, `false` otherwise.
|
68
|
+
# @see #stream
|
45
69
|
def streaming?
|
46
|
-
stream.
|
70
|
+
!stream.nil?
|
47
71
|
end
|
48
72
|
|
49
73
|
#
|
@@ -67,29 +91,25 @@ module Kappa::V2
|
|
67
91
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/channels.md#get-channelschannelfollows
|
68
92
|
# TODO: Warning: this set can be very large, this can run for very long time, recommend using :limit/:offset.
|
69
93
|
#
|
70
|
-
def followers(
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
user_json = follow_json['user']
|
80
|
-
user = User.new(user_json, @connection)
|
81
|
-
if ids.add?(user.id)
|
82
|
-
followers << user
|
83
|
-
if followers.count == limit
|
84
|
-
return followers
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
!current_followers.empty?
|
94
|
+
def followers(args = {})
|
95
|
+
params = {}
|
96
|
+
|
97
|
+
limit = args[:limit]
|
98
|
+
if limit && (limit < 100)
|
99
|
+
params[:limit] = limit
|
100
|
+
else
|
101
|
+
params[:limit] = 100
|
102
|
+
limit = 0
|
90
103
|
end
|
91
104
|
|
92
|
-
|
105
|
+
return connection.accumulate(
|
106
|
+
:path => "channels/#{@name}/follows",
|
107
|
+
:params => params,
|
108
|
+
:json => 'follows',
|
109
|
+
:sub_json => 'user',
|
110
|
+
:class => User,
|
111
|
+
:limit => limit
|
112
|
+
)
|
93
113
|
end
|
94
114
|
|
95
115
|
# TODO: Requires authentication.
|
@@ -105,36 +125,42 @@ module Kappa::V2
|
|
105
125
|
# Support User object or username (string)
|
106
126
|
end
|
107
127
|
|
128
|
+
# @return [Fixnum] Unique Twitch ID.
|
108
129
|
attr_reader :id
|
130
|
+
|
131
|
+
# @return [String] URL for background image.
|
109
132
|
attr_reader :background_url
|
133
|
+
|
134
|
+
# @return [String] URL for banner image.
|
110
135
|
attr_reader :banner_url
|
136
|
+
|
137
|
+
# @return [DateTime] When the channel was created.
|
111
138
|
attr_reader :created_at
|
112
|
-
|
139
|
+
|
140
|
+
# @return [String] Display name, e.g. name used for page title.
|
113
141
|
attr_reader :display_name
|
142
|
+
|
143
|
+
# @return [String] Name of the primary game for this channel.
|
114
144
|
attr_reader :game_name
|
145
|
+
|
146
|
+
# @return [String] URL for the logo image.
|
115
147
|
attr_reader :logo_url
|
148
|
+
|
149
|
+
# @return [String] Unique Twitch name.
|
116
150
|
attr_reader :name
|
151
|
+
|
152
|
+
# @return [String] Current status.
|
117
153
|
attr_reader :status
|
154
|
+
|
155
|
+
# @return [DateTime] When the channel was last updated, e.g. last stream time.
|
118
156
|
attr_reader :updated_at
|
157
|
+
|
158
|
+
# @return [String] The URL for the channel's main page.
|
119
159
|
attr_reader :url
|
160
|
+
|
161
|
+
# @return [String] URL for the image shown when the stream is offline.
|
120
162
|
attr_reader :video_banner_url
|
121
163
|
|
122
|
-
|
123
|
-
def parse(hash)
|
124
|
-
@id = hash['_id']
|
125
|
-
@background_url = hash['background']
|
126
|
-
@banner_url = hash['banner']
|
127
|
-
@created_at = DateTime.parse(hash['created_at'])
|
128
|
-
@stream_delay_sec = hash['delay']
|
129
|
-
@display_name = hash['display_name']
|
130
|
-
@game_name = hash['game']
|
131
|
-
@logo_url = hash['logo']
|
132
|
-
@mature = hash['mature'] || false
|
133
|
-
@name = hash['name']
|
134
|
-
@status = hash['status']
|
135
|
-
@updated_at = DateTime.parse(hash['updated_at'])
|
136
|
-
@url = hash['url']
|
137
|
-
@video_banner_url = hash['video_banner']
|
138
|
-
end
|
164
|
+
attr_reader :teams
|
139
165
|
end
|
140
166
|
end
|
data/lib/kappa/connection.rb
CHANGED
@@ -2,8 +2,11 @@ require 'httparty'
|
|
2
2
|
require 'addressable/uri'
|
3
3
|
require 'securerandom'
|
4
4
|
require 'json'
|
5
|
+
require 'singleton'
|
6
|
+
require 'set'
|
5
7
|
|
6
8
|
module Kappa
|
9
|
+
# @private
|
7
10
|
class ConnectionBase
|
8
11
|
include HTTParty
|
9
12
|
|
@@ -17,12 +20,6 @@ module Kappa
|
|
17
20
|
@last_request_time = Time.now - RATE_LIMIT_SEC
|
18
21
|
end
|
19
22
|
|
20
|
-
def self.instance
|
21
|
-
@connection ||= self.class_eval do
|
22
|
-
self.new
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
23
|
def get(path, query = nil)
|
27
24
|
request_url = @base_url + path
|
28
25
|
|
@@ -42,6 +39,36 @@ module Kappa
|
|
42
39
|
return JSON.parse(json)
|
43
40
|
end
|
44
41
|
|
42
|
+
def accumulate(args)
|
43
|
+
path = args[:path]
|
44
|
+
params = args[:params]
|
45
|
+
json = args[:json]
|
46
|
+
sub_json = args[:sub_json]
|
47
|
+
klass = args[:class]
|
48
|
+
limit = args[:limit]
|
49
|
+
|
50
|
+
objects = []
|
51
|
+
ids = Set.new
|
52
|
+
|
53
|
+
paginated(path, params) do |response_json|
|
54
|
+
current_objects = response_json[json]
|
55
|
+
current_objects.each do |object_json|
|
56
|
+
object_json = object_json[sub_json] if sub_json
|
57
|
+
object = klass.new(object_json)
|
58
|
+
if ids.add?(object.id)
|
59
|
+
objects << object
|
60
|
+
if objects.count == limit
|
61
|
+
return objects
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
!current_objects.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
return objects
|
70
|
+
end
|
71
|
+
|
45
72
|
def paginated(path, params = {})
|
46
73
|
limit = [params[:limit] || 100, 100].min
|
47
74
|
offset = params[:offset] || 0
|
@@ -100,19 +127,29 @@ module Kappa
|
|
100
127
|
end
|
101
128
|
|
102
129
|
module Kappa::V2
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
130
|
+
# @private
|
131
|
+
module Connection
|
132
|
+
class Impl < Kappa::ConnectionBase
|
133
|
+
include Singleton
|
134
|
+
|
135
|
+
private
|
136
|
+
def custom_headers
|
137
|
+
{ 'Accept' => 'application/vnd.twitchtv.v2+json' }
|
138
|
+
end
|
107
139
|
end
|
108
|
-
end
|
109
|
-
end
|
110
140
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
141
|
+
def self.included(base)
|
142
|
+
base.extend(ClassMethods)
|
143
|
+
end
|
144
|
+
|
145
|
+
def connection
|
146
|
+
Impl.instance
|
147
|
+
end
|
148
|
+
|
149
|
+
module ClassMethods
|
150
|
+
def connection
|
151
|
+
Impl.instance
|
152
|
+
end
|
116
153
|
end
|
117
154
|
end
|
118
155
|
end
|
data/lib/kappa/game.rb
CHANGED
@@ -1,43 +1,18 @@
|
|
1
1
|
module Kappa
|
2
|
+
# @private
|
2
3
|
class GameBase
|
3
4
|
include IdEquality
|
4
|
-
|
5
|
-
def initialize(arg)
|
6
|
-
case arg
|
7
|
-
when Hash
|
8
|
-
parse(arg)
|
9
|
-
else
|
10
|
-
raise ArgumentError
|
11
|
-
end
|
12
|
-
end
|
13
5
|
end
|
14
6
|
|
7
|
+
# @private
|
15
8
|
class GameSuggestionBase
|
16
9
|
include IdEquality
|
17
|
-
|
18
|
-
def initialize(arg)
|
19
|
-
case arg
|
20
|
-
when Hash
|
21
|
-
parse(arg)
|
22
|
-
else
|
23
|
-
raise ArgumentError
|
24
|
-
end
|
25
|
-
end
|
26
10
|
end
|
27
11
|
end
|
28
12
|
|
29
13
|
module Kappa::V2
|
30
14
|
class Game < Kappa::GameBase
|
31
|
-
|
32
|
-
attr_reader :name
|
33
|
-
attr_reader :giantbomb_id
|
34
|
-
attr_reader :box_images
|
35
|
-
attr_reader :logo_images
|
36
|
-
attr_reader :channel_count
|
37
|
-
attr_reader :viewer_count
|
38
|
-
|
39
|
-
private
|
40
|
-
def parse(hash)
|
15
|
+
def initialize(hash)
|
41
16
|
@channel_count = hash['channels']
|
42
17
|
@viewer_count = hash['viewers']
|
43
18
|
|
@@ -48,18 +23,18 @@ module Kappa::V2
|
|
48
23
|
@box_images = Images.new(game['box'])
|
49
24
|
@logo_images = Images.new(game['logo'])
|
50
25
|
end
|
51
|
-
end
|
52
26
|
|
53
|
-
class GameSuggestion < Kappa::GameSuggestionBase
|
54
27
|
attr_reader :id
|
55
28
|
attr_reader :name
|
56
29
|
attr_reader :giantbomb_id
|
57
|
-
attr_reader :popularity
|
58
30
|
attr_reader :box_images
|
59
31
|
attr_reader :logo_images
|
32
|
+
attr_reader :channel_count
|
33
|
+
attr_reader :viewer_count
|
34
|
+
end
|
60
35
|
|
61
|
-
|
62
|
-
def
|
36
|
+
class GameSuggestion < Kappa::GameSuggestionBase
|
37
|
+
def initialize(hash)
|
63
38
|
@id = hash['_id']
|
64
39
|
@name = hash['name']
|
65
40
|
@giantbomb_id = hash['giantbomb_id']
|
@@ -67,47 +42,54 @@ module Kappa::V2
|
|
67
42
|
@box_images = Images.new(hash['box'])
|
68
43
|
@logo_images = Images.new(hash['logo'])
|
69
44
|
end
|
45
|
+
|
46
|
+
attr_reader :id
|
47
|
+
attr_reader :name
|
48
|
+
attr_reader :giantbomb_id
|
49
|
+
attr_reader :popularity
|
50
|
+
attr_reader :box_images
|
51
|
+
attr_reader :logo_images
|
70
52
|
end
|
71
53
|
|
72
54
|
class Games
|
55
|
+
include Connection
|
56
|
+
|
73
57
|
#
|
74
58
|
# GET /games/top
|
75
59
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/games.md#get-gamestop
|
76
60
|
#
|
77
|
-
def top(
|
78
|
-
|
79
|
-
|
80
|
-
games = []
|
81
|
-
ids = Set.new
|
61
|
+
def self.top(args = {})
|
62
|
+
params = {}
|
82
63
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
if games.count == limit
|
90
|
-
return games
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
64
|
+
limit = args[:limit]
|
65
|
+
if limit && (limit < 100)
|
66
|
+
params[:limit] = limit
|
67
|
+
else
|
68
|
+
params[:limit] = 100
|
69
|
+
limit = 0
|
94
70
|
end
|
95
71
|
|
96
|
-
|
72
|
+
return connection.accumulate(
|
73
|
+
:path => 'games/top',
|
74
|
+
:params => params,
|
75
|
+
:json => 'top',
|
76
|
+
:class => Game,
|
77
|
+
:limit => limit
|
78
|
+
)
|
97
79
|
end
|
98
80
|
|
99
81
|
#
|
100
82
|
# GET /search/games
|
101
83
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/search.md#get-searchgames
|
102
84
|
#
|
103
|
-
def search(params = {})
|
85
|
+
def self.search(params = {})
|
104
86
|
live = params[:live] || false
|
105
87
|
name = params[:name]
|
106
88
|
|
107
89
|
games = []
|
108
90
|
ids = Set.new
|
109
91
|
|
110
|
-
json =
|
92
|
+
json = connection.get('search/games', :query => name, :type => 'suggest', :live => live)
|
111
93
|
all_games = json['games']
|
112
94
|
all_games.each do |game_json|
|
113
95
|
game = GameSuggestion.new(game_json)
|
data/lib/kappa/id_equality.rb
CHANGED
data/lib/kappa/images.rb
CHANGED
@@ -1,33 +1,19 @@
|
|
1
|
-
module Kappa
|
2
|
-
class
|
3
|
-
def initialize(
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
raise ArgumentError
|
9
|
-
end
|
1
|
+
module Kappa::V2
|
2
|
+
class Images
|
3
|
+
def initialize(hash)
|
4
|
+
@large_url = hash['large']
|
5
|
+
@medium_url = hash['medium']
|
6
|
+
@small_url = hash['small']
|
7
|
+
@template_url = hash['template']
|
10
8
|
end
|
11
|
-
end
|
12
|
-
end
|
13
9
|
|
14
|
-
module Kappa::V2
|
15
|
-
class Images < Kappa::ImagesBase
|
16
10
|
def url(width, height)
|
17
|
-
@template_url.gsub('{width}', width.to_s
|
11
|
+
@template_url.gsub('{width}', width.to_s).gsub('{height}', height.to_s)
|
18
12
|
end
|
19
13
|
|
20
14
|
attr_reader :large_url
|
21
15
|
attr_reader :medium_url
|
22
16
|
attr_reader :small_url
|
23
17
|
attr_reader :template_url
|
24
|
-
|
25
|
-
private
|
26
|
-
def parse(hash)
|
27
|
-
@large_url = hash['large']
|
28
|
-
@medium_url = hash['medium']
|
29
|
-
@small_url = hash['small']
|
30
|
-
@template_url = hash['template']
|
31
|
-
end
|
32
18
|
end
|
33
19
|
end
|
data/lib/kappa/stream.rb
CHANGED
@@ -1,54 +1,46 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
1
|
module Kappa
|
2
|
+
# @private
|
4
3
|
class StreamBase
|
5
4
|
include IdEquality
|
6
5
|
|
7
|
-
def
|
8
|
-
@connection = connection
|
9
|
-
parse(hash)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.get(stream_name, connection = default_connection)
|
6
|
+
def self.get(stream_name)
|
13
7
|
json = connection.get("streams/#{stream_name}")
|
14
8
|
stream = json['stream']
|
15
9
|
if json['status'] == 404 || !stream
|
16
10
|
nil
|
17
11
|
else
|
18
|
-
new(stream
|
12
|
+
new(stream)
|
19
13
|
end
|
20
14
|
end
|
21
|
-
|
22
|
-
private
|
23
|
-
def self.default_connection
|
24
|
-
self.class.module_class(:Connection).instance
|
25
|
-
end
|
26
15
|
end
|
27
16
|
end
|
28
17
|
|
29
18
|
module Kappa::V2
|
30
19
|
class Stream < Kappa::StreamBase
|
31
|
-
|
32
|
-
attr_reader :broadcaster
|
33
|
-
attr_reader :game_name
|
34
|
-
attr_reader :name
|
35
|
-
attr_reader :viewer_count
|
36
|
-
attr_reader :preview_url
|
37
|
-
attr_reader :channel
|
20
|
+
include Connection
|
38
21
|
|
39
|
-
|
40
|
-
def parse(hash)
|
22
|
+
def initialize(hash)
|
41
23
|
@id = hash['_id']
|
42
24
|
@broadcaster = hash['broadcaster']
|
43
25
|
@game_name = hash['game']
|
44
26
|
@name = hash['name']
|
45
27
|
@viewer_count = hash['viewers']
|
46
28
|
@preview_url = hash['preview']
|
47
|
-
@channel = Channel.new(hash['channel']
|
29
|
+
@channel = Channel.new(hash['channel'])
|
48
30
|
end
|
31
|
+
|
32
|
+
attr_reader :id
|
33
|
+
attr_reader :broadcaster
|
34
|
+
attr_reader :game_name
|
35
|
+
attr_reader :name
|
36
|
+
attr_reader :viewer_count
|
37
|
+
attr_reader :preview_url
|
38
|
+
attr_reader :channel
|
49
39
|
end
|
50
40
|
|
51
41
|
class Streams
|
42
|
+
include Connection
|
43
|
+
|
52
44
|
def self.all
|
53
45
|
end
|
54
46
|
|
@@ -76,76 +68,45 @@ module Kappa::V2
|
|
76
68
|
end
|
77
69
|
|
78
70
|
limit = args[:limit]
|
79
|
-
if limit && (limit <
|
71
|
+
if limit && (limit < 100)
|
80
72
|
params[:limit] = limit
|
81
73
|
else
|
82
|
-
params[:limit] =
|
74
|
+
params[:limit] = 100
|
83
75
|
limit = 0
|
84
76
|
end
|
85
77
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
stream = Stream.new(stream_json, connection)
|
94
|
-
if ids.add?(stream.id)
|
95
|
-
streams << stream
|
96
|
-
if streams.count == limit
|
97
|
-
return streams
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
!current_streams.empty?
|
103
|
-
end
|
104
|
-
|
105
|
-
streams
|
78
|
+
return connection.accumulate(
|
79
|
+
:path => 'streams',
|
80
|
+
:params => params,
|
81
|
+
:json => 'streams',
|
82
|
+
:class => Stream,
|
83
|
+
:limit => limit
|
84
|
+
)
|
106
85
|
end
|
107
86
|
|
108
87
|
#
|
109
88
|
# GET /streams/featured
|
110
89
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/streams.md#get-streamsfeatured
|
111
90
|
#
|
112
|
-
def self.featured(
|
113
|
-
|
114
|
-
|
115
|
-
streams = []
|
116
|
-
ids = Set.new
|
117
|
-
|
118
|
-
connection = Connection.instance
|
119
|
-
connection.paginated('streams/featured', params) do |json|
|
120
|
-
current_streams = json['featured']
|
121
|
-
current_streams.each do |featured_json|
|
122
|
-
# TODO: Capture more information from the featured_json structure (need a FeaturedStream class?)
|
123
|
-
stream_json = featured_json['stream']
|
124
|
-
stream = Stream.new(stream_json, connection)
|
125
|
-
if ids.add?(stream.id)
|
126
|
-
streams << stream
|
127
|
-
if streams.count == limit
|
128
|
-
return streams
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
91
|
+
def self.featured(args = {})
|
92
|
+
params = {}
|
132
93
|
|
133
|
-
|
94
|
+
limit = args[:limit]
|
95
|
+
if limit && (limit < 100)
|
96
|
+
params[:limit] = limit
|
97
|
+
else
|
98
|
+
params[:limit] = 100
|
99
|
+
limit = 0
|
134
100
|
end
|
135
101
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
super(arg, connection)
|
145
|
-
end
|
146
|
-
|
147
|
-
private
|
148
|
-
def parse(hash)
|
102
|
+
return connection.accumulate(
|
103
|
+
:path => 'streams/featured',
|
104
|
+
:params => params,
|
105
|
+
:json => 'featured',
|
106
|
+
:sub_json => 'stream',
|
107
|
+
:class => Stream,
|
108
|
+
:limit => limit
|
109
|
+
)
|
149
110
|
end
|
150
111
|
end
|
151
112
|
end
|
data/lib/kappa/team.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
module Kappa
|
2
|
+
# @private
|
2
3
|
class TeamBase
|
3
4
|
include IdEquality
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
#
|
7
|
+
# GET /teams/:team
|
8
|
+
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/teams.md#get-teamsteam
|
9
|
+
#
|
10
|
+
def self.get(team_name)
|
11
|
+
json = connection.get("teams/#{team_name}")
|
12
|
+
if json['status'] == 404
|
13
|
+
nil
|
14
|
+
else
|
15
|
+
new(json)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
end
|
@@ -19,26 +20,9 @@ end
|
|
19
20
|
|
20
21
|
module Kappa::V2
|
21
22
|
class Team < Kappa::TeamBase
|
22
|
-
|
23
|
-
# GET /teams/:team
|
24
|
-
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/teams.md#get-teamsteam
|
25
|
-
#
|
26
|
-
def intialize(arg, connection = Connection.instance)
|
27
|
-
super(arg, connection)
|
28
|
-
end
|
29
|
-
|
30
|
-
attr_reader :id
|
31
|
-
attr_reader :info
|
32
|
-
attr_reader :background_url
|
33
|
-
attr_reader :banner_url
|
34
|
-
attr_reader :logo_url
|
35
|
-
attr_reader :name
|
36
|
-
attr_reader :display_name
|
37
|
-
attr_reader :updated_at
|
38
|
-
attr_reader :created_at
|
23
|
+
include Connection
|
39
24
|
|
40
|
-
|
41
|
-
def parse(hash)
|
25
|
+
def initialize(hash)
|
42
26
|
@id = hash['_id']
|
43
27
|
@info = hash['info']
|
44
28
|
@background_url = hash['background']
|
@@ -49,35 +33,43 @@ module Kappa::V2
|
|
49
33
|
@updated_at = DateTime.parse(hash['updated_at'])
|
50
34
|
@created_at = DateTime.parse(hash['created_at'])
|
51
35
|
end
|
36
|
+
|
37
|
+
attr_reader :id
|
38
|
+
attr_reader :info
|
39
|
+
attr_reader :background_url
|
40
|
+
attr_reader :banner_url
|
41
|
+
attr_reader :logo_url
|
42
|
+
attr_reader :name
|
43
|
+
attr_reader :display_name
|
44
|
+
attr_reader :updated_at
|
45
|
+
attr_reader :created_at
|
52
46
|
end
|
53
47
|
|
54
48
|
class Teams
|
49
|
+
include Connection
|
50
|
+
|
55
51
|
#
|
56
52
|
# GET /teams
|
57
53
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/teams.md#get-teams
|
58
54
|
#
|
59
|
-
def all(
|
60
|
-
|
61
|
-
|
62
|
-
teams = []
|
63
|
-
ids = Set.new
|
64
|
-
|
65
|
-
@conn.paginated('teams', params) do |json|
|
66
|
-
teams_json = json['teams']
|
67
|
-
teams_json.each do |team_json|
|
68
|
-
team = Team.new(team_json, @conn)
|
69
|
-
if ids.add?(team.id)
|
70
|
-
teams << team
|
71
|
-
if teams.count == limit
|
72
|
-
return teams
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
55
|
+
def self.all(args = {})
|
56
|
+
params = {}
|
76
57
|
|
77
|
-
|
58
|
+
limit = args[:limit]
|
59
|
+
if limit && (limit < 100)
|
60
|
+
params[:limit] = limit
|
61
|
+
else
|
62
|
+
params[:limit] = 100
|
63
|
+
limit = 0
|
78
64
|
end
|
79
65
|
|
80
|
-
|
66
|
+
return connection.accumulate(
|
67
|
+
:path => 'teams',
|
68
|
+
:params => params,
|
69
|
+
:json => 'teams',
|
70
|
+
:class => Team,
|
71
|
+
:limit => limit
|
72
|
+
)
|
81
73
|
end
|
82
74
|
end
|
83
75
|
end
|
data/lib/kappa/user.rb
CHANGED
@@ -1,34 +1,37 @@
|
|
1
1
|
module Kappa
|
2
|
+
# @private
|
2
3
|
class UserBase
|
3
4
|
include IdEquality
|
4
5
|
|
5
|
-
def initialize(hash, connection = self.class.default_connection)
|
6
|
-
@connection = connection
|
7
|
-
parse(hash)
|
8
|
-
end
|
9
|
-
|
10
6
|
#
|
11
7
|
# GET /users/:user
|
12
8
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/users.md#get-usersuser
|
13
9
|
#
|
14
|
-
def self.get(user_name
|
10
|
+
def self.get(user_name)
|
15
11
|
json = connection.get("users/#{user_name}")
|
16
12
|
if json['status'] == 404
|
17
13
|
nil
|
18
14
|
else
|
19
|
-
new(json
|
15
|
+
new(json)
|
20
16
|
end
|
21
17
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def self.default_connection
|
25
|
-
self.class.module_class(:Connection).instance
|
26
|
-
end
|
27
18
|
end
|
28
19
|
end
|
29
20
|
|
30
21
|
module Kappa::V2
|
31
22
|
class User < Kappa::UserBase
|
23
|
+
include Connection
|
24
|
+
|
25
|
+
def initialize(hash)
|
26
|
+
@id = hash['_id']
|
27
|
+
@created_at = DateTime.parse(hash['created_at'])
|
28
|
+
@display_name = hash['display_name']
|
29
|
+
@logo_url = hash['logo']
|
30
|
+
@name = hash['name']
|
31
|
+
@staff = hash['staff'] || false
|
32
|
+
@updated_at = DateTime.parse(hash['updated_at'])
|
33
|
+
end
|
34
|
+
|
32
35
|
def channel
|
33
36
|
# TODO
|
34
37
|
end
|
@@ -54,28 +57,24 @@ module Kappa::V2
|
|
54
57
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/follows.md#get-usersuserfollowschannels
|
55
58
|
#
|
56
59
|
def following(params = {})
|
57
|
-
|
58
|
-
|
59
|
-
channels = []
|
60
|
-
ids = Set.new
|
61
|
-
|
62
|
-
@connection.paginated("users/#{@name}/follows/channels", params) do |json|
|
63
|
-
current_channels = json['follows']
|
64
|
-
current_channels.each do |follow_json|
|
65
|
-
channel_json = follow_json['channel']
|
66
|
-
channel = Channel.new(channel_json, @connection)
|
67
|
-
if ids.add?(channel.id)
|
68
|
-
channels << channel
|
69
|
-
if channels.count == limit
|
70
|
-
return channels
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
60
|
+
params = {}
|
74
61
|
|
75
|
-
|
62
|
+
limit = args[:limit]
|
63
|
+
if limit && (limit < 100)
|
64
|
+
params[:limit] = limit
|
65
|
+
else
|
66
|
+
params[:limit] = 100
|
67
|
+
limit = 0
|
76
68
|
end
|
77
69
|
|
78
|
-
|
70
|
+
return connection.accumulate(
|
71
|
+
:path => "users/#{@name}/follows/channels",
|
72
|
+
:params => params,
|
73
|
+
:json => 'follows',
|
74
|
+
:sub_json => 'channel',
|
75
|
+
:class => Channel,
|
76
|
+
:limit => limit
|
77
|
+
)
|
79
78
|
end
|
80
79
|
|
81
80
|
#
|
@@ -83,7 +82,7 @@ module Kappa::V2
|
|
83
82
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/follows.md#get-usersuserfollowschannelstarget
|
84
83
|
#
|
85
84
|
def following?(channel_name)
|
86
|
-
json =
|
85
|
+
json = connection.get("users/#{@name}/follows/channels/#{channel_name}")
|
87
86
|
status = json['status']
|
88
87
|
return !status || (status != 404)
|
89
88
|
end
|
@@ -98,16 +97,5 @@ module Kappa::V2
|
|
98
97
|
# TODO: Authenticated user attributes.
|
99
98
|
# attr_reader :email
|
100
99
|
# def partnered?
|
101
|
-
|
102
|
-
private
|
103
|
-
def parse(hash)
|
104
|
-
@id = hash['_id']
|
105
|
-
@created_at = DateTime.parse(hash['created_at'])
|
106
|
-
@display_name = hash['display_name']
|
107
|
-
@logo_url = hash['logo']
|
108
|
-
@name = hash['name']
|
109
|
-
@staff = hash['staff'] || false
|
110
|
-
@updated_at = DateTime.parse(hash['updated_at'])
|
111
|
-
end
|
112
100
|
end
|
113
101
|
end
|
data/lib/kappa/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
$version = '0.1.
|
1
|
+
$version = '0.1.4.pre'
|
data/lib/kappa/video.rb
CHANGED
@@ -1,31 +1,35 @@
|
|
1
1
|
module Kappa
|
2
|
+
# @private
|
2
3
|
class VideoBase
|
3
4
|
include IdEquality
|
4
5
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
case arg
|
9
|
-
when Hash
|
10
|
-
parse(arg)
|
11
|
-
when String
|
12
|
-
json = @connection.get("videos/#{arg}")
|
13
|
-
parse(json)
|
14
|
-
else
|
15
|
-
raise ArgumentError
|
16
|
-
end
|
6
|
+
def self.get(id)
|
7
|
+
json = connection.get("videos/#{id}")
|
8
|
+
new(json)
|
17
9
|
end
|
18
10
|
end
|
19
11
|
end
|
20
12
|
|
21
13
|
module Kappa::V2
|
22
14
|
class Video < Kappa::VideoBase
|
23
|
-
|
24
|
-
|
15
|
+
include Connection
|
16
|
+
|
17
|
+
def initialize(hash)
|
18
|
+
@id = hash['id']
|
19
|
+
@title = hash['title']
|
20
|
+
@recorded_at = DateTime.parse(hash['recorded_at'])
|
21
|
+
@url = hash['url']
|
22
|
+
@view_count = hash['views']
|
23
|
+
@description = hash['description']
|
24
|
+
@length_sec = hash['length']
|
25
|
+
@game_name = hash['game']
|
26
|
+
@preview_url = hash['preview']
|
27
|
+
@channel_name = hash['channel']['name']
|
28
|
+
# @channel_display_name = json['channel']['display_name']
|
25
29
|
end
|
26
30
|
|
27
31
|
def channel
|
28
|
-
Channel.new(
|
32
|
+
Channel.new(connection.get("channels/#{@channel_name}"))
|
29
33
|
end
|
30
34
|
|
31
35
|
attr_reader :id
|
@@ -40,23 +44,6 @@ module Kappa::V2
|
|
40
44
|
attr_reader :preview_url
|
41
45
|
# TODO: Move this under "v.channel.name" and force the query if other attributes are requested.
|
42
46
|
attr_reader :channel_name
|
43
|
-
|
44
|
-
private
|
45
|
-
def parse(hash)
|
46
|
-
@conn = conn
|
47
|
-
|
48
|
-
@id = hash['id']
|
49
|
-
@title = hash['title']
|
50
|
-
@recorded_at = DateTime.parse(hash['recorded_at'])
|
51
|
-
@url = hash['url']
|
52
|
-
@view_count = hash['views']
|
53
|
-
@description = hash['description']
|
54
|
-
@length_sec = hash['length']
|
55
|
-
@game_name = hash['game']
|
56
|
-
@preview_url = hash['preview']
|
57
|
-
@channel_name = hash['channel']['name']
|
58
|
-
# @channel_display_name = json['channel']['display_name']
|
59
|
-
end
|
60
47
|
end
|
61
48
|
|
62
49
|
class Videos
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kappa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4.pre
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -91,6 +91,22 @@ dependencies:
|
|
91
91
|
- - ! '>='
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: 2.13.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: coveralls
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
94
110
|
description: ! " A Ruby library for interfacing with the Twitch.tv Kraken API\n
|
95
111
|
\ including users, channels, streams, and followers.\n"
|
96
112
|
email: schmch@gmail.com
|
@@ -98,7 +114,6 @@ executables: []
|
|
98
114
|
extensions: []
|
99
115
|
extra_rdoc_files: []
|
100
116
|
files:
|
101
|
-
- lib/kappa/base.rb
|
102
117
|
- lib/kappa/channel.rb
|
103
118
|
- lib/kappa/connection.rb
|
104
119
|
- lib/kappa/game.rb
|
@@ -137,3 +152,4 @@ signing_key:
|
|
137
152
|
specification_version: 3
|
138
153
|
summary: Ruby library for interfacing with the Twitch.tv Kraken API.
|
139
154
|
test_files: []
|
155
|
+
has_rdoc:
|