turntabler 0.0.1
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/.gitignore +7 -0
- data/.rspec +2 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +383 -0
- data/Rakefile +11 -0
- data/examples/Gemfile +3 -0
- data/examples/Gemfile.lock +29 -0
- data/examples/autobop.rb +13 -0
- data/examples/autofan.rb +13 -0
- data/examples/blacklist.rb +16 -0
- data/examples/bop.rb +15 -0
- data/examples/bopcount.rb +20 -0
- data/examples/chat_bot.rb +16 -0
- data/examples/modlist.rb +19 -0
- data/examples/switch.rb +40 -0
- data/examples/time_afk_list.rb +46 -0
- data/lib/turntabler/assertions.rb +36 -0
- data/lib/turntabler/authorized_user.rb +217 -0
- data/lib/turntabler/avatar.rb +34 -0
- data/lib/turntabler/boot.rb +22 -0
- data/lib/turntabler/client.rb +457 -0
- data/lib/turntabler/connection.rb +176 -0
- data/lib/turntabler/digest_helpers.rb +13 -0
- data/lib/turntabler/error.rb +5 -0
- data/lib/turntabler/event.rb +239 -0
- data/lib/turntabler/handler.rb +67 -0
- data/lib/turntabler/loggable.rb +11 -0
- data/lib/turntabler/message.rb +24 -0
- data/lib/turntabler/playlist.rb +50 -0
- data/lib/turntabler/preferences.rb +70 -0
- data/lib/turntabler/resource.rb +194 -0
- data/lib/turntabler/room.rb +377 -0
- data/lib/turntabler/room_directory.rb +133 -0
- data/lib/turntabler/snag.rb +16 -0
- data/lib/turntabler/song.rb +247 -0
- data/lib/turntabler/sticker.rb +48 -0
- data/lib/turntabler/sticker_placement.rb +25 -0
- data/lib/turntabler/user.rb +274 -0
- data/lib/turntabler/version.rb +9 -0
- data/lib/turntabler/vote.rb +19 -0
- data/lib/turntabler.rb +102 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/turntabler_spec.rb +4 -0
- data/turntable.gemspec +24 -0
- metadata +173 -0
@@ -0,0 +1,377 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'em-synchrony/em-http'
|
3
|
+
require 'turntabler/resource'
|
4
|
+
|
5
|
+
module Turntabler
|
6
|
+
# Represents an individual room in Turntable. The room must be explicitly
|
7
|
+
# entered before being able to DJ.
|
8
|
+
class Room < Resource
|
9
|
+
# Allow the id to be set via the "roomid" attribute
|
10
|
+
# @return [String]
|
11
|
+
attribute :id, :roomid, :load => false
|
12
|
+
|
13
|
+
# The section of the room that the user is in. This only applies to
|
14
|
+
# overflow rooms.
|
15
|
+
# @return [String]
|
16
|
+
attribute :section, :load => false
|
17
|
+
|
18
|
+
# The human-readable name for the room
|
19
|
+
# @return [String]
|
20
|
+
attribute :name
|
21
|
+
|
22
|
+
# A longer description of the room (sometimes includes rules, guidelines, etc.)
|
23
|
+
# @return [String]
|
24
|
+
attribute :description
|
25
|
+
|
26
|
+
# The path which can be used in the url to load the room
|
27
|
+
# @return [String]
|
28
|
+
attribute :shortcut
|
29
|
+
|
30
|
+
# The privacy level for the room (either "public" or "unlisted")
|
31
|
+
# @return [String]
|
32
|
+
attribute :privacy
|
33
|
+
|
34
|
+
# The maximum number of listeners that can be in the room (including DJs)
|
35
|
+
# @return [Fixnum]
|
36
|
+
attribute :listener_capacity, :max_size
|
37
|
+
|
38
|
+
# The maximum number of users that can DJ
|
39
|
+
# @return [Fixnum]
|
40
|
+
attribute :dj_capacity, :max_djs
|
41
|
+
|
42
|
+
# The minimum number of points required to DJ
|
43
|
+
# @return [Fixnum]
|
44
|
+
attribute :dj_minimum_points, :djthreshold
|
45
|
+
|
46
|
+
# The type of music being played in the room
|
47
|
+
# @return [String]
|
48
|
+
attribute :genre
|
49
|
+
|
50
|
+
# The time at which this room was created
|
51
|
+
# @return [Time]
|
52
|
+
attribute :created_at, :created do |value|
|
53
|
+
Time.at(value)
|
54
|
+
end
|
55
|
+
|
56
|
+
# The host to connect to for joining this room
|
57
|
+
# @return [String]
|
58
|
+
attribute :host, :chatserver do |value|
|
59
|
+
value[0]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Whether this room is being featured by Turntable
|
63
|
+
# @return [Boolean]
|
64
|
+
attribute :featured
|
65
|
+
|
66
|
+
# The user that created the room
|
67
|
+
# @return [Turntabler::User]
|
68
|
+
attribute :creator do |attrs|
|
69
|
+
build_user(attrs)
|
70
|
+
end
|
71
|
+
|
72
|
+
# The listeners currently in the rom
|
73
|
+
# @return [Array<Turntabler::User>]
|
74
|
+
attribute :listeners, :users do |users|
|
75
|
+
Set.new(users.map {|attrs| build_user(attrs)})
|
76
|
+
end
|
77
|
+
|
78
|
+
# The users that are currently DJ'ing in the room
|
79
|
+
# @return [Array<Turntabler::User>]
|
80
|
+
attribute :djs do |ids|
|
81
|
+
Set.new(ids.map {|id| build_user(:_id => id)})
|
82
|
+
end
|
83
|
+
|
84
|
+
# The users that are appointed to moderate the room
|
85
|
+
# @return [Array<Turntabler::User>]
|
86
|
+
attribute :moderators, :moderator_id do |ids|
|
87
|
+
Set.new(ids.map {|id| build_user(:_id => id)})
|
88
|
+
end
|
89
|
+
|
90
|
+
# The current user's friends who are also known to be in the room. These
|
91
|
+
# friends must be connected through a separate network like Facebook or Twitter.
|
92
|
+
#
|
93
|
+
# @note This is only available when the room is discovered via Turntabler::RoomDirectory#with_friends
|
94
|
+
# @return [Array<Turntabler::User>]
|
95
|
+
attribute :friends, :load => false do |users|
|
96
|
+
Set.new(users.map {|attrs| build_user(attrs)})
|
97
|
+
end
|
98
|
+
|
99
|
+
# The current song being played
|
100
|
+
# @return [Turntabler::Song]
|
101
|
+
attribute :current_song do |attrs|
|
102
|
+
Song.new(client, attrs)
|
103
|
+
end
|
104
|
+
|
105
|
+
# The current DJ playing
|
106
|
+
# @return [Turntabler::User]
|
107
|
+
attribute :current_dj do |id|
|
108
|
+
build_user(:_id => id)
|
109
|
+
end
|
110
|
+
|
111
|
+
# The list of songs that have been played in this room.
|
112
|
+
# @note This is not an exhaustive list
|
113
|
+
# @return [Array<Turntabler::Song>]
|
114
|
+
attribute :songs_played, :songlog, :load => false do |songs|
|
115
|
+
songs.map {|attrs| Song.new(client, attrs)}
|
116
|
+
end
|
117
|
+
|
118
|
+
# @api private
|
119
|
+
def initialize(*)
|
120
|
+
@friends = Set.new
|
121
|
+
@songs_played = []
|
122
|
+
super
|
123
|
+
end
|
124
|
+
|
125
|
+
# Uses the configured chat host or attempts to look it up based on the room id
|
126
|
+
#
|
127
|
+
# @return [String]
|
128
|
+
# @raise [Turntabler::Error] if the host lookup fails
|
129
|
+
def host
|
130
|
+
@host ||= begin
|
131
|
+
response = EventMachine::HttpRequest.new("http://turntable.fm/api/room.which_chatserver?roomid=#{id}").get.response
|
132
|
+
JSON.parse(response)[1]['chatserver'][0]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Gets the configured chat url
|
137
|
+
#
|
138
|
+
# @return [String]
|
139
|
+
def url
|
140
|
+
"ws://#{host}/socket.io/websocket"
|
141
|
+
end
|
142
|
+
|
143
|
+
# Loads the attributes for this room. Attributes will automatically load
|
144
|
+
# when accessed, but this allows data to be forcefully loaded upfront.
|
145
|
+
#
|
146
|
+
# @note This will open a connection to the chat server the room is hosted on if the client is not already connected to it
|
147
|
+
# @param [Hash] options The configuration options
|
148
|
+
# @option options [Boolean] :song_log (false) Whether to include the song log
|
149
|
+
# @return [true]
|
150
|
+
# @raise [Turntabler::Error] if the command fails
|
151
|
+
# @example
|
152
|
+
# room.load # => true
|
153
|
+
# room.load(:song_log => true) # => true
|
154
|
+
def load(options = {})
|
155
|
+
assert_valid_keys(options, :song_log)
|
156
|
+
options = {:song_log => false}.merge(options)
|
157
|
+
|
158
|
+
# Use a client that is connected on the same url this room is hosted on
|
159
|
+
client = @client.url == url ? @client : Turntabler::Client.new(@client.user.id, @client.user.auth, :url => url, :timeout => @client.timeout)
|
160
|
+
|
161
|
+
begin
|
162
|
+
data = client.api('room.info', :roomid => id, :section => section, :extended => options[:song_log])
|
163
|
+
self.attributes = data['room'].merge('users' => data['users'])
|
164
|
+
super()
|
165
|
+
ensure
|
166
|
+
# Close the client if it was only opened for use in this API call
|
167
|
+
client.close if client != @client
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Sets the current attributes for this room, ensures that the full list of
|
172
|
+
# listeners gets set first so that we can use those built users to then fill
|
173
|
+
# out the collection of djs, moderators, etc.
|
174
|
+
#
|
175
|
+
# @api private
|
176
|
+
def attributes=(attrs)
|
177
|
+
if attrs
|
178
|
+
super('users' => attrs.delete('users')) if attrs['users']
|
179
|
+
super
|
180
|
+
|
181
|
+
# Set room-level attributes that are specific to the song
|
182
|
+
song_attributes = attrs['metadata'] && attrs['metadata'].select {|key, value| %w(upvotes downvotes votelog).include?(key)}
|
183
|
+
current_song.attributes = song_attributes if @current_song
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Updates this room's information.
|
188
|
+
#
|
189
|
+
# @param [Hash] attributes The attributes to update
|
190
|
+
# @option attributes [String] :description
|
191
|
+
# @return [true]
|
192
|
+
# @raise [Turntabler::Error] if the command fails
|
193
|
+
# @example
|
194
|
+
# room.update(:description => '...') # => true
|
195
|
+
def update(attributes = {})
|
196
|
+
assert_valid_keys(attributes, :description)
|
197
|
+
|
198
|
+
api('room.modify', attributes)
|
199
|
+
self.attributes = attributes
|
200
|
+
true
|
201
|
+
end
|
202
|
+
|
203
|
+
# Enters the current room.
|
204
|
+
#
|
205
|
+
# @return [true]
|
206
|
+
# @raise [Turntabler::Error] if the command fails
|
207
|
+
# @example
|
208
|
+
# room.enter # => true
|
209
|
+
def enter
|
210
|
+
if client.room != self
|
211
|
+
# Leave the old room
|
212
|
+
client.room.leave if client.room
|
213
|
+
|
214
|
+
# Connect and register with this room
|
215
|
+
client.connect(url)
|
216
|
+
begin
|
217
|
+
client.room = self
|
218
|
+
data = api('room.register', :roomid => id, :section => nil)
|
219
|
+
self.attributes = {'section' => data['section']}
|
220
|
+
rescue Exception
|
221
|
+
client.room = nil
|
222
|
+
raise
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
true
|
227
|
+
end
|
228
|
+
|
229
|
+
# Leaves from the current room.
|
230
|
+
#
|
231
|
+
# @return [true]
|
232
|
+
# @raise [Turntabler::Error] if the command fails
|
233
|
+
# @example
|
234
|
+
# room.leave # => true
|
235
|
+
def leave
|
236
|
+
api('room.deregister', :roomid => id, :section => section)
|
237
|
+
true
|
238
|
+
end
|
239
|
+
|
240
|
+
# Add this room to the current user's favorites.
|
241
|
+
#
|
242
|
+
# @return [true]
|
243
|
+
# @raise [Turntabler::Error] if the command fails
|
244
|
+
# @example
|
245
|
+
# room.add_as_favorite # => true
|
246
|
+
def add_as_favorite
|
247
|
+
api('room.add_favorite', :roomid => id, :section => section)
|
248
|
+
true
|
249
|
+
end
|
250
|
+
|
251
|
+
# Remove this room from current user's favorites.
|
252
|
+
#
|
253
|
+
# @return [true]
|
254
|
+
# @raise [Turntabler::Error] if the command fails
|
255
|
+
# @example
|
256
|
+
# room.remove_as_favorite # => true
|
257
|
+
def remove_as_favorite
|
258
|
+
api('room.rem_favorite', :roomid => id, :section => section)
|
259
|
+
true
|
260
|
+
end
|
261
|
+
|
262
|
+
# Gets the user represented by the given attributes. This can either pull
|
263
|
+
# the user from:
|
264
|
+
# * The currently authorized user
|
265
|
+
# * The room's creator
|
266
|
+
# * The room's listeners
|
267
|
+
# * The room's moderators
|
268
|
+
#
|
269
|
+
# If the user isn't present in any of those, then a new User instance will
|
270
|
+
# get created.
|
271
|
+
#
|
272
|
+
# @api private
|
273
|
+
def build_user(attrs)
|
274
|
+
user = User.new(client, attrs)
|
275
|
+
user = if client.user == user
|
276
|
+
client.user
|
277
|
+
elsif @creator == user
|
278
|
+
creator
|
279
|
+
elsif result = @listeners && listener(user.id) || @moderators && moderator(user.id) || friend(user.id)
|
280
|
+
result
|
281
|
+
else
|
282
|
+
user
|
283
|
+
end
|
284
|
+
user.attributes = attrs
|
285
|
+
user
|
286
|
+
end
|
287
|
+
|
288
|
+
# Determines whether the current user can dj based on the minimum points
|
289
|
+
# required and spot availability
|
290
|
+
def can_dj?
|
291
|
+
dj_capacity > djs.length && dj_minimum_points <= client.user.points
|
292
|
+
end
|
293
|
+
|
294
|
+
# Adds the current user to the list of DJs.
|
295
|
+
#
|
296
|
+
# @note This will cause the user to enter the current room if that isn't already the case
|
297
|
+
# @return [true]
|
298
|
+
# @raise [Turntabler::Error] if the command fails
|
299
|
+
# @example
|
300
|
+
# room.become_dj # => true
|
301
|
+
def become_dj
|
302
|
+
enter
|
303
|
+
api('room.add_dj', :roomid => id, :section => section)
|
304
|
+
true
|
305
|
+
end
|
306
|
+
|
307
|
+
# Gets the dj with the given user id.
|
308
|
+
#
|
309
|
+
# @return [Turntabler::User, nil]
|
310
|
+
# @example
|
311
|
+
# room.dj('4fd8...') # => #<Turntabler::User ...>
|
312
|
+
def dj(user_id)
|
313
|
+
djs.detect {|dj| dj.id == user_id}
|
314
|
+
end
|
315
|
+
|
316
|
+
# Gets the listener with the given user id.
|
317
|
+
#
|
318
|
+
# @return [Turntabler::User, nil]
|
319
|
+
# @example
|
320
|
+
# room.listener('4fd8...') # => #<Turntabler::User ...>
|
321
|
+
def listener(user_id)
|
322
|
+
listeners.detect {|listener| listener.id == user_id}
|
323
|
+
end
|
324
|
+
|
325
|
+
# Gets the moderator with the given user id.
|
326
|
+
#
|
327
|
+
# @return [Turntabler::User, nil]
|
328
|
+
# @example
|
329
|
+
# room.moderator('4fd8...') # => #<Turntabler::User ...>
|
330
|
+
def moderator(user_id)
|
331
|
+
moderators.detect {|moderator| moderator.id == user_id}
|
332
|
+
end
|
333
|
+
|
334
|
+
# Gets the friend in the room with the given user id.
|
335
|
+
#
|
336
|
+
# @note This is only available when the room is discovered via Turntabler::RoomDirectory#with_friends
|
337
|
+
# @return [Turntabler::User, nil]
|
338
|
+
# @example
|
339
|
+
# room.friend('4fd8...') # => #<Turntabler::User ...>
|
340
|
+
def friend(user_id)
|
341
|
+
friends.detect {|friend| friend.id == user_id}
|
342
|
+
end
|
343
|
+
|
344
|
+
# Braodcasts a message in the chat.
|
345
|
+
#
|
346
|
+
# @param [String] text The text to send to the chat
|
347
|
+
# @return [true]
|
348
|
+
# @raise [Turntabler::Error] if the command fails
|
349
|
+
# @example
|
350
|
+
# room.say("What's up guys?") # => true
|
351
|
+
def say(text)
|
352
|
+
enter
|
353
|
+
api('room.speak', :text => text)
|
354
|
+
true
|
355
|
+
end
|
356
|
+
|
357
|
+
# Reports abuse by a room.
|
358
|
+
#
|
359
|
+
# @param [String] reason The reason the room is being reported
|
360
|
+
# @return [true]
|
361
|
+
# @raise [Turntabler::Error] if the command fails
|
362
|
+
# @example
|
363
|
+
# room.report('Name abuse ...') # => true
|
364
|
+
def report(reason = '')
|
365
|
+
api('room.report', :roomid => id, :section => section, :reason => reason)
|
366
|
+
true
|
367
|
+
end
|
368
|
+
|
369
|
+
private
|
370
|
+
# Sets the sticker placements for each dj
|
371
|
+
def sticker_placements=(user_placements)
|
372
|
+
user_placements.each do |user_id, placements|
|
373
|
+
listener(user_id).attributes = {'placements' => placements}
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'turntabler/room'
|
2
|
+
|
3
|
+
module Turntabler
|
4
|
+
# Provides a set of helper methods for interacting with Turntable's directory
|
5
|
+
# of rooms.
|
6
|
+
class RoomDirectory
|
7
|
+
include Assertions
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
# Creates a new room with the given name and configuration. This should
|
15
|
+
# only be used if the room doesn't already exist.
|
16
|
+
#
|
17
|
+
# @note This will automatically enter the room when it is created
|
18
|
+
# @param [String] name The name of the room
|
19
|
+
# @param [Hash] attributes The initial attributes for the room
|
20
|
+
# @option attributes [String] :privacy ("public") TheThe level which the room will be made available to others ("public" or "unlisted")
|
21
|
+
# @option attributes [Fixnum] :dj_capacity (5) The maximum number of DJs allowed
|
22
|
+
# @option attributes [Fixnum] :dj_minimum_points (0) The minimum number of points required for a user to DJ
|
23
|
+
# @return [Turntabler::Room]
|
24
|
+
# @raise [ArgumentError] if an invalid attribute is specified
|
25
|
+
# @raise [Turntabler::Error] if the command fails
|
26
|
+
# @example
|
27
|
+
# rooms.create("Rock Awesomeness") # => #<Turntabler::Room ...>
|
28
|
+
def create(name, attributes = {})
|
29
|
+
assert_valid_keys(attributes, :privacy, :dj_capacity, :dj_minimum_points)
|
30
|
+
attributes = {:privacy => 'public', :dj_capacity => 5, :dj_minimum_points => 0}.merge(attributes)
|
31
|
+
|
32
|
+
# Convert attribute names over to their Turntable equivalent
|
33
|
+
{:dj_capacity => :max_djs, :dj_minimum_points => :djthreshold}.each do |from, to|
|
34
|
+
attributes[to] = attributes.delete(from) if attributes[from]
|
35
|
+
end
|
36
|
+
|
37
|
+
data = api('room.create', attributes.merge(:room_name => name))
|
38
|
+
room = Room.new(client, attributes.merge(:_id => data['roomid'], :shortcut => data['shortcut'], :name => name))
|
39
|
+
room.enter
|
40
|
+
room
|
41
|
+
end
|
42
|
+
|
43
|
+
# Gets the list of available rooms.
|
44
|
+
#
|
45
|
+
# @param [Hash] options The search options
|
46
|
+
# @option options [Fixnum] :limit (20) The total number of rooms to list
|
47
|
+
# @option options [Fixnum] :skip (0) The number of rooms to skip when loading the list
|
48
|
+
# @option options [Fixnum] :favorites (false) Whether to only include rooms marked as favorites
|
49
|
+
# @option options [Fixnum] :available_djs (false) Whether to only include rooms that have dj spots available
|
50
|
+
# @option options [Fixnum] :genre The genre of music being played in the room, . Possible values are +:rock+, +:electronica+, +:indie+, +:hiphop+, +:pop+, and +:dubstep+.
|
51
|
+
# @option options [Fixnum] :minimum_listeners (1) The minimum number of listeners in the room
|
52
|
+
# @option options [Fixnum] :sort (:listeners) The order to list rooms in. Possible values are +:created+, +:listeners+, and +:random+.
|
53
|
+
# @return [Array<Turntabler::Room>]
|
54
|
+
# @raise [ArgumentError] if an invalid option is specified
|
55
|
+
# @raise [Turntabler::Error] if the command fails
|
56
|
+
# @example
|
57
|
+
# rooms.list # => [#<Turntabler::Room ...>, ...]
|
58
|
+
# rooms.list(:favorites => true) # => [#<Turntabler::Room ...>, ...]
|
59
|
+
# rooms.list(:available_djs => true, :genre => :rock) # => [#<Turntabler::Room ...>, ...]
|
60
|
+
# rooms.list(:sort => :random) # => [#<Turntabler::Room ...>, ...]
|
61
|
+
def list(options = {})
|
62
|
+
assert_valid_keys(options, :limit, :skip, :favorites, :available_djs, :genre, :minimum_listeners, :sort)
|
63
|
+
assert_valid_values(options[:genre], :rock, :electronic, :indie, :hiphop, :pop, :dubstep) if options[:genre]
|
64
|
+
assert_valid_values(options[:sort], :created, :listeners, :random) if options[:sort]
|
65
|
+
options = {
|
66
|
+
:limit => 20,
|
67
|
+
:skip => 0,
|
68
|
+
:favorites => false,
|
69
|
+
:available_djs => false,
|
70
|
+
:minimum_listeners => 1,
|
71
|
+
:sort => :listeners
|
72
|
+
}.merge(options)
|
73
|
+
|
74
|
+
constraints = []
|
75
|
+
constraints << :favorites if options[:favorites]
|
76
|
+
constraints << :available_djs if options[:available_djs]
|
77
|
+
constraints << :"has_people=#{options[:minimum_listeners]}"
|
78
|
+
if options[:genre]
|
79
|
+
constraints << :"genre=#{options[:genre]}"
|
80
|
+
options[:sort] = "#{options[:sort]},genre:#{options[:genre]}"
|
81
|
+
end
|
82
|
+
|
83
|
+
data = api('room.directory_rooms',
|
84
|
+
:section_aware => true,
|
85
|
+
:limit => options[:limit],
|
86
|
+
:skip => options[:skip],
|
87
|
+
:constraints => constraints * ',',
|
88
|
+
:sort => options[:sort]
|
89
|
+
)
|
90
|
+
data['rooms'].map {|attrs| Room.new(client, attrs)}
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get the rooms where your friends are currently in.
|
94
|
+
#
|
95
|
+
# @return [Array<Turntabler::Room>]
|
96
|
+
# @raise [Turntabler::Error] if the command fails
|
97
|
+
# @example
|
98
|
+
# rooms.with_friends # => [#<Turntabler::Room ...>, ...]
|
99
|
+
def with_friends
|
100
|
+
data = api('room.directory_graph')
|
101
|
+
data['rooms'].map do |(attrs, friends)|
|
102
|
+
Room.new(client, attrs.merge(:friends => friends))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Finds rooms that match the given query string.
|
107
|
+
#
|
108
|
+
# @param [String] query The query string to search with
|
109
|
+
# @param [Hash] options The search options
|
110
|
+
# @option options [Fixnum] :limit (20) The maximum number of rooms to query for
|
111
|
+
# @option options [Fixnum] :skip (0) The number of rooms to skip when loading the results
|
112
|
+
# @return [Array<Turntabler::Room>]
|
113
|
+
# @raise [ArgumentError] if an invalid option is specified
|
114
|
+
# @raise [Turntabler::Error] if the command fails
|
115
|
+
# rooms.find('indie') # => [#<Turntabler::Room ...>, ...]
|
116
|
+
def find(query, options = {})
|
117
|
+
assert_valid_keys(options, :limit, :skip)
|
118
|
+
options = {:limit => 20, :skip => 0}.merge(options)
|
119
|
+
|
120
|
+
data = api('room.search', :query => query, :skip => options[:skip])
|
121
|
+
data['rooms'].map {|(attrs, *)| Room.new(client, attrs)}
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
# The client that all APIs filter through
|
126
|
+
attr_reader :client
|
127
|
+
|
128
|
+
# Runs the given API command on the client.
|
129
|
+
def api(command, options = {})
|
130
|
+
client.api(command, options)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'turntabler/resource'
|
2
|
+
|
3
|
+
module Turntabler
|
4
|
+
# Represents a song that was snagged
|
5
|
+
class Snag < Resource
|
6
|
+
# The user who snagged the song
|
7
|
+
# @return [Turntabler::User]
|
8
|
+
attribute :user, :userid do |value|
|
9
|
+
room.build_user(:_id => value)
|
10
|
+
end
|
11
|
+
|
12
|
+
# The song that was snagged
|
13
|
+
# @return [Turntabler::Song]
|
14
|
+
attribute :song
|
15
|
+
end
|
16
|
+
end
|