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 CHANGED
@@ -1,9 +1,14 @@
1
- # <img src="http://static-cdn.jtvnw.net/jtv_user_pictures/chansub-global-emoticon-ddc6e3a8732cb50f-25x28.png" /> Kappa
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 Kraken API](https://github.com/justintv/Twitch-API).
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.new('followgrubby')
20
+ grubby = Channel.get('followgrubby')
16
21
  puts grubby.streaming?
17
22
  ```
18
23
 
19
- ## API
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
@@ -8,7 +8,6 @@ require 'kappa/team'
8
8
  require 'kappa/user'
9
9
  require 'kappa/images'
10
10
  require 'kappa/twitch'
11
- require 'kappa/base'
12
11
  require 'kappa/version'
13
12
 
14
13
  # TODO
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 initialize(arg, connection)
6
- @connection = connection
7
-
8
- case arg
9
- when Hash
10
- parse(arg)
11
- when String
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
- def initialize(arg, connection = Connection.instance)
30
- super(arg, connection)
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
- # TODO: Move these into derived classes?
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
- # TODO: Use _links instead of hard-coding.
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.live?
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(params = {})
71
- limit = params[:limit] || 0
72
-
73
- followers = []
74
- ids = Set.new
75
-
76
- @connection.paginated("channels/#{@name}/follows", params) do |json|
77
- current_followers = json['follows']
78
- current_followers.each do |follow_json|
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
- followers
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
- attr_reader :stream_delay_sec
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
- private
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
@@ -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
- class Connection < Kappa::ConnectionBase
104
- private
105
- def custom_headers
106
- { 'Accept' => 'application/vnd.twitchtv.v2+json' }
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
- module Kappa::V3
112
- class Connection < Kappa::ConnectionBase
113
- private
114
- def custom_headers
115
- { 'Accept' => 'application/vnd.twitchtv.v3+json' }
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
- attr_reader :id
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
- private
62
- def parse(hash)
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(params = {})
78
- limit = params[:limit] || 0
79
-
80
- games = []
81
- ids = Set.new
61
+ def self.top(args = {})
62
+ params = {}
82
63
 
83
- @conn.paginated('games/top', params) do |json|
84
- current_games = json['top']
85
- current_games.each do |game_json|
86
- game = Game.new(game_json)
87
- if ids.add?(game.id)
88
- games << game
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
- games
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 = @conn.get('search/games', :query => name, :type => 'suggest', :live => live)
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)
@@ -1,4 +1,5 @@
1
1
  module Kappa
2
+ # @private
2
3
  module IdEquality
3
4
  def hash
4
5
  @id.hash
data/lib/kappa/images.rb CHANGED
@@ -1,33 +1,19 @@
1
- module Kappa
2
- class ImagesBase
3
- def initialize(arg)
4
- case arg
5
- when Hash
6
- parse(arg)
7
- else
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, '{height}', height.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 initialize(hash, connection = self.class.default_connection)
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, connection)
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
- attr_reader :id
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
- private
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'], @connection)
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 < 25)
71
+ if limit && (limit < 100)
80
72
  params[:limit] = limit
81
73
  else
82
- params[:limit] = 25
74
+ params[:limit] = 100
83
75
  limit = 0
84
76
  end
85
77
 
86
- streams = []
87
- ids = Set.new
88
-
89
- connection = Connection.instance
90
- connection.paginated('streams', params) do |json|
91
- current_streams = json['streams']
92
- current_streams.each do |stream_json|
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(params = {})
113
- limit = params[:limit] || 0
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
- !current_streams.empty?
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
- streams
137
- end
138
- end
139
- end
140
-
141
- module Kappa::V3
142
- class Stream < Kappa::StreamBase
143
- def initialize(arg, connection = Connection.instance)
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
- def initialize(arg, connection)
6
- @connection = connection
7
-
8
- case arg
9
- when Hash
10
- parse(arg)
11
- when String
12
- json = @connection.get("teams/#{arg}")
13
- else
14
- raise ArgumentError
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
- private
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(params = {})
60
- limit = params[:limit] || 0
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
- !teams_json.empty?
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
- teams
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, connection = default_connection)
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, connection)
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
- limit = params[:limit] || 0
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
- !current_channels.empty?
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
- channels
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 = @connection.get("users/#{@name}/follows/channels/#{channel_name}")
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.3.pre'
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 initialize(arg, connection)
6
- @connection = connection
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
- def initialize(arg)
24
- super(arg, Connection.instance)
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(@conn.get("channels/#{@channel_name}"), @conn)
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.3.pre
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-09 00:00:00.000000000 Z
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:
data/lib/kappa/base.rb DELETED
@@ -1,9 +0,0 @@
1
- class Class
2
- def module_class(sym)
3
- parts = name.split('::')
4
- parts[-1] = sym
5
- parts.inject(Kernel) { |const, part|
6
- const.const_get(part)
7
- }
8
- end
9
- end