turntabler 0.2.0 → 0.2.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/CHANGELOG.md +7 -0
- data/examples/Gemfile.lock +1 -1
- data/lib/turntabler/authorized_user.rb +4 -3
- data/lib/turntabler/client.rb +45 -17
- data/lib/turntabler/error.rb +9 -1
- data/lib/turntabler/resource.rb +2 -1
- data/lib/turntabler/room.rb +4 -1
- data/lib/turntabler/song.rb +2 -3
- data/lib/turntabler/version.rb +1 -1
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# master
|
2
2
|
|
3
|
+
## 0.2.1 / 2013-02-16
|
4
|
+
|
5
|
+
* Fix exceptions on initial connection not causing reconnection process to kick in
|
6
|
+
* Fix exceptions in reconnects causing the reconnect process to halt retrying
|
7
|
+
* Fix reconnects not occurring when socket is closed without a killdashnine event from Turntable
|
8
|
+
* Fix exceptions in keepalive timer causing the EM reactor to be shut down
|
9
|
+
|
3
10
|
## 0.2.0 / 2013-02-16
|
4
11
|
|
5
12
|
* Respect the keepalive update interval from API responses
|
data/examples/Gemfile.lock
CHANGED
@@ -77,9 +77,10 @@ module Turntabler
|
|
77
77
|
# @raise [Turntabler::Error] if the command fails
|
78
78
|
def login
|
79
79
|
response = EventMachine::HttpRequest.new('https://turntable.fm/api/user.email_login').get(:query => {:email => email, :password => password, :client => client.id}).response
|
80
|
-
data = JSON.parse(response)
|
81
|
-
raise(
|
82
|
-
|
80
|
+
success, data = response.empty? ? [nil, {}] : JSON.parse(response)
|
81
|
+
raise(ConnectionError, data['err']) unless success
|
82
|
+
|
83
|
+
self.attributes = data
|
83
84
|
true
|
84
85
|
end
|
85
86
|
|
data/lib/turntabler/client.rb
CHANGED
@@ -71,14 +71,17 @@ module Turntabler
|
|
71
71
|
# Setup default event handlers
|
72
72
|
on(:heartbeat) { on_heartbeat }
|
73
73
|
on(:session_missing) { on_session_missing }
|
74
|
+
on(:session_ended) { on_session_ended }
|
74
75
|
|
75
76
|
# Connect to an initial room / server
|
76
|
-
|
77
|
-
room
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
reconnect_from(ConnectionError, APIError) do
|
78
|
+
if room_name = options[:room]
|
79
|
+
room(room_name).enter
|
80
|
+
elsif url = options[:url]
|
81
|
+
connect(url)
|
82
|
+
else
|
83
|
+
connect
|
84
|
+
end
|
82
85
|
end
|
83
86
|
|
84
87
|
instance_eval(&block) if block_given?
|
@@ -88,7 +91,7 @@ module Turntabler
|
|
88
91
|
# this will also attempt to authenticate the user.
|
89
92
|
#
|
90
93
|
# @api private
|
91
|
-
# @note This
|
94
|
+
# @note This will only open a new connection if the client isn't already connected to the given url
|
92
95
|
# @param [String] url The url to open a connection to
|
93
96
|
# @return [true]
|
94
97
|
# @raise [Turntabler::Error] if the connection cannot be opened
|
@@ -116,15 +119,20 @@ module Turntabler
|
|
116
119
|
# @return [true]
|
117
120
|
def close(allow_reconnect = false)
|
118
121
|
if @connection
|
122
|
+
# Disable reconnects if specified
|
123
|
+
reconnect = @reconnect
|
124
|
+
@reconnect = reconnect && allow_reconnect
|
125
|
+
|
126
|
+
# Clean up timers / connections
|
119
127
|
@keepalive_timer.cancel if @keepalive_timer
|
120
128
|
@keepalive_timer = nil
|
121
129
|
@connection.close
|
122
130
|
|
131
|
+
# Revert change to reconnect config once the final signal is received
|
123
132
|
wait do |&resume|
|
124
133
|
on(:session_ended, :once => true) { resume.call }
|
125
134
|
end
|
126
|
-
|
127
|
-
on_session_ended(allow_reconnect)
|
135
|
+
@reconnect = reconnect
|
128
136
|
end
|
129
137
|
|
130
138
|
true
|
@@ -146,7 +154,7 @@ module Turntabler
|
|
146
154
|
# @return [Hash] The data returned from the Turntable service
|
147
155
|
# @raise [Turntabler::Error] if the connection is not open or the command fails to execute
|
148
156
|
def api(command, params = {})
|
149
|
-
raise(
|
157
|
+
raise(ConnectionError, 'Connection is not open') unless @connection && @connection.connected?
|
150
158
|
|
151
159
|
message_id = @connection.publish(params.merge(:api => command))
|
152
160
|
|
@@ -159,7 +167,7 @@ module Turntabler
|
|
159
167
|
data
|
160
168
|
else
|
161
169
|
error = data['error'] || data['err']
|
162
|
-
raise
|
170
|
+
raise APIError, "Command \"#{command}\" failed with message: \"#{error}\""
|
163
171
|
end
|
164
172
|
end
|
165
173
|
|
@@ -420,7 +428,7 @@ module Turntabler
|
|
420
428
|
assert_valid_keys(options, :artist, :duration, :page)
|
421
429
|
options = {:page => 1}.merge(options)
|
422
430
|
|
423
|
-
raise(
|
431
|
+
raise(APIError, 'User must be in a room to search for songs') unless room
|
424
432
|
|
425
433
|
if artist = options[:artist]
|
426
434
|
query = "title: #{query}"
|
@@ -436,7 +444,7 @@ module Turntabler
|
|
436
444
|
on(:search_failed, :once => true, :if => {'query' => query}) { resume.call }
|
437
445
|
end
|
438
446
|
|
439
|
-
songs || raise(
|
447
|
+
songs || raise(APIError, 'Search failed to complete')
|
440
448
|
end
|
441
449
|
|
442
450
|
# Triggers callback handlers for the given Turntable command. This should
|
@@ -495,7 +503,9 @@ module Turntabler
|
|
495
503
|
|
496
504
|
# Periodically update the user's status to remain available
|
497
505
|
@keepalive_timer.cancel if @keepalive_timer
|
498
|
-
@keepalive_timer = EM::Synchrony.add_periodic_timer(interval)
|
506
|
+
@keepalive_timer = EM::Synchrony.add_periodic_timer(interval) do
|
507
|
+
Turntabler.run { user.update(:status => user.status) }
|
508
|
+
end
|
499
509
|
end
|
500
510
|
end
|
501
511
|
|
@@ -518,20 +528,38 @@ module Turntabler
|
|
518
528
|
|
519
529
|
# Callback when the session has ended. This will automatically reconnect if
|
520
530
|
# allowed to do so.
|
521
|
-
def on_session_ended
|
531
|
+
def on_session_ended
|
522
532
|
url = @connection.url
|
523
533
|
room = @room
|
524
534
|
@connection = nil
|
525
535
|
@room = nil
|
526
536
|
|
527
537
|
# Automatically reconnect to the room / server if allowed
|
528
|
-
if @reconnect
|
529
|
-
|
538
|
+
if @reconnect
|
539
|
+
reconnect_from(Exception) do
|
530
540
|
room ? room.enter : connect(url)
|
531
541
|
trigger(:reconnected)
|
532
542
|
end
|
533
543
|
end
|
534
544
|
end
|
545
|
+
|
546
|
+
# Runs a given block and retries that block after a certain period of time
|
547
|
+
# if any of the specified exceptions are raised. Note that there is no
|
548
|
+
# limit on the number of attempts to retry.
|
549
|
+
def reconnect_from(*exceptions)
|
550
|
+
begin
|
551
|
+
yield
|
552
|
+
rescue *exceptions => ex
|
553
|
+
if @reconnect
|
554
|
+
logger.debug "Connection failed: #{ex.message}"
|
555
|
+
EM::Synchrony.sleep(@reconnect_wait)
|
556
|
+
logger.debug 'Attempting to reconnect'
|
557
|
+
retry
|
558
|
+
else
|
559
|
+
raise
|
560
|
+
end
|
561
|
+
end
|
562
|
+
end
|
535
563
|
|
536
564
|
# Pauses the current fiber until it is resumed with response data. This
|
537
565
|
# can only get resumed explicitly by the provided block.
|
data/lib/turntabler/error.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
module Turntabler
|
2
|
-
# Represents an error
|
2
|
+
# Represents an error within the library
|
3
3
|
class Error < StandardError
|
4
4
|
end
|
5
|
+
|
6
|
+
# Represents an error that occurred while connecting to the Turntable API
|
7
|
+
class ConnectionError < Error
|
8
|
+
end
|
9
|
+
|
10
|
+
# Represents an error that occurred while interacting with the Turntable API
|
11
|
+
class APIError < Error
|
12
|
+
end
|
5
13
|
end
|
data/lib/turntabler/resource.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'pp'
|
2
2
|
require 'turntabler/assertions'
|
3
3
|
require 'turntabler/digest_helpers'
|
4
|
+
require 'turntabler/error'
|
4
5
|
|
5
6
|
module Turntabler
|
6
7
|
# Represents an object that's been created using content from Turntable. This
|
@@ -185,7 +186,7 @@ module Turntabler
|
|
185
186
|
|
186
187
|
# Gets the current room the user is in
|
187
188
|
def room
|
188
|
-
client.room || raise(
|
189
|
+
client.room || raise(APIError, 'User is not currently in a room')
|
189
190
|
end
|
190
191
|
|
191
192
|
# Determines whether the user is currently in a room
|
data/lib/turntabler/room.rb
CHANGED
@@ -128,7 +128,10 @@ module Turntabler
|
|
128
128
|
def host
|
129
129
|
begin
|
130
130
|
response = EventMachine::HttpRequest.new("http://turntable.fm/api/room.which_chatserver?roomid=#{id}").get.response
|
131
|
-
|
131
|
+
success, data = response.empty? ? [nil, {}] : JSON.parse(response)
|
132
|
+
raise(ConnectionError, data['err']) unless success
|
133
|
+
|
134
|
+
self.attributes = data
|
132
135
|
end unless @host
|
133
136
|
@host
|
134
137
|
end
|
data/lib/turntabler/song.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'turntabler/error'
|
2
1
|
require 'turntabler/resource'
|
3
2
|
require 'turntabler/user'
|
4
3
|
require 'turntabler/vote'
|
@@ -232,7 +231,7 @@ module Turntabler
|
|
232
231
|
# Asserts that this is the song currently being played in the room the user
|
233
232
|
# is in. Raises Turntabler::Error if this is not the case.
|
234
233
|
def assert_current_song
|
235
|
-
raise(
|
234
|
+
raise(APIError, "Song \"#{id}\" is not currently playing") unless room.current_song == self
|
236
235
|
end
|
237
236
|
|
238
237
|
# Gets the index of this song within the given playlist. Raises Turntabler::Error
|
@@ -240,7 +239,7 @@ module Turntabler
|
|
240
239
|
def index(playlist_id)
|
241
240
|
playlist = client.user.playlist(playlist_id)
|
242
241
|
index = playlist.songs.index(self)
|
243
|
-
raise(
|
242
|
+
raise(APIError, "Song \"#{id}\" is not in playlist \"#{playlist.id}\"") unless index
|
244
243
|
return playlist, index
|
245
244
|
end
|
246
245
|
end
|
data/lib/turntabler/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: turntabler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Aaron Pfeifer
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2013-02-
|
13
|
+
date: 2013-02-17 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: em-synchrony
|