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,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Keep the last activity timestamp of everyone in the room
|
3
|
+
require 'turntabler'
|
4
|
+
|
5
|
+
AUTH = ENV['AUTH'] # 'auth+live+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
6
|
+
USER = ENV['USER'] # 'xxxxxxxxxxxxxxxxxxxxxxxx'
|
7
|
+
ROOM = ENV['ROOM'] # 'xxxxxxxxxxxxxxxxxxxxxxxx'
|
8
|
+
|
9
|
+
# Reset the users list
|
10
|
+
last_activity = {}
|
11
|
+
|
12
|
+
Turntabler.run(USER, AUTH, :room => ROOM) do
|
13
|
+
room.listeners.each do |user|
|
14
|
+
last_activity[user.id] = Time.now
|
15
|
+
end
|
16
|
+
|
17
|
+
on :user_entered do |user|
|
18
|
+
last_activity[user.id] = Time.now
|
19
|
+
end
|
20
|
+
|
21
|
+
on :user_left do |user|
|
22
|
+
last_activity.delete(user.id)
|
23
|
+
end
|
24
|
+
|
25
|
+
on :user_spoke do |message|
|
26
|
+
last_activity[message.sender.id] = Time.now
|
27
|
+
end
|
28
|
+
|
29
|
+
on :dj_added do |user|
|
30
|
+
last_activity[user.id] = Time.now
|
31
|
+
end
|
32
|
+
|
33
|
+
on :dj_removed do |user|
|
34
|
+
last_activity[user.id] = Time.now
|
35
|
+
end
|
36
|
+
|
37
|
+
on :song_voted do |song|
|
38
|
+
song.votes.each do |vote|
|
39
|
+
last_activity[vote.user.id] = Time.now
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
on :song_snagged do |snag|
|
44
|
+
last_activity[snag.user.id] = Time.now
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Turntabler
|
2
|
+
# Provides a set of helper methods for making assertions about the content
|
3
|
+
# of various objects
|
4
|
+
# @api private
|
5
|
+
module Assertions
|
6
|
+
# Validates that the given hash *only* includes the specified valid keys.
|
7
|
+
#
|
8
|
+
# @return [nil]
|
9
|
+
# @raise [ArgumentError] if any invalid keys are found
|
10
|
+
# @example
|
11
|
+
# options = {:name => 'John Smith', :age => 30}
|
12
|
+
#
|
13
|
+
# assert_valid_keys(options, :name) # => ArgumentError: Invalid key(s): age
|
14
|
+
# assert_valid_keys(options, 'name', 'age') # => ArgumentError: Invalid key(s): age, name
|
15
|
+
# assert_valid_keys(options, :name, :age) # => nil
|
16
|
+
def assert_valid_keys(hash, *valid_keys)
|
17
|
+
invalid_keys = hash.keys - valid_keys
|
18
|
+
raise ArgumentError, "Invalid key(s): #{invalid_keys.join(', ')}" unless invalid_keys.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Validates that the given value *only* matches one of the specified valid
|
22
|
+
# values.
|
23
|
+
#
|
24
|
+
# @return [nil]
|
25
|
+
# @raise [ArgumentError] if the value is not found
|
26
|
+
# @example
|
27
|
+
# value = :age
|
28
|
+
#
|
29
|
+
# assert_valid_values(value, :name) # => ArgumentError: :age is an invalid value; must be one of: :name
|
30
|
+
# assert_valid_values(value, 'name', 'age') # => ArgumentError: :age is an invalid value; must be one of: :name, "age"
|
31
|
+
# assert_valid_values(value, :name, :age) # => nil
|
32
|
+
def assert_valid_values(value, *valid_values)
|
33
|
+
raise ArgumentError, "#{value} is an invalid value; must be one of: #{valid_values.join(', ')}" unless valid_values.include?(value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'turntabler/playlist'
|
2
|
+
require 'turntabler/preferences'
|
3
|
+
require 'turntabler/user'
|
4
|
+
require 'turntabler/sticker_placement'
|
5
|
+
|
6
|
+
module Turntabler
|
7
|
+
# Represents a user who has authorized with the Turntable service
|
8
|
+
class AuthorizedUser < User
|
9
|
+
# The current availability status of the user ("available", "unavailable", or "away")
|
10
|
+
# @return [String]
|
11
|
+
attribute :status
|
12
|
+
|
13
|
+
# The authenticate token required to connect to the API
|
14
|
+
# @return [String]
|
15
|
+
attribute :auth
|
16
|
+
|
17
|
+
# The user's unique identifier on Facebook
|
18
|
+
# @return [String]
|
19
|
+
attribute :facebook_id, :fbid
|
20
|
+
|
21
|
+
# The user's unique identifier on Twitter
|
22
|
+
# @return [String]
|
23
|
+
attribute :twitter_id, :twitterid
|
24
|
+
|
25
|
+
# The e-mail address the user registered with on Turntable
|
26
|
+
# @return [String]
|
27
|
+
attribute :email
|
28
|
+
|
29
|
+
# Whether the user has a password associated with their account. This is
|
30
|
+
# typically only the case if the user didn't log in via Facebook or Twitter.
|
31
|
+
# @return [Boolean]
|
32
|
+
attribute :has_password, :has_tt_password
|
33
|
+
|
34
|
+
# The user's current Turntable preferences
|
35
|
+
# @return [Turntabler::Preferences]
|
36
|
+
attr_reader :preferences
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def initialize(client, *)
|
40
|
+
@status = 'available'
|
41
|
+
@playlists = {}
|
42
|
+
@preferences = Preferences.new(client)
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
# Authenticates the current user with turntable.
|
47
|
+
#
|
48
|
+
# @return [true]
|
49
|
+
# @raise [Turntabler::Error] if the command fails
|
50
|
+
# @api private
|
51
|
+
def authenticate
|
52
|
+
api('user.authenticate')
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
# Loads the attributes for this user. Attributes will automatically load
|
57
|
+
# when accessed, but this allows data to be forcefully loaded upfront.
|
58
|
+
#
|
59
|
+
# @return [true]
|
60
|
+
# @raise [Turntabler::Error] if the command fails
|
61
|
+
# @example
|
62
|
+
# user.load # => true
|
63
|
+
# user.email # => "john.doe@gmail.com"
|
64
|
+
def load
|
65
|
+
data = api('user.info')
|
66
|
+
self.attributes = data
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
# Updates this user's profile information.
|
71
|
+
#
|
72
|
+
# @param [Hash] attributes The attributes to update
|
73
|
+
# @option attributes [String] :name
|
74
|
+
# @option attributes [String] :status Valid values include "available", "unavailable", and "away"
|
75
|
+
# @option attributes [String] :laptop_name Valid values include "mac", "pc", "linux", "chrome", "iphone", "cake", "intel", and "android"
|
76
|
+
# @option attributes [String] :twitter_id
|
77
|
+
# @option attributes [String] :facebook_url
|
78
|
+
# @option attributes [String] :website
|
79
|
+
# @option attributes [String] :about
|
80
|
+
# @option attributes [String] :top_artists
|
81
|
+
# @option attributes [String] :hangout
|
82
|
+
# @return [true]
|
83
|
+
# @raise [ArgumentError] if an invalid attribute or value is specified
|
84
|
+
# @raise [Turntabler::Error] if the command fails
|
85
|
+
# @example
|
86
|
+
# user.update(:status => "away") # => true
|
87
|
+
# user.update(:laptop_name => "mac") # => true
|
88
|
+
# user.update(:name => "...") # => true
|
89
|
+
def update(attributes = {})
|
90
|
+
assert_valid_keys(attributes, :name, :status, :laptop_name, :twitter_id, :facebook_url, :website, :about, :top_artists, :hangout)
|
91
|
+
|
92
|
+
# Update status
|
93
|
+
status = attributes.delete(:status)
|
94
|
+
update_status(status) if status
|
95
|
+
|
96
|
+
# Update laptop
|
97
|
+
laptop_name = attributes.delete(:laptop_name)
|
98
|
+
update_laptop(laptop_name) if laptop_name
|
99
|
+
|
100
|
+
# Update profile with remaining data
|
101
|
+
update_profile(attributes) if attributes.any?
|
102
|
+
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
# Loads the list of users that are connected to the current user through a
|
107
|
+
# social network like Facebook or Twitter.
|
108
|
+
#
|
109
|
+
# @return [Array<Turntabler::User>]
|
110
|
+
# @raise [Turntabler::Error] if the command fails
|
111
|
+
# @example
|
112
|
+
# user.buddies # => [#<Turntabler::User ...>, ...]
|
113
|
+
def buddies
|
114
|
+
data = api('user.get_buddies')
|
115
|
+
data['buddies'].map {|id| User.new(client, :_id => id)}
|
116
|
+
end
|
117
|
+
|
118
|
+
# Loads the list of users that the current user is a fan of.
|
119
|
+
#
|
120
|
+
# @return [Array<Turntabler::User>]
|
121
|
+
# @raise [Turntabler::Error] if the command fails
|
122
|
+
# @example
|
123
|
+
# user.fan_of # => [#<Turntabler::User ...>, ...]
|
124
|
+
def fan_of
|
125
|
+
data = api('user.get_fan_of')
|
126
|
+
data['fanof'].map {|id| User.new(client, :_id => id)}
|
127
|
+
end
|
128
|
+
|
129
|
+
# Loads the list of users that are a fan of the current user.
|
130
|
+
#
|
131
|
+
# @return [Array<Turntabler::User>]
|
132
|
+
# @raise [Turntabler::Error] if the command fails
|
133
|
+
# @example
|
134
|
+
# user.fans # => [#<Turntabler::User ...>, ...]
|
135
|
+
def fans
|
136
|
+
data = api('user.get_fans')
|
137
|
+
data['fans'].map {|id| User.new(client, :_id => id)}
|
138
|
+
end
|
139
|
+
|
140
|
+
# Gets the avatars that can be set by this user.
|
141
|
+
#
|
142
|
+
# @note This may load the user's data in order to get the ACL if it's not available already
|
143
|
+
# @return [Array<Turntabler::Avatar>]
|
144
|
+
# @raise [Turntabler::Error] if the command fails
|
145
|
+
# @example
|
146
|
+
# user.avatars # => [#<Turntabler::Avatar ...>, ...]
|
147
|
+
def avatars
|
148
|
+
client.avatars.select {|avatar| avatar.available?}
|
149
|
+
end
|
150
|
+
|
151
|
+
# Gets the playlist with the given id.
|
152
|
+
#
|
153
|
+
# @param [String] id The unique identifier for the playlist
|
154
|
+
# @return [Turntabler::Playlist]
|
155
|
+
# @example
|
156
|
+
# user.playlist # => #<Turntabler::Playlist id="default" ...>
|
157
|
+
# user.playlist("rock") # => #<Turntabler::Playlist id="rock" ...>
|
158
|
+
def playlist(id = 'default')
|
159
|
+
@playlists[id] ||= Playlist.new(client, :_id => id)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Gets the stickers that have been purchased by this user.
|
163
|
+
#
|
164
|
+
# @return [Array<Turntabler::Sticker>]
|
165
|
+
# @raise [Turntabler::Error] if the command fails
|
166
|
+
# @example
|
167
|
+
# user.stickers_purchased # => [#<Turntabler::Sticker ...>, ...]
|
168
|
+
def stickers_purchased
|
169
|
+
data = api('sticker.get_purchased_stickers')
|
170
|
+
data['stickers'].map {|sticker_id| Sticker.new(client, :_id => sticker_id)}
|
171
|
+
end
|
172
|
+
|
173
|
+
# Gets the users that have been blocked by this user.
|
174
|
+
#
|
175
|
+
# @return [Array<Turntabler::User>]
|
176
|
+
# @raise [Turntabler::Error] if the command fails
|
177
|
+
# @example
|
178
|
+
# user.blocks # => [#<Turntabler::User ...>, ...]
|
179
|
+
def blocks
|
180
|
+
data = api('block.list_all')
|
181
|
+
data['blocks'].map {|attrs| User.new(client, attrs['block']['blocked'])}
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
# Updates the user's profile information
|
186
|
+
def update_profile(attributes = {})
|
187
|
+
assert_valid_keys(attributes, :name, :twitter_id, :facebook_url, :website, :about, :top_artists, :hangout)
|
188
|
+
|
189
|
+
# Convert attribute names over to their Turntable equivalent
|
190
|
+
{:twitter_id => :twitter, :facebook_url => :facebook, :top_artists => :topartists}.each do |from, to|
|
191
|
+
attributes[to] = attributes.delete(from) if attributes[from]
|
192
|
+
end
|
193
|
+
|
194
|
+
api('user.modify_profile', attributes)
|
195
|
+
self.attributes = attributes
|
196
|
+
true
|
197
|
+
end
|
198
|
+
|
199
|
+
# Updates the laptop currently being used
|
200
|
+
def update_laptop(name)
|
201
|
+
assert_valid_values(name, *%w(mac pc linux chrome iphone cake intel android))
|
202
|
+
|
203
|
+
api('user.modify', :laptop => name)
|
204
|
+
self.attriutes = {'laptop' => name}
|
205
|
+
true
|
206
|
+
end
|
207
|
+
|
208
|
+
# Sets the user's current status
|
209
|
+
def update_status(status = self.status)
|
210
|
+
assert_valid_values(status, *%w(available unavailable away))
|
211
|
+
|
212
|
+
api('presence.update', :status => status)
|
213
|
+
self.attributes = {'status' => status}
|
214
|
+
true
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'turntabler/resource'
|
2
|
+
|
3
|
+
module Turntabler
|
4
|
+
# Represents an avatar for DJ'ing
|
5
|
+
class Avatar < Resource
|
6
|
+
# The minimum points required to activate this avatar
|
7
|
+
# @return [Fixnum]
|
8
|
+
attribute :minimum_points, :min
|
9
|
+
|
10
|
+
# The access control required to activate this avatar
|
11
|
+
# @return [Fixnum]
|
12
|
+
attribute :acl
|
13
|
+
|
14
|
+
# Determines whether this avatar is available to the current user.
|
15
|
+
#
|
16
|
+
# @return [Boolean] +true+ if the avatar is available, otherwise +false+
|
17
|
+
def available?
|
18
|
+
client.user.points >= minimum_points && (!acl || client.user.acl >= acl)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Updates the current user's avatar to this one.
|
22
|
+
#
|
23
|
+
# @return [true]
|
24
|
+
# @raise [Turntabler::Error] if the command fails
|
25
|
+
# @example
|
26
|
+
# avatar.set # => true
|
27
|
+
def set
|
28
|
+
api('user.set_avatar', :avatarid => id)
|
29
|
+
client.user.attributes = {'avatarid' => id}
|
30
|
+
client.user.avatar.attributes = {'min' => minimum_points, 'acl' => acl}
|
31
|
+
true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'turntabler/resource'
|
2
|
+
|
3
|
+
module Turntabler
|
4
|
+
# Represents an instance where a user has been booted from a room
|
5
|
+
class Boot < Resource
|
6
|
+
# The user that was booted from the room
|
7
|
+
# @return [Turntabler::User]
|
8
|
+
attribute :user, :userid do |value|
|
9
|
+
room.build_user(:_id => value)
|
10
|
+
end
|
11
|
+
|
12
|
+
# The moderator that booted the user
|
13
|
+
# @return [Turntabler::User]
|
14
|
+
attribute :moderator, :modid do |value|
|
15
|
+
room.build_user(:_id => value)
|
16
|
+
end
|
17
|
+
|
18
|
+
# The reason for being booted
|
19
|
+
# @return [String]
|
20
|
+
attribute :reason
|
21
|
+
end
|
22
|
+
end
|