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 +14 -0
- data/README.md +1 -1
- data/examples/Gemfile.lock +1 -1
- data/lib/turntabler/authorized_user.rb +4 -1
- data/lib/turntabler/client.rb +74 -6
- data/lib/turntabler/event.rb +84 -21
- data/lib/turntabler/playlist.rb +1 -1
- data/lib/turntabler/song.rb +55 -26
- data/lib/turntabler/user.rb +2 -1
- data/lib/turntabler/version.rb +2 -2
- data/lib/turntabler.rb +1 -1
- metadata +98 -74
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
data/examples/Gemfile.lock
CHANGED
@@ -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
|
-
|
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
|
data/lib/turntabler/client.rb
CHANGED
@@ -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
|
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.
|
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
|
-
# * +:
|
240
|
-
# * +:
|
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
|
-
# * +:
|
277
|
-
# * +:
|
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
|
# # ...
|
data/lib/turntabler/event.rb
CHANGED
@@ -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}
|
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
|
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
|
-
|
124
|
-
|
125
|
-
|
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
|
161
|
+
# A dj was removed from the stage
|
133
162
|
handle :dj_removed, :rem_dj do
|
134
|
-
data['user']
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
-
|
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 [
|
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
|
data/lib/turntabler/playlist.rb
CHANGED
@@ -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
|
data/lib/turntabler/song.rb
CHANGED
@@ -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 =>
|
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
|
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.
|
182
|
-
def
|
210
|
+
# song.add(:index => 1) # => true
|
211
|
+
def add(options = {})
|
183
212
|
assert_valid_keys(options, :playlist, :index)
|
184
|
-
options = {:playlist =>
|
185
|
-
|
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,
|
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.
|
201
|
-
def
|
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
|
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
|
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
|
-
|
272
|
+
index
|
244
273
|
end
|
245
274
|
end
|
246
275
|
end
|
data/lib/turntabler/user.rb
CHANGED
@@ -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
|
|
data/lib/turntabler/version.rb
CHANGED
data/lib/turntabler.rb
CHANGED
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
|
-
|
14
|
-
|
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
|
-
|
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:
|
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
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
25
|
none: false
|
31
|
-
requirements:
|
32
|
-
- -
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version:
|
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
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version:
|
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
|
-
|
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:
|
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
|
-
|
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:
|
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
|
-
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
89
|
none: false
|
75
|
-
requirements:
|
76
|
-
- -
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version:
|
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
|
-
|
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:
|
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:
|
187
|
+
requirements:
|
188
|
+
- - ! '>='
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '0'
|
165
191
|
requirements: []
|
166
|
-
|
167
192
|
rubyforge_project:
|
168
|
-
rubygems_version: 1.8.
|
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:
|