turntabler 0.2.1 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # master
2
2
 
3
+ ## 0.3.0 / 2013-02-23
4
+
5
+ * Fix playlist order not being maintained properly in process
6
+ * Rename Song#enqueue to Song#add and Song#dequeue to Song#remove
7
+ * Song#dequeue and #move no longer allow the playlist to be specified since it's known upfront
8
+ * Fix Song#load not getting metadata from the correct playlist
9
+ * Add Song#playlist
10
+ * Add room_description_updated event
11
+ * Add song_skipped / song_moderated events
12
+ * Add #started_at, #ends_at, and #seconds_remaining to Song
13
+ * Add dj_escorted_off / dj_booed_off events
14
+ * Add fan_added / fan_removed events
15
+ * Add user_name_updated / user_avatar_updated / user_stickers_updated events
16
+
3
17
  ## 0.2.1 / 2013-02-16
4
18
 
5
19
  * Fix exceptions on initial connection not causing reconnection process to kick in
data/README.md CHANGED
@@ -160,7 +160,7 @@ Turntabler.run do
160
160
  # Songs
161
161
  songs = client.search_song('Rolling Stones') # => [#<Turntabler::Song @album="Tattoo You (2009 Remaster)" ...>, ...]
162
162
  songs.each do
163
- song.enqueue # => true
163
+ song.add # => true
164
164
  end
165
165
  end
166
166
  ```
@@ -17,7 +17,7 @@ GEM
17
17
  faye-websocket (0.4.6)
18
18
  eventmachine (>= 0.12.0)
19
19
  http_parser.rb (0.5.3)
20
- turntabler (0.2.1)
20
+ turntabler (0.3.0)
21
21
  em-http-request
22
22
  em-synchrony
23
23
  faye-websocket
@@ -250,8 +250,11 @@ module Turntabler
250
250
  def update_status(status = self.status)
251
251
  assert_valid_values(status, *%w(available unavailable away))
252
252
 
253
+ now = Time.now.to_i
253
254
  result = api('presence.update', :status => status)
254
- client.reset_keepalive(result['interval']) if result['interval']
255
+
256
+ client.reset_keepalive(result['interval'])
257
+ client.clock_delta = ((now + Time.now.to_i) / 2 - result['now']).round
255
258
  self.attributes = {'status' => status}
256
259
 
257
260
  true
@@ -36,6 +36,10 @@ module Turntabler
36
36
  # @return [Fixnum]
37
37
  attr_reader :timeout
38
38
 
39
+ # The difference of time (in seconds) between this client and Turntable servers
40
+ # @return [Fixnum]
41
+ attr_accessor :clock_delta
42
+
39
43
  # Creates a new client for communicating with Turntable.fm with the given
40
44
  # email / password.
41
45
  #
@@ -67,6 +71,7 @@ module Turntabler
67
71
  @timeout = options[:timeout]
68
72
  @reconnect = options[:reconnect]
69
73
  @reconnect_wait = options[:reconnect_wait]
74
+ @clock_delta = 0
70
75
 
71
76
  # Setup default event handlers
72
77
  on(:heartbeat) { on_heartbeat }
@@ -192,19 +197,27 @@ module Turntabler
192
197
  # == Room Events
193
198
  #
194
199
  # * +:room_updated+ - Information about the room was updated
200
+ # * +:room_description_updated+ - The room's description was updated
195
201
  #
196
202
  # @example
197
203
  # client.on :room_updated do |room| # Room
198
204
  # puts room.description
199
205
  # # ...
200
206
  # end
207
+ #
208
+ # client.on :room_description_updated do |room| # Room
209
+ # puts room.description
210
+ # # ...
211
+ # end
201
212
  #
202
213
  # == User Events
203
214
  #
204
215
  # * +:user_entered+ - A user entered the room
205
216
  # * +:user_left+ - A user left the room
206
217
  # * +:user_booted+ - A user has been booted from the room
207
- # * +:user_updated+ - A user's name / profile was updated
218
+ # * +:user_updated+ - A user's profile was updated
219
+ # * +:user_name_updated+ - A user's name was updated
220
+ # * +:user_avatar_updated+ - A user's avatar was updated
208
221
  # * +:user_spoke+ - A user spoke in the chat room
209
222
  #
210
223
  # @example
@@ -225,7 +238,22 @@ module Turntabler
225
238
  # end
226
239
  #
227
240
  # client.on :user_updated do |user| # User
228
- # puts user.laptop_name
241
+ # puts user.name
242
+ # # ...
243
+ # end
244
+ #
245
+ # client.on :user_name_updated do |user| # User
246
+ # puts user.name
247
+ # # ...
248
+ # end
249
+ #
250
+ # client.on :user_avatar_updated do |user| # User
251
+ # puts user.avatar.id
252
+ # # ...
253
+ # end
254
+ #
255
+ # client.on :user_stickers_updated do |user| # User
256
+ # puts user.stickers.map {|sticker| sticker.id}
229
257
  # # ...
230
258
  # end
231
259
  #
@@ -236,8 +264,26 @@ module Turntabler
236
264
  #
237
265
  # == DJ Events
238
266
  #
239
- # * +:dj_added+ - A new DJ was added to the booth
240
- # * +:dj_removed+ - A DJ was removed from the booth
267
+ # * +:fan_added+ - A new fan was added by a user in the room
268
+ # * +:fan_removed+ - A fan was removed from a user in the room
269
+ #
270
+ # @example
271
+ # client.on :fan_added do |user, fan_of| # User, User
272
+ # puts user.id
273
+ # # ...
274
+ # end
275
+ #
276
+ # client.on :fan_removed do |user, count| # User, Fixnum
277
+ # puts user.id
278
+ # # ...
279
+ # end
280
+ #
281
+ # == DJ Events
282
+ #
283
+ # * +:dj_added+ - A new DJ was added to the stage
284
+ # * +:dj_removed+ - A DJ was removed from the stage
285
+ # * +:dj_escorted_off+ - A DJ was escorted off the stage by a moderator
286
+ # * +:dj_booed_off+ - A DJ was booed off the stage
241
287
  #
242
288
  # @example
243
289
  # client.on :dj_added do |user| # User
@@ -249,6 +295,16 @@ module Turntabler
249
295
  # puts user.id
250
296
  # # ...
251
297
  # end
298
+ #
299
+ # client.on :dj_escorted_off do |user, moderator| # User, User
300
+ # puts user.id
301
+ # # ...
302
+ # end
303
+ #
304
+ # client.on :dj_booed_off do |user| # User
305
+ # puts user.id
306
+ # # ...
307
+ # end
252
308
  #
253
309
  # == Moderator Events
254
310
  #
@@ -273,8 +329,9 @@ module Turntabler
273
329
  # * +:song_ended+ - The current song has ended. This is typically followed by a +:song_started+ or +:song_unavailable+ event.
274
330
  # * +:song_voted+ - One or more votes were cast for the song
275
331
  # * +:song_snagged+ - A user in the room has queued the current song onto their playlist
276
- # * +:song_blocked+ - A song was skipped due to a copyright claim
277
- # * +:song_limited+ - A song was skipped due to a limit on # of plays per hour
332
+ # * +:song_skipped+ - A song was skipped due to either the dj skipping it or too many downvotes
333
+ # * +:song_moderated+ - A song was forcefully skipped by a moderator
334
+ # * +:song_blocked+ - A song was prevented from playing due to a copyright claim
278
335
  #
279
336
  # @example
280
337
  # client.on :song_unavailable do
@@ -304,6 +361,17 @@ module Turntabler
304
361
  # # ...
305
362
  # end
306
363
  #
364
+ # client.on :song_skipped do |song| # Song
365
+ # puts song.title
366
+ # # ...
367
+ # end
368
+ #
369
+ # client.on :song_moderated do |song, moderator| # Song, User
370
+ # puts song.title
371
+ # puts moderator.id
372
+ # # ...
373
+ # end
374
+ #
307
375
  # client.on :song_blocked do |song| # Song
308
376
  # puts song.id
309
377
  # # ...
@@ -23,7 +23,7 @@ module Turntabler
23
23
  # @yieldreturn The typecasted data that should be passed into any handlers bound to the event
24
24
  # @return [nil]
25
25
  def handle(name, command = name, &block)
26
- block ||= lambda {}
26
+ block ||= lambda { [args] }
27
27
  commands[command] = name
28
28
 
29
29
  define_method("typecast_#{command}_event", &block)
@@ -71,9 +71,17 @@ module Turntabler
71
71
  # Information about the room was updated
72
72
  handle :room_updated, :update_room do
73
73
  room.attributes = data
74
+
75
+ # Trigger detailed events for exactly what changed to make it easier to
76
+ # detect the various situations
77
+ client.trigger(:room_description_updated, room) if data['description']
78
+
74
79
  room
75
80
  end
76
81
 
82
+ # A room's description has been updated
83
+ handle :room_description_updated
84
+
77
85
  # One or more users have entered the room
78
86
  handle :user_entered, :registered do
79
87
  data['user'].map do |attrs|
@@ -101,43 +109,78 @@ module Turntabler
101
109
 
102
110
  # A user's name / profile has been updated
103
111
  handle :user_updated, :update_user do
104
- fans_change = data.delete('fans')
112
+ fans_change = data.delete('fans') || 0
105
113
  user = room.build_user(data)
106
- user.attributes = {'fans' => user.fans_count + fans_change} if fans_change
114
+ user.attributes = {'fans' => user.fans_count + fans_change}
115
+
116
+ # Trigger detailed events for exactly what changed to make it easier to
117
+ # detect the various situations
118
+ client.trigger(:user_name_updated, user) if data['name']
119
+ client.trigger(:user_avatar_updated, user) if data['avatarid']
120
+ client.trigger(:fan_added, user, room.build_user(:_id => data['fanid'])) if fans_change > 0
121
+ client.trigger(:fan_removed, user, fans_change.abs) if fans_change < 0
122
+
107
123
  user
108
124
  end
109
125
 
126
+ # A user's name has been updated
127
+ handle :user_name_updated
128
+
129
+ # A user's avatar has been updated
130
+ handle :user_avatar_updated
131
+
110
132
  # A user's stickers have been updated
111
133
  handle :user_updated, :update_sticker_placements do
112
- room.build_user(data)
134
+ user = room.build_user(data)
135
+ client.trigger(:user_stickers_updated, user)
136
+ user
113
137
  end
114
138
 
139
+ # A user's stickers have been updated
140
+ handle :user_stickers_updated
141
+
115
142
  # A user spoke in the chat room
116
143
  handle :user_spoke, :speak do
117
144
  data['senderid'] = data.delete('userid')
118
145
  Message.new(client, data)
119
146
  end
120
147
 
121
- # A new dj was added to the room
148
+ # A new fan was added by a user in the room
149
+ handle :fan_added
150
+
151
+ # A fan has been removed by a user in the room
152
+ handle :fan_removed
153
+
154
+ # A new dj was added to the stage
122
155
  handle :dj_added, :add_dj do
123
- new_djs = []
124
- data['user'].each_with_index do |attrs, index|
125
- user = room.build_user(attrs.merge('placements' => data['placements'][index]))
126
- new_djs << [user]
127
- room.djs << user
128
- end
129
- new_djs
156
+ user = room.build_user(data['user'][0].merge('placements' => data['placements']))
157
+ room.djs << user
158
+ user
130
159
  end
131
160
 
132
- # A dj was removed from the room
161
+ # A dj was removed from the stage
133
162
  handle :dj_removed, :rem_dj do
134
- data['user'].map do |attrs|
135
- user = room.build_user(attrs)
136
- room.djs.delete(user)
137
- [user]
163
+ user = room.build_user(data['user'][0])
164
+ room.djs.delete(user)
165
+
166
+ if moderator_id = data['modid']
167
+ if moderator_id == 1
168
+ client.trigger(:dj_booed_off, user)
169
+ else
170
+ moderator = room.build_user(:_id => data['user'][0])
171
+ client.trigger(:dj_escorted_off, user, moderator)
172
+ end
138
173
  end
174
+
175
+ [user]
139
176
  end
140
177
 
178
+ # A dj was escorted off the stage by a moderator
179
+ handle :dj_escorted_off
180
+
181
+ # A dj was booed off the stage
182
+ handle :dj_booed_off
183
+
141
184
  # A new moderator was added to the room
142
185
  handle :moderator_added, :new_moderator do
143
186
  user = room.build_user(data)
@@ -155,7 +198,8 @@ module Turntabler
155
198
  # There are no more songs to play in the room
156
199
  handle :song_unavailable, :nosong do
157
200
  client.trigger(:song_ended) if room.current_song
158
- room.attributes = data['room'].merge('current_song' => nil)
201
+ data['room'].delete('current_song')
202
+ room.attributes = data['room']
159
203
  nil
160
204
  end
161
205
 
@@ -163,12 +207,20 @@ module Turntabler
163
207
  handle :song_started, :newsong do
164
208
  client.trigger(:song_ended) if room.current_song
165
209
  room.attributes = data['room']
166
- room.current_song
210
+ current_song = room.current_song
211
+
212
+ # Update playlist order if it was played by the current user
213
+ current_song.dequeue if current_song.played_by == client.user
214
+
215
+ current_song
167
216
  end
168
217
 
169
218
  # The current song has ended
170
219
  handle :song_ended do
171
- room.current_song
220
+ current_song = room.current_song
221
+ client.trigger(:song_skipped) if current_song.seconds_remaining > 10
222
+ room.attributes = {'current_song' => nil}
223
+ current_song
172
224
  end
173
225
 
174
226
  # A vote was cast for the song
@@ -201,6 +253,16 @@ module Turntabler
201
253
  Song.new(client, data)
202
254
  end
203
255
 
256
+ # A song was forcefully skipped by a moderator
257
+ handle :song_moderated, :stop_song do
258
+ moderator = room.build_user(:_id => data['skipperId'])
259
+ [[room.current_song, moderator]]
260
+ end
261
+
262
+ # A song was ended before it completed, either because the dj skipped it or
263
+ # it was booed off
264
+ handle :song_skipped
265
+
204
266
  # A private message was received from another user in the room
205
267
  handle :message_received, :pmmed do
206
268
  Message.new(client, data)
@@ -233,7 +295,8 @@ module Turntabler
233
295
  # Creates a new event triggered with the given data
234
296
  #
235
297
  # @param [Turntabler::Client] client The client that this event is bound to
236
- # @param [Hash] data The response data from Turntable
298
+ # @param [Symbol] command The name of the command that fired the event
299
+ # @param [Array] args The raw argument data from the event
237
300
  def initialize(client, command, args)
238
301
  @client = client
239
302
  @args = args
@@ -16,7 +16,7 @@ module Turntabler
16
16
  # The songs that have been added to this playlist
17
17
  # @return [Array<Turntabler::Song>]
18
18
  attribute :songs, :list do |songs|
19
- songs.map {|attrs| Song.new(client, attrs)}
19
+ songs.map {|attrs| Song.new(client, attrs.merge(:playlist => id))}
20
20
  end
21
21
 
22
22
  # Loads the attributes for this playlist. Attributes will automatically load
@@ -49,6 +49,16 @@ module Turntabler
49
49
  # @return [String]
50
50
  attribute :source_id, :sourceid
51
51
 
52
+ # The playlist this song is referenced from
53
+ # @return [Turntabler::Playlist]
54
+ attribute :playlist do |id|
55
+ client.user.playlists.build(:_id => id)
56
+ end
57
+
58
+ # The time at which the song was started
59
+ # @return [Time]
60
+ attribute :started_at, :starttime
61
+
52
62
  # The number of up votes this song has received.
53
63
  # @note This is only available for the current song playing in a room
54
64
  # @return [Fixnum]
@@ -84,14 +94,33 @@ module Turntabler
84
94
  end
85
95
 
86
96
  # @api private
87
- def initialize(*)
97
+ def initialize(client, *)
88
98
  @up_votes_count = 0
89
99
  @down_votes_count = 0
90
100
  @votes = []
91
101
  @score = 0
102
+ @playlist = client.user.playlists.build(:_id => 'default')
92
103
  super
93
104
  end
94
105
 
106
+ # The time at which this song will end playing.
107
+ #
108
+ # @return [Time]
109
+ # @example
110
+ # song.ends_at # => 2013-01-05 12:14:25 -0500
111
+ def ends_at
112
+ started_at + client.clock_delta + length if started_at
113
+ end
114
+
115
+ # The number of seconds remaining to play in the song
116
+ #
117
+ # @return [Fixnum]
118
+ # @example
119
+ # song.seconds_remaining # => 12
120
+ def seconds_remaining
121
+ ends_at ? (ends_at - started_at).round : 0
122
+ end
123
+
95
124
  # Loads the attributes for this song. Attributes will automatically load
96
125
  # when accessed, but this allows data to be forcefully loaded upfront.
97
126
  #
@@ -101,7 +130,7 @@ module Turntabler
101
130
  # song.load # => true
102
131
  # song.title # => "..."
103
132
  def load
104
- data = api('playlist.get_metadata', :playlist_name => 'default', :files => [id])
133
+ data = api('playlist.get_metadata', :playlist_name => playlist.id, :files => [id])
105
134
  self.attributes = data['files'][id]
106
135
  super
107
136
  end
@@ -172,37 +201,35 @@ module Turntabler
172
201
  # Adds the song to one of the user's playlists.
173
202
  #
174
203
  # @param [Hash] options The options for where to add the song
175
- # @option options [String] :playlist ("default") The playlist to enqueue the song in
204
+ # @option options [String] :playlist ("default") The playlist to add the song in
176
205
  # @option options [Fixnum] :index (0) The location in the playlist to insert the song
177
206
  # @return [true]
178
207
  # @raise [ArgumentError] if an invalid option is specified
179
208
  # @raise [Turntabler::Error] if the command fails
180
209
  # @example
181
- # song.enqueue(:index => 1) # => true
182
- def enqueue(options = {})
210
+ # song.add(:index => 1) # => true
211
+ def add(options = {})
183
212
  assert_valid_keys(options, :playlist, :index)
184
- options = {:playlist => 'default', :index => 0}.merge(options)
185
- playlist, index = client.user.playlist(options[:playlist]), options[:index]
213
+ options = {:playlist => playlist.id, :index => 0}.merge(options)
214
+
215
+ # Create a copy of the song so that the playlist can get set properly
216
+ song = dup
217
+ song.attributes = {:playlist => options[:playlist]}
218
+ playlist, index = song.playlist, options[:index]
186
219
 
187
220
  api('playlist.add', :playlist_name => playlist.id, :song_dict => {:fileid => id}, :index => index)
188
- playlist.songs.insert(index, self) if playlist.loaded?
221
+ playlist.songs.insert(index, song) if playlist.loaded?
189
222
  true
190
223
  end
191
224
 
192
225
  # Removes the song from the playlist at the given index.
193
226
  #
194
- # @param [Hash] options The options for where to remove the song
195
- # @option options [String] :playlist ("default") The playlist to dequeue the song from
196
227
  # @return [true]
197
228
  # @raise [ArgumentError] if an invalid option is specified
198
229
  # @raise [Turntabler::Error] if the command fails
199
230
  # @example
200
- # song.dequeue # => true
201
- def dequeue(options = {})
202
- assert_valid_keys(options, :playlist)
203
- options = {:playlist => 'default'}.merge(options)
204
- playlist, index = index(options[:playlist])
205
-
231
+ # song.remove # => true
232
+ def remove
206
233
  api('playlist.remove', :playlist_name => playlist.id, :index => index)
207
234
  playlist.songs.delete(self)
208
235
  true
@@ -211,22 +238,25 @@ module Turntabler
211
238
  # Move a song from one location in the playlist to another.
212
239
  #
213
240
  # @param [Fixnum] to_index The index to move the song to
214
- # @param [Hash] options The options for where to remove the song
215
- # @option options [String] :playlist ("default") The playlist to move the song within
216
241
  # @return [true]
217
242
  # @raise [ArgumentError] if an invalid option is specified
218
243
  # @raise [Turntabler::Error] if the command fails
219
244
  # song.move(5) # => true
220
- def move(to_index, options = {})
221
- assert_valid_keys(options, :playlist)
222
- options = {:playlist => 'default'}.merge(options)
223
- playlist, index = index(options[:playlist])
224
-
245
+ def move(to_index)
225
246
  api('playlist.reorder', :playlist_name => playlist.id, :index_from => index, :index_to => to_index)
226
247
  playlist.songs.insert(to_index, playlist.songs.delete(self))
227
248
  true
228
249
  end
229
250
 
251
+ # Moves this song to the back of the playlist it's associated with. If there
252
+ # are other songs in front of it, those will be moved to the back as well.
253
+ #
254
+ # @api private
255
+ def dequeue
256
+ playlist.songs.concat(playlist.songs.slice!(0, index + 1))
257
+ true
258
+ end
259
+
230
260
  private
231
261
  # Asserts that this is the song currently being played in the room the user
232
262
  # is in. Raises Turntabler::Error if this is not the case.
@@ -236,11 +266,10 @@ module Turntabler
236
266
 
237
267
  # Gets the index of this song within the given playlist. Raises Turntabler::Error
238
268
  # if the song cannot be found in the playlist.
239
- def index(playlist_id)
240
- playlist = client.user.playlist(playlist_id)
269
+ def index
241
270
  index = playlist.songs.index(self)
242
271
  raise(APIError, "Song \"#{id}\" is not in playlist \"#{playlist.id}\"") unless index
243
- return playlist, index
272
+ index
244
273
  end
245
274
  end
246
275
  end
@@ -68,7 +68,8 @@ module Turntabler
68
68
 
69
69
  # The placements of stickers on the user's laptop
70
70
  # @return [Array<Turntabler::StickerPlacement>]
71
- attribute :sticker_placements, :placements do |placements|
71
+ attribute :sticker_placements, :sticker_placements, :placements do |placements|
72
+ placements = placements.keys if placements.is_a?(Hash)
72
73
  placements.map {|attrs| StickerPlacement.new(client, attrs)}
73
74
  end
74
75
 
@@ -2,8 +2,8 @@ module Turntabler
2
2
  # The current version of the library
3
3
  module Version
4
4
  MAJOR = 0
5
- MINOR = 2
6
- PATCH = 1
5
+ MINOR = 3
6
+ PATCH = 0
7
7
  STRING = [MAJOR, MINOR, PATCH].join(".")
8
8
  end
9
9
  end
data/lib/turntabler.rb CHANGED
@@ -113,7 +113,7 @@ module Turntabler
113
113
  if Event.command?(name)
114
114
  raise ArgumentError, "Event :#{name} is already defined"
115
115
  else
116
- Event.handle(name) { [args] }
116
+ Event.handle(name)
117
117
  end
118
118
  end
119
119
  end
metadata CHANGED
@@ -1,94 +1,121 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: turntabler
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
4
5
  prerelease:
5
- version: 0.2.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Aaron Pfeifer
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2013-02-17 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2013-02-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: em-synchrony
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
24
22
  type: :runtime
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: em-http-request
28
23
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
30
25
  none: false
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: "0"
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: em-http-request
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
35
38
  type: :runtime
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: faye-websocket
39
39
  prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- version: "0"
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: faye-websocket
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
46
54
  type: :runtime
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: rake
50
55
  prerelease: false
51
- requirement: &id004 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
52
65
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: "0"
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
57
70
  type: :development
58
- version_requirements: *id004
59
- - !ruby/object:Gem::Dependency
60
- name: rspec
61
71
  prerelease: false
62
- requirement: &id005 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
63
81
  none: false
64
- requirements:
82
+ requirements:
65
83
  - - ~>
66
- - !ruby/object:Gem::Version
67
- version: "2.11"
84
+ - !ruby/object:Gem::Version
85
+ version: '2.11'
68
86
  type: :development
69
- version_requirements: *id005
70
- - !ruby/object:Gem::Dependency
71
- name: simplecov
72
87
  prerelease: false
73
- requirement: &id006 !ruby/object:Gem::Requirement
88
+ version_requirements: !ruby/object:Gem::Requirement
74
89
  none: false
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- version: "0"
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '2.11'
94
+ - !ruby/object:Gem::Dependency
95
+ name: simplecov
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
79
102
  type: :development
80
- version_requirements: *id006
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
81
110
  description: Turntable.FM API for Ruby
82
111
  email: aaron.pfeifer@gmail.com
83
112
  executables: []
84
-
85
113
  extensions: []
86
-
87
- extra_rdoc_files:
114
+ extra_rdoc_files:
88
115
  - README.md
89
116
  - CHANGELOG.md
90
117
  - LICENSE
91
- files:
118
+ files:
92
119
  - .gitignore
93
120
  - .rspec
94
121
  - .yardopts
@@ -139,36 +166,33 @@ files:
139
166
  - turntabler.gemspec
140
167
  homepage: http://github.com/obrie/turntabler
141
168
  licenses: []
142
-
143
169
  post_install_message:
144
- rdoc_options:
170
+ rdoc_options:
145
171
  - --line-numbers
146
172
  - --inline-source
147
173
  - --title
148
174
  - turntabler
149
175
  - --main
150
176
  - README.md
151
- require_paths:
177
+ require_paths:
152
178
  - lib
153
- required_ruby_version: !ruby/object:Gem::Requirement
179
+ required_ruby_version: !ruby/object:Gem::Requirement
154
180
  none: false
155
- requirements:
156
- - - ">="
157
- - !ruby/object:Gem::Version
158
- version: "0"
159
- required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ! '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
186
  none: false
161
- requirements:
162
- - - ">="
163
- - !ruby/object:Gem::Version
164
- version: "0"
187
+ requirements:
188
+ - - ! '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
165
191
  requirements: []
166
-
167
192
  rubyforge_project:
168
- rubygems_version: 1.8.24
193
+ rubygems_version: 1.8.25
169
194
  signing_key:
170
195
  specification_version: 3
171
196
  summary: Turntable.FM API for Ruby
172
197
  test_files: []
173
-
174
198
  has_rdoc: