turntable_api 0.0.2
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/lib/turntable_api.rb +2 -0
- data/lib/turntable_api/bot.rb +162 -0
- data/lib/turntable_api/version.rb +3 -0
- metadata +103 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'websocker'
|
3
|
+
require 'json'
|
4
|
+
require 'digest/sha1'
|
5
|
+
require 'httparty'
|
6
|
+
|
7
|
+
module TurntableAPI
|
8
|
+
class Bot
|
9
|
+
attr_reader :connected, :roomid
|
10
|
+
|
11
|
+
def initialize(opts = {})
|
12
|
+
@userid = opts[:userid]
|
13
|
+
@clientid = opts[:clientid] || "#{Time.now.to_i}-#{rand}"
|
14
|
+
@auth = opts[:auth]
|
15
|
+
@logger = opts[:logger] || Logger.new(STDOUT)
|
16
|
+
@msgId = 0
|
17
|
+
@command_handlers ||= {}
|
18
|
+
@response_handler ||= {}
|
19
|
+
@received_heartbeat = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def start
|
23
|
+
connect
|
24
|
+
end
|
25
|
+
|
26
|
+
def room_register(roomid)
|
27
|
+
@ws.close unless @ws.nil?
|
28
|
+
if roomid.instance_of?(Hash) then roomid = roomid[:roomid] end
|
29
|
+
connect(roomid)
|
30
|
+
call_api 'room.register', :roomid => roomid
|
31
|
+
@roomid = roomid
|
32
|
+
end
|
33
|
+
|
34
|
+
def room_vote(opts)
|
35
|
+
dir = opts[:val]
|
36
|
+
songid = opts[:songid]
|
37
|
+
raise ArgumentError, "dir and songid are required" if songid.nil? or dir.nil?
|
38
|
+
opts[:vh] ||= hash("#{@roomid}#{dir}#{songid}")
|
39
|
+
opts[:th] ||= hash(rand.to_s)
|
40
|
+
opts[:ph] ||= hash(rand.to_s)
|
41
|
+
send_command('room_vote', opts)
|
42
|
+
end
|
43
|
+
alias_method :vote, :room_vote
|
44
|
+
|
45
|
+
# sends a command and sets up a callback that triggers
|
46
|
+
# when the reply is received
|
47
|
+
def on_response(cmd, opts={}, &blk)
|
48
|
+
msg_id = send_command cmd, opts
|
49
|
+
@response_handler[msg_id] = blk
|
50
|
+
end
|
51
|
+
|
52
|
+
def method_missing(meth, *args)
|
53
|
+
@logger.debug "method_missing #{meth}: #{args}"
|
54
|
+
hash = args[0] unless args.empty?
|
55
|
+
hash ||= {}
|
56
|
+
send_command(meth, hash)
|
57
|
+
end
|
58
|
+
|
59
|
+
# send a command to Turntable.FM
|
60
|
+
def send_command(command, opts={})
|
61
|
+
command = command.to_s.sub('_', '.')
|
62
|
+
call_api(command, opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
# triggered when we receive a command from Turntable.FM
|
66
|
+
def on_command(command, &blk)
|
67
|
+
@command_handlers[command.to_sym] = blk
|
68
|
+
end
|
69
|
+
|
70
|
+
def on_ready(&blk)
|
71
|
+
@ready_handler = blk
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_error(&blk)
|
75
|
+
@error_handler = blk
|
76
|
+
end
|
77
|
+
|
78
|
+
def on_message(msg)
|
79
|
+
if msg == "~m~10~m~no_session"
|
80
|
+
authenticate
|
81
|
+
elsif msg =~ /~m~[0-9]+~m~(~h~[0-9]+)/
|
82
|
+
hb = $1
|
83
|
+
@ready_handler.call unless @received_heartbeat or @ready_handler.nil?
|
84
|
+
@received_heartbeat = true
|
85
|
+
send_text(hb)
|
86
|
+
else
|
87
|
+
msg =~ /~m~\d*~m~(\{.*\})/
|
88
|
+
json = JSON.parse($1)
|
89
|
+
command = json["command"]
|
90
|
+
err = json["err"]
|
91
|
+
msgid = json["msgid"]
|
92
|
+
@error_handler.call(err) unless @error_handler.nil? or err.nil?
|
93
|
+
unless command.nil?
|
94
|
+
blk = @command_handlers[command.to_sym]
|
95
|
+
blk.call(json) unless blk.nil?
|
96
|
+
end
|
97
|
+
unless @response_handler[msgid].nil?()
|
98
|
+
blk = @response_handler[msgid]
|
99
|
+
blk.call(json) unless blk.nil?
|
100
|
+
@response_handler.delete(msgid)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def connect(roomid='unknown')
|
108
|
+
@ws = Websocker::Client.new(:host => chatserver(roomid), :path => "/socket.io/websocket")
|
109
|
+
@ws.connect
|
110
|
+
@ws.on_message do |msg|
|
111
|
+
on_message msg
|
112
|
+
end
|
113
|
+
@ws.on_closed do
|
114
|
+
on_closed
|
115
|
+
end
|
116
|
+
@listener_thread = @ws.listen
|
117
|
+
@connected = true
|
118
|
+
end
|
119
|
+
|
120
|
+
def on_closed
|
121
|
+
@connected = false
|
122
|
+
Thread.kill(@listener_thread) unless @listener_thread.nil?
|
123
|
+
end
|
124
|
+
|
125
|
+
def authenticate
|
126
|
+
call_api "user.authenticate"
|
127
|
+
end
|
128
|
+
|
129
|
+
def call_api(api, addl_params={})
|
130
|
+
messageId = next_message_id
|
131
|
+
params = { 'api' => api, 'userid' => @userid, 'clientid' => @clientid, 'userauth' => @auth, 'msgid' => messageId }
|
132
|
+
params['roomid'] = @roomid if @roomid
|
133
|
+
params.merge!(addl_params)
|
134
|
+
send_text(params.to_json)
|
135
|
+
return messageId
|
136
|
+
end
|
137
|
+
|
138
|
+
def send_text(txt)
|
139
|
+
msg = "~m~#{txt.length}~m~#{txt}"
|
140
|
+
send_raw(msg)
|
141
|
+
end
|
142
|
+
|
143
|
+
def send_raw(msg)
|
144
|
+
@logger.debug "Sent: #{msg}"
|
145
|
+
@ws.send(msg)
|
146
|
+
end
|
147
|
+
|
148
|
+
def next_message_id
|
149
|
+
@msgId += 1
|
150
|
+
end
|
151
|
+
|
152
|
+
def hash(msg)
|
153
|
+
Digest::SHA1.hexdigest(msg)
|
154
|
+
end
|
155
|
+
|
156
|
+
def chatserver(roomid)
|
157
|
+
resp = HTTParty.get("http://turntable.fm/api/room.which_chatserver?roomid=#{roomid}").body
|
158
|
+
JSON.parse(resp)[1]["chatserver"][0]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: turntable_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Lawrence Mcalpin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: websocker
|
16
|
+
requirement: &24047748 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *24047748
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
requirement: &24046992 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *24046992
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: httparty
|
38
|
+
requirement: &24046212 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *24046212
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &24060960 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *24060960
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rake
|
60
|
+
requirement: &24059892 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *24059892
|
69
|
+
description: A simple API for making Turntable.fm bots.
|
70
|
+
email:
|
71
|
+
- lmcalpin+turntable_api@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/turntable_api/bot.rb
|
77
|
+
- lib/turntable_api/version.rb
|
78
|
+
- lib/turntable_api.rb
|
79
|
+
homepage: ''
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project: turntable_api
|
99
|
+
rubygems_version: 1.8.16
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: API for creating Turntable bots.
|
103
|
+
test_files: []
|