kappa 0.1.5.pre → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +99 -35
- data/lib/kappa.rb +0 -78
- data/lib/kappa/channel.rb +60 -42
- data/lib/kappa/connection.rb +17 -28
- data/lib/kappa/game.rb +85 -28
- data/lib/kappa/images.rb +17 -0
- data/lib/kappa/stream.rb +100 -37
- data/lib/kappa/team.rb +51 -27
- data/lib/kappa/user.rb +69 -38
- data/lib/kappa/version.rb +1 -1
- data/lib/kappa/video.rb +64 -17
- metadata +51 -17
data/README.md
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# <img src="https://raw.github.com/schmich/kappa/master/assets/kappa.png" /> Kappa
|
2
2
|
|
3
|
-
Kappa is
|
3
|
+
Kappa is the Ruby library for interfacing with the [Twitch.tv API](https://github.com/justintv/Twitch-API).
|
4
4
|
|
5
|
-
[](
|
6
|
-
[](http://rubygems.org/gems/kappa)
|
6
|
+
[](http://travis-ci.org/schmich/kappa)
|
7
7
|
[](https://gemnasium.com/schmich/kappa)
|
8
8
|
[](https://coveralls.io/r/schmich/kappa?branch=master)
|
9
9
|
[](https://codeclimate.com/github/schmich/kappa)
|
10
10
|
|
11
11
|
## Getting Started
|
12
12
|
|
13
|
-
`gem install kappa
|
13
|
+
`gem install kappa`
|
14
14
|
|
15
15
|
```ruby
|
16
16
|
require 'kappa'
|
@@ -23,60 +23,124 @@ puts grubby.streaming?
|
|
23
23
|
|
24
24
|
## Examples
|
25
25
|
|
26
|
-
### Channels
|
26
|
+
### <a id="channels"></a>Channels
|
27
27
|
|
28
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
29
|
|
30
|
+
See also [`Kappa::V2::Channel`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Channel) documentation.
|
31
|
+
|
30
32
|
```ruby
|
31
33
|
c = Channel.get('destiny')
|
32
|
-
|
33
|
-
c.
|
34
|
-
c.
|
35
|
-
c.
|
36
|
-
c.
|
37
|
-
c.
|
38
|
-
c.
|
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?
|
34
|
+
c.nil? # => false (channel exists)
|
35
|
+
c.stream # => #<Kappa::V2::Stream> (current live stream)
|
36
|
+
c.url # => "http://www.twitch.tv/destiny"
|
37
|
+
c.status # => "Destiny - Diamond I ADC - Number 1 Draven player..."
|
38
|
+
c.teams # => [#<Kappa::V2::Team>]
|
39
|
+
c.videos # => [#<Kappa::V2::Video>, ...]
|
40
|
+
c.followers # => [#<Kappa::V2::User>, ...]
|
56
41
|
```
|
57
42
|
|
58
|
-
### Streams
|
43
|
+
### <a id="streams"></a>Streams
|
44
|
+
|
45
|
+
Streams are video broadcasts that are currently live. They belong to a [user](#users) and are part of a [channel](#channels).
|
59
46
|
|
60
|
-
|
47
|
+
See also [`Kappa::V2::Stream`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Stream) and [`Kappa::V2::Streams`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Streams) documentation.
|
61
48
|
|
62
|
-
|
49
|
+
```ruby
|
50
|
+
s = Stream.get('idrajit')
|
51
|
+
s.nil? # => false (currently live)
|
52
|
+
s.game_name # => "StarCraft II: Heart of the Swarm"
|
53
|
+
s.viewer_count # => 7267
|
54
|
+
s.channel.url # => "http://www.twitch.tv/idrajit"
|
55
|
+
```
|
56
|
+
|
57
|
+
### <a id="users"></a>Users
|
63
58
|
|
64
59
|
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
60
|
|
66
|
-
|
61
|
+
See also [`Kappa::V2::User`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/User) documentation.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
u = User.get('snoopeh')
|
65
|
+
u.nil? # => false (user exists)
|
66
|
+
u.channel # => #<Kappa::V2::Channel>
|
67
|
+
u.following.map(&:name) # => ["national_esl1", "dreamhacklol", "riotgames"]
|
68
|
+
```
|
69
|
+
|
70
|
+
### <a id="videos"></a>Videos
|
67
71
|
|
68
72
|
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
73
|
|
70
|
-
|
74
|
+
See also [`Kappa::V2::Video`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Video) and [`Kappa::V2::Videos`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Videos) documentation.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
v = Video.get('a395995729')
|
78
|
+
v.nil? # => false (video exists)
|
79
|
+
v.title # => "DreamHack Open Stockholm 26-27 April"
|
80
|
+
v.game_name # => "StarCraft II: Heart of the Swarm"
|
81
|
+
v.recorded_at # => #<DateTime: 2013-04-26T18:33:48+00:00>
|
82
|
+
v.view_count # => 12506
|
83
|
+
```
|
84
|
+
|
85
|
+
### <a id="teams"></a>Teams
|
71
86
|
|
72
87
|
Teams are an organization of [channels](#channels).
|
73
88
|
|
74
|
-
|
89
|
+
See also [`Kappa::V2::Team`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Team) documentation.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
t = Team.get('teamliquid')
|
93
|
+
t.display_name # => "TeamLiquid"
|
94
|
+
t.info # => "TeamLiquid is awesome. and esports. video games. \n\n"
|
95
|
+
t.updated_at # => #<DateTime: 2013-04-27T16:58:55+00:00>
|
96
|
+
```
|
97
|
+
|
98
|
+
### <a id="games"></a>Games
|
75
99
|
|
76
100
|
Games are categories (e.g. League of Legends, Diablo 3) used by [streams](#streams) and [channels](#channels). Games can be searched for by query.
|
77
101
|
|
102
|
+
See also [`Kappa::V2::Game`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Game), [`Kappa::V2::Games`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/Games), and [`Kappa::V2::GameSuggestion`](http://rdoc.info/github/schmich/kappa/master/Kappa/V2/GameSuggestion) documentation.
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
top = Games.top(:limit => 3)
|
106
|
+
top.map(&:name) # => ["League of Legends", "Dota 2", "StarCraft II: Heart of the Swarm"]
|
107
|
+
```
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
g = Games.top(:limit => 1).first
|
111
|
+
g.name # => "League of Legends"
|
112
|
+
g.channel_count # => 906
|
113
|
+
g.viewer_count # => 79223
|
114
|
+
g.box_images.medium_url # =>"http://static-cdn.jtvnw.net/ttv-boxart/League%20of%20Legends-272x380.jpg"
|
115
|
+
```
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
s = Games.find(:name => 'diablo', :live => true)
|
119
|
+
s.map(&:name) # => ["Diablo III", "Diablo II", "Diablo", "Diablo II: Lord of Destruction"]
|
120
|
+
s.map(&:popularity) # => [120, 4, 1, 1]
|
121
|
+
```
|
122
|
+
|
123
|
+
## Documentation
|
124
|
+
|
125
|
+
Detailed API documentation is available at [http://rdoc.info/github/schmich/kappa/master/frames](http://rdoc.info/github/schmich/kappa/master/frames).
|
126
|
+
|
127
|
+
## Versioning
|
128
|
+
|
129
|
+
- TODO: Semantic versioning
|
130
|
+
- TODO: Twitch API versions
|
131
|
+
|
78
132
|
## Contributing
|
79
133
|
|
134
|
+
- [Fork and clone the repo.](http://help.github.com/fork-a-repo/)
|
135
|
+
- [Create a branch for your changes.](http://learn.github.com/p/branching.html)
|
136
|
+
- Run `bundle install` to install development requirements.
|
137
|
+
- Implement your feature or bug fix.
|
138
|
+
- Add specs under the `spec` folder to prevent regressions or to test new code.
|
139
|
+
- Add [YARD](http://rubydoc.info/docs/yard/file/docs/GettingStarted.md) documentation for new features. Run `rake yard` to view documentation.
|
140
|
+
- Run `rake coverage` to run specs with code coverage. All specs must pass; coverage must remain at 100%.
|
141
|
+
- Commit and push your changes.
|
142
|
+
- [Submit a pull request.](http://help.github.com/send-pull-requests/)
|
143
|
+
|
80
144
|
## License
|
81
145
|
|
82
146
|
Copyright © 2013 Chris Schmich
|
data/lib/kappa.rb
CHANGED
@@ -9,81 +9,3 @@ require 'kappa/user'
|
|
9
9
|
require 'kappa/images'
|
10
10
|
require 'kappa/twitch'
|
11
11
|
require 'kappa/version'
|
12
|
-
|
13
|
-
# TODO
|
14
|
-
# https://github.com/justintv/Twitch-API
|
15
|
-
# Blocks
|
16
|
-
# GET /users/:login/blocks
|
17
|
-
# PUT /users/:user/blocks/:target
|
18
|
-
# DELETE /users/:user/blocks/:target
|
19
|
-
# Channels
|
20
|
-
# - GET /channels/:channel
|
21
|
-
# GET /channel
|
22
|
-
# GET /channels/:channel/editors
|
23
|
-
# PUT /channels/:channel
|
24
|
-
# GET /channels/:channel/videos
|
25
|
-
# GET /channels/:channel/follows
|
26
|
-
# DELETE /channels/:channel/stream_key
|
27
|
-
# POST /channels/:channel/commercial
|
28
|
-
# Chat
|
29
|
-
# GET /chat/:channel
|
30
|
-
# GET /chat/emoticons
|
31
|
-
# Follows
|
32
|
-
# GET /channels/:channel/follows
|
33
|
-
# GET /users/:user/follows/channels
|
34
|
-
# GET /users/:user/follows/channels/:target
|
35
|
-
# PUT /users/:user/follows/channels/:target
|
36
|
-
# DELETE /users/:user/follows/channels/:target
|
37
|
-
# Games
|
38
|
-
# - GET /games/top
|
39
|
-
# Ingests
|
40
|
-
# GET /ingests
|
41
|
-
# Root
|
42
|
-
# GET /
|
43
|
-
# Search
|
44
|
-
# GET /search/streams
|
45
|
-
# - GET /search/games
|
46
|
-
# Streams
|
47
|
-
# - GET /streams/:channel
|
48
|
-
# - GET /streams
|
49
|
-
# GET /streams/featured
|
50
|
-
# GET /streams/summary
|
51
|
-
# GET /streams/followed
|
52
|
-
# Subscriptions
|
53
|
-
# GET /channels/:channel/subscriptions
|
54
|
-
# GET /channels/:channel/subscriptions/:user
|
55
|
-
# Teams
|
56
|
-
# GET /teams
|
57
|
-
# GET /teams/:team
|
58
|
-
# Users
|
59
|
-
# GET /users/:user
|
60
|
-
# GET /user
|
61
|
-
# GET /streams/followed
|
62
|
-
# Videos
|
63
|
-
# GET /videos/:id
|
64
|
-
# GET /videos/top
|
65
|
-
# GET /channels/:channel/videos
|
66
|
-
|
67
|
-
# Overarching
|
68
|
-
# - Common query syntax
|
69
|
-
# - Access to raw properties (e.g. stream['game'] or stream.raw('game'))
|
70
|
-
# - Paginated results take a block to allow for intermediate processing/termination
|
71
|
-
|
72
|
-
# t = Kappa::Client.new
|
73
|
-
# c = t.channel('lagtvmaximusblack')
|
74
|
-
# c.editors -> [...]
|
75
|
-
# c.videos -> [...]
|
76
|
-
# c.followers -> [...]
|
77
|
-
# c.subscriptions
|
78
|
-
# c.start_commercial
|
79
|
-
# c.reset_stream_key
|
80
|
-
# c... ; c.save!
|
81
|
-
# TODO: current user channel
|
82
|
-
|
83
|
-
# t = Kappa::Client.new
|
84
|
-
# t.streams.all
|
85
|
-
# t.streams.all(:limit => 10)
|
86
|
-
# t.streams.featured
|
87
|
-
# t.streams.where(:channel => 'lagtvmaximusblack')
|
88
|
-
# t.streams.where(:channel => [...], :game => '...', :embeddable => t/f, :hls => t/f)
|
89
|
-
# t.stream_summary
|
data/lib/kappa/channel.rb
CHANGED
@@ -1,24 +1,13 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
|
3
|
-
module Kappa
|
4
|
-
# @private
|
5
|
-
class ChannelBase
|
6
|
-
include IdEquality
|
7
|
-
|
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)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
3
|
module Kappa::V2
|
21
|
-
|
4
|
+
# Channels serve as the home location for a user's content. Channels have a stream, can run
|
5
|
+
# commercials, store videos, display information and status, and have a customized page including
|
6
|
+
# banners and backgrounds.
|
7
|
+
# @see .get Channel.get
|
8
|
+
# @see Stream
|
9
|
+
# @see User
|
10
|
+
class Channel
|
22
11
|
# TODO:
|
23
12
|
# c.subscriptions
|
24
13
|
# c.start_commercial
|
@@ -26,7 +15,9 @@ module Kappa::V2
|
|
26
15
|
# c.foo = 'bar' ; c.save!
|
27
16
|
# Current user's channel
|
28
17
|
include Connection
|
18
|
+
include Kappa::IdEquality
|
29
19
|
|
20
|
+
# @private
|
30
21
|
def initialize(hash)
|
31
22
|
@id = hash['_id']
|
32
23
|
@background_url = hash['background']
|
@@ -49,7 +40,22 @@ module Kappa::V2
|
|
49
40
|
end
|
50
41
|
end
|
51
42
|
|
52
|
-
#
|
43
|
+
# Get a channel by name.
|
44
|
+
# @param channel_name [String] The name of the channel to get. This is the same as the stream or user name.
|
45
|
+
# @return [Channel] A valid `Channel` object if the channel exists, `nil` otherwise.
|
46
|
+
def self.get(channel_name)
|
47
|
+
encoded_name = CGI.escape(channel_name)
|
48
|
+
json = connection.get("channels/#{encoded_name}")
|
49
|
+
|
50
|
+
# HTTP 422 can happen if the channel is associated with a Justin.tv account.
|
51
|
+
if !json || json['status'] == 404 || json['status'] == 422
|
52
|
+
nil
|
53
|
+
else
|
54
|
+
new(json)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Does this channel have mature content? This flag is specified by the owner of the channel.
|
53
59
|
# @return [Boolean] `true` if the channel has mature content, `false` otherwise.
|
54
60
|
def mature?
|
55
61
|
@mature
|
@@ -62,8 +68,8 @@ module Kappa::V2
|
|
62
68
|
Stream.get(@name)
|
63
69
|
end
|
64
70
|
|
65
|
-
#
|
66
|
-
# the stream object, you should call `#stream` instead.
|
71
|
+
# Does this channel currently have a live stream?
|
72
|
+
# @note This makes a separate request to get the channel's stream. If you want to actually use the stream object, you should call `#stream` instead.
|
67
73
|
# @return [Boolean] `true` if the channel currently has a live stream, `false` otherwise.
|
68
74
|
# @see #stream
|
69
75
|
def streaming?
|
@@ -74,6 +80,8 @@ module Kappa::V2
|
|
74
80
|
# GET /channels/:channel/editors
|
75
81
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/channels.md#get-channelschanneleditors
|
76
82
|
#
|
83
|
+
# @private
|
84
|
+
# Private until implemented.
|
77
85
|
def editors
|
78
86
|
# TODO
|
79
87
|
end
|
@@ -82,19 +90,41 @@ module Kappa::V2
|
|
82
90
|
# GET /channels/:channels/videos
|
83
91
|
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/videos.md#get-channelschannelvideos
|
84
92
|
#
|
93
|
+
# @private
|
94
|
+
# Private until implemented.
|
85
95
|
def videos(params = {})
|
86
96
|
# TODO
|
87
97
|
end
|
88
98
|
|
99
|
+
# TODO: Requires authentication.
|
100
|
+
# @private
|
101
|
+
# Private until implemented.
|
102
|
+
def subscribers
|
103
|
+
end
|
104
|
+
|
89
105
|
#
|
90
|
-
# GET /channels/:channel/
|
91
|
-
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/
|
92
|
-
# TODO: Warning: this set can be very large, this can run for very long time, recommend using :limit/:offset.
|
106
|
+
# GET /channels/:channel/subscriptions/:user
|
107
|
+
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/subscriptions.md#get-channelschannelsubscriptionsuser
|
93
108
|
#
|
94
|
-
|
109
|
+
# TODO: Requires authentication.
|
110
|
+
# @private
|
111
|
+
# Private until implemented.
|
112
|
+
def has_subscriber?(user)
|
113
|
+
# Support User object or username (string)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Get the users following this channel.
|
117
|
+
# @note The number of followers is potentially very large, so it's recommended that you specify a `:limit`.
|
118
|
+
# @param options [Hash] Filter criteria.
|
119
|
+
# @option options [Fixnum] :limit (none) Limit on the number of results returned.
|
120
|
+
# @option options [Fixnum] :offset (0) Offset into the result set to begin enumeration.
|
121
|
+
# @see User
|
122
|
+
# @see https://github.com/justintv/Twitch-API/blob/master/v2_resources/channels.md#get-channelschannelfollows GET /channels/:channel/follows
|
123
|
+
# @return [Array<User>] List of users following this channel.
|
124
|
+
def followers(options = {})
|
95
125
|
params = {}
|
96
126
|
|
97
|
-
limit =
|
127
|
+
limit = options[:limit]
|
98
128
|
if limit && (limit < 100)
|
99
129
|
params[:limit] = limit
|
100
130
|
else
|
@@ -112,19 +142,6 @@ module Kappa::V2
|
|
112
142
|
)
|
113
143
|
end
|
114
144
|
|
115
|
-
# TODO: Requires authentication.
|
116
|
-
def subscribers
|
117
|
-
end
|
118
|
-
|
119
|
-
#
|
120
|
-
# GET /channels/:channel/subscriptions/:user
|
121
|
-
# https://github.com/justintv/Twitch-API/blob/master/v2_resources/subscriptions.md#get-channelschannelsubscriptionsuser
|
122
|
-
#
|
123
|
-
# TODO: Requires authentication.
|
124
|
-
def has_subscriber?(user)
|
125
|
-
# Support User object or username (string)
|
126
|
-
end
|
127
|
-
|
128
145
|
# @return [Fixnum] Unique Twitch ID.
|
129
146
|
attr_reader :id
|
130
147
|
|
@@ -137,7 +154,7 @@ module Kappa::V2
|
|
137
154
|
# @return [DateTime] When the channel was created.
|
138
155
|
attr_reader :created_at
|
139
156
|
|
140
|
-
# @return [String]
|
157
|
+
# @return [String] User-friendly display name. This name is used for the channel's page title.
|
141
158
|
attr_reader :display_name
|
142
159
|
|
143
160
|
# @return [String] Name of the primary game for this channel.
|
@@ -149,10 +166,10 @@ module Kappa::V2
|
|
149
166
|
# @return [String] Unique Twitch name.
|
150
167
|
attr_reader :name
|
151
168
|
|
152
|
-
# @return [String] Current status.
|
169
|
+
# @return [String] Current status set by the channel's owner.
|
153
170
|
attr_reader :status
|
154
171
|
|
155
|
-
# @return [DateTime] When the channel was last updated
|
172
|
+
# @return [DateTime] When the channel was last updated. When a stream is started, its channel is updated.
|
156
173
|
attr_reader :updated_at
|
157
174
|
|
158
175
|
# @return [String] The URL for the channel's main page.
|
@@ -161,6 +178,7 @@ module Kappa::V2
|
|
161
178
|
# @return [String] URL for the image shown when the stream is offline.
|
162
179
|
attr_reader :video_banner_url
|
163
180
|
|
181
|
+
# @return [Array<Team>] The list of teams that this channel is associated with. Not all channels have associated teams.
|
164
182
|
attr_reader :teams
|
165
183
|
end
|
166
184
|
end
|
data/lib/kappa/connection.rb
CHANGED
@@ -13,11 +13,13 @@ module Kappa
|
|
13
13
|
def initialize(base_url = DEFAULT_BASE_URL)
|
14
14
|
@base_url = Addressable::URI.parse(base_url)
|
15
15
|
|
16
|
+
# TODO: Expose client_id so clients of the library can (optionally) set this
|
17
|
+
# themselves and avoid rate limiting. Clients should still have the option to
|
18
|
+
# not set this and use a randomly generated ID.
|
19
|
+
|
16
20
|
uuid = SecureRandom.uuid
|
17
21
|
# TODO: Use current library version.
|
18
22
|
@client_id = "Kappa-v1-#{uuid}"
|
19
|
-
|
20
|
-
@last_request_time = Time.now - RATE_LIMIT_SEC
|
21
23
|
end
|
22
24
|
|
23
25
|
def get(path, query = nil)
|
@@ -27,25 +29,26 @@ module Kappa
|
|
27
29
|
'Client-ID' => @client_id,
|
28
30
|
}.merge(custom_headers)
|
29
31
|
|
30
|
-
response =
|
31
|
-
self.class.get(request_url, :headers => headers, :query => query)
|
32
|
-
end
|
32
|
+
response = self.class.get(request_url, :headers => headers, :query => query)
|
33
33
|
|
34
34
|
# TODO: Handle non-JSON response
|
35
35
|
# TODO: Handle invalid JSON
|
36
36
|
# TODO: Handle non-200 codes
|
37
|
+
# TODO: Include HTTP status code in the return value
|
37
38
|
|
38
39
|
json = response.body
|
39
40
|
return JSON.parse(json)
|
40
41
|
end
|
41
42
|
|
42
|
-
def accumulate(
|
43
|
-
path =
|
44
|
-
params =
|
45
|
-
json =
|
46
|
-
sub_json =
|
47
|
-
klass =
|
48
|
-
|
43
|
+
def accumulate(options)
|
44
|
+
path = options[:path]
|
45
|
+
params = options[:params] || {}
|
46
|
+
json = options[:json]
|
47
|
+
sub_json = options[:sub_json]
|
48
|
+
klass = options[:class]
|
49
|
+
|
50
|
+
total_limit = options[:limit]
|
51
|
+
page_limit = params[:limit] || 100
|
49
52
|
|
50
53
|
objects = []
|
51
54
|
ids = Set.new
|
@@ -57,13 +60,13 @@ module Kappa
|
|
57
60
|
object = klass.new(object_json)
|
58
61
|
if ids.add?(object.id)
|
59
62
|
objects << object
|
60
|
-
if objects.count ==
|
63
|
+
if objects.count == total_limit
|
61
64
|
return objects
|
62
65
|
end
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
66
|
-
!current_objects.empty?
|
69
|
+
!current_objects.empty? && (current_objects.count >= page_limit)
|
67
70
|
end
|
68
71
|
|
69
72
|
return objects
|
@@ -106,20 +109,6 @@ module Kappa
|
|
106
109
|
end
|
107
110
|
|
108
111
|
private
|
109
|
-
def rate_limit
|
110
|
-
delta = Time.now - @last_request_time
|
111
|
-
delay = [RATE_LIMIT_SEC - delta, 0].max
|
112
|
-
|
113
|
-
sleep delay if delay > 0
|
114
|
-
|
115
|
-
begin
|
116
|
-
return yield
|
117
|
-
ensure
|
118
|
-
@last_request_time = Time.now
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
RATE_LIMIT_SEC = 1
|
123
112
|
DEFAULT_BASE_URL = 'https://api.twitch.tv/kraken/'
|
124
113
|
end
|
125
114
|
end
|