turntabler 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: