libastag 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/CHANGES +7 -0
- data/MIT-LICENSE +19 -0
- data/README +65 -0
- data/Rakefile +276 -0
- data/TODO +7 -0
- data/doc/classes/Helpers/REXML/Attributes.html +179 -0
- data/doc/classes/Helpers/REXML.html +115 -0
- data/doc/classes/Helpers.html +181 -0
- data/doc/classes/Libastag/Rabbit.html +462 -0
- data/doc/classes/Libastag/RabitEar.html +120 -0
- data/doc/classes/Libastag/RabitLed.html +120 -0
- data/doc/classes/Libastag.html +141 -0
- data/doc/classes/Request/Action.html +213 -0
- data/doc/classes/Request/Base/Event.html +226 -0
- data/doc/classes/Request/Base/EventCollection.html +246 -0
- data/doc/classes/Request/Base.html +134 -0
- data/doc/classes/Request/GET_EARS_POSITION.html +151 -0
- data/doc/classes/Request/Query.html +244 -0
- data/doc/classes/Request/SetEarsPosition.html +213 -0
- data/doc/classes/Request/TtsMessage.html +235 -0
- data/doc/classes/Request.html +414 -0
- data/doc/classes/Response/AbuseSending.html +165 -0
- data/doc/classes/Response/Base/BadServerRsp.html +163 -0
- data/doc/classes/Response/Base/GoodServerRsp.html +161 -0
- data/doc/classes/Response/Base/ServerRsp.html +347 -0
- data/doc/classes/Response/Base.html +162 -0
- data/doc/classes/Response/Blacklist.html +165 -0
- data/doc/classes/Response/ChorNotSend.html +166 -0
- data/doc/classes/Response/ChorSend.html +165 -0
- data/doc/classes/Response/CommandSend.html +168 -0
- data/doc/classes/Response/EarPositionNotSend.html +165 -0
- data/doc/classes/Response/EarPositionSend.html +165 -0
- data/doc/classes/Response/EmptyServerRsp.html +161 -0
- data/doc/classes/Response/LangListUser.html +166 -0
- data/doc/classes/Response/LinkPreview.html +165 -0
- data/doc/classes/Response/ListFriend.html +165 -0
- data/doc/classes/Response/ListReceivedMsg.html +165 -0
- data/doc/classes/Response/MessageNotSend.html +165 -0
- data/doc/classes/Response/MessageSend.html +165 -0
- data/doc/classes/Response/NabCastNotSend.html +169 -0
- data/doc/classes/Response/NabCastSend.html +165 -0
- data/doc/classes/Response/NoCorrectParameters.html +165 -0
- data/doc/classes/Response/NoGoodTokenOrSerial.html +165 -0
- data/doc/classes/Response/NotV2Rabbit.html +165 -0
- data/doc/classes/Response/PositionEar.html +166 -0
- data/doc/classes/Response/ProtocolExcepion.html +164 -0
- data/doc/classes/Response/RabbitName.html +164 -0
- data/doc/classes/Response/RabbitSleep.html +164 -0
- data/doc/classes/Response/RabbitVersion.html +164 -0
- data/doc/classes/Response/Signature.html +164 -0
- data/doc/classes/Response/Timezone.html +164 -0
- data/doc/classes/Response/TtsNotSend.html +168 -0
- data/doc/classes/Response/TtsSend.html +165 -0
- data/doc/classes/Response/VoiceListTts.html +165 -0
- data/doc/classes/Response/WebRadioNotSend.html +165 -0
- data/doc/classes/Response/WebRadioSend.html +165 -0
- data/doc/classes/Response.html +337 -0
- data/doc/classes/VioletAPI.html +118 -0
- data/doc/created.rid +1 -0
- data/doc/dot/f_0.dot +14 -0
- data/doc/dot/f_0.png +0 -0
- data/doc/dot/f_4.dot +57 -0
- data/doc/dot/f_4.png +0 -0
- data/doc/dot/f_5.dot +489 -0
- data/doc/dot/f_5.png +0 -0
- data/doc/dot/f_6.dot +55 -0
- data/doc/dot/f_6.png +0 -0
- data/doc/dot/f_7.dot +30 -0
- data/doc/dot/f_7.png +0 -0
- data/doc/dot/f_8.dot +142 -0
- data/doc/dot/f_8.png +0 -0
- data/doc/files/CHANGES.html +126 -0
- data/doc/files/MIT-LICENSE.html +134 -0
- data/doc/files/README.html +192 -0
- data/doc/files/TODO.html +126 -0
- data/doc/files/lib/libastag_rb.html +116 -0
- data/doc/files/lib/violet/helpers_rb.html +123 -0
- data/doc/files/lib/violet/request_rb.html +133 -0
- data/doc/files/lib/violet/response_rb.html +220 -0
- data/doc/files/lib/violet/violetapi_rb.html +114 -0
- data/doc/fr_class_index.html +79 -0
- data/doc/fr_file_index.html +35 -0
- data/doc/fr_method_index.html +56 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/libastag.rb +116 -0
- data/lib/violet/helpers.rb +48 -0
- data/lib/violet/request.rb +301 -0
- data/lib/violet/response.rb +412 -0
- data/lib/violet/violetapi.rb +14 -0
- data/test/fake_violet_srv.rb +94 -0
- data/test/test_helpers.rb +31 -0
- data/test/test_request.rb +20 -0
- data/test/test_response.rb +295 -0
- data/test/test_send.rb +137 -0
- metadata +264 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
=begin rdoc
|
|
2
|
+
|
|
3
|
+
=violet/response.rb
|
|
4
|
+
|
|
5
|
+
==Summary
|
|
6
|
+
this module handle servers messages. Main method/class are Response.parse and Response::Base::ServerRsp (well documented).
|
|
7
|
+
|
|
8
|
+
you should only use Response.parse with the server's message (xml) as argument, it returns a ServerRsp instance
|
|
9
|
+
from the corresponding class (see all the ServerRsp subclass). with a ServerRsp instance you can use :
|
|
10
|
+
|
|
11
|
+
[ r.has_x? ]
|
|
12
|
+
return +true+ if r has at least one element of name "x", return +false+ otherwhise.
|
|
13
|
+
[ r.has_many_xs? ]
|
|
14
|
+
return +true+ if r has more than one element of name "x", return +false+ otherwhise.
|
|
15
|
+
[ r.x ]
|
|
16
|
+
find the first xml element of name x and return it's text if any, or a hash of it's options
|
|
17
|
+
[ r.x ]
|
|
18
|
+
find all xml element of name x and return an Array of their text if any, or their options.
|
|
19
|
+
[ r.good? ]
|
|
20
|
+
return +true+ if the response is not an error, +false+ otherwhise.
|
|
21
|
+
[ r.bad? ]
|
|
22
|
+
return +true+ if the response is an error, +false+ otherwhise.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
==Examples :
|
|
26
|
+
>> rsp = Response.parse('<?xml version="1.0" encoding="UTF-8"?><rsp><blacklist nb="2"/><pseudo name="toto"/><pseudo name="titi"/></rsp>')
|
|
27
|
+
=> #<Response::Blacklist:0x2acd8c08f2f8 @xml=<UNDEFINED> ... </>>
|
|
28
|
+
>> rsp.good?
|
|
29
|
+
=> true
|
|
30
|
+
>> rsp.has_message?
|
|
31
|
+
=> false
|
|
32
|
+
>> rsp.message
|
|
33
|
+
NameError: undefined local variable or method message for #<Response::Blacklist:0x2b1f056afdc0 @xml=<UNDEFINED> ... </>>
|
|
34
|
+
>> rsp.has_blacklist?
|
|
35
|
+
=> true
|
|
36
|
+
>> rsp.blacklist
|
|
37
|
+
=> {:nb=>"2"}
|
|
38
|
+
>> rsp.pseudo
|
|
39
|
+
=> {:name=>"toto"}
|
|
40
|
+
>> rsp.has_many_pseudos?
|
|
41
|
+
=> true
|
|
42
|
+
>> rsp.pseudos
|
|
43
|
+
=> [{:name=>"toto"}, {:name=>"titi"}]
|
|
44
|
+
|
|
45
|
+
==Low Level
|
|
46
|
+
|
|
47
|
+
if you want to access to the REXML::Document object of a ServerRsp you can either use rsp.xml or use ServerRsp#get_all method.
|
|
48
|
+
|
|
49
|
+
=end
|
|
50
|
+
|
|
51
|
+
module Response
|
|
52
|
+
require File.join(File.dirname(__FILE__), 'helpers.rb')
|
|
53
|
+
|
|
54
|
+
# ProtocolExcepion are raised if server return a unknown response.
|
|
55
|
+
#
|
|
56
|
+
# see http://api.nabaztag.com/docs/home.html#messages
|
|
57
|
+
class ProtocolExcepion < Exception; end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# contains some basic stuff, abstract class etc. they're used internaly and you should not access this module.
|
|
61
|
+
module Base
|
|
62
|
+
require 'rexml/document'
|
|
63
|
+
|
|
64
|
+
# base class used to handle Violet server's responses.
|
|
65
|
+
#
|
|
66
|
+
# We want to access to all xml elements easily, like the powerful ActiveRecord 'find' function. This class
|
|
67
|
+
# provide virtual accessor and predicate for elements. If you have a ServerRsp, rsp.has_message? will return
|
|
68
|
+
# +true+ if rsp has a 'message' element, and rsp.has_many_messages? will return +true+ if rsp has more than one
|
|
69
|
+
# 'message' element. rsp.message will return the first message element and rsp.messages will return an Array
|
|
70
|
+
# that contains all message elements of rsp (see doc of Response module for examples).
|
|
71
|
+
class ServerRsp
|
|
72
|
+
# create a ServerRsp with the raw argument. raw must be the xml text of the server's response. if the xml
|
|
73
|
+
# is malformed, a REXML::ParseException will be raised.
|
|
74
|
+
def initialize raw
|
|
75
|
+
@xml = REXML::Document.new raw
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# It's possible to access the REXML::Document object if needed, but try to use virtual accessors and get_all
|
|
79
|
+
# if possible.
|
|
80
|
+
attr_reader :xml
|
|
81
|
+
|
|
82
|
+
# return +true+ if the response is not an error, +false+ otherwhise.
|
|
83
|
+
def good?
|
|
84
|
+
self.is_a? GoodServerRsp
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# return +true+ if the response is an error, +false+ otherwhise.
|
|
88
|
+
def bad?
|
|
89
|
+
self.is_a? BadServerRsp
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# ==Summary
|
|
93
|
+
# get all xml's element that match name.
|
|
94
|
+
#
|
|
95
|
+
#
|
|
96
|
+
# ==Arguments
|
|
97
|
+
# name : name of the element you want to fetch (see examples)
|
|
98
|
+
# block : a block of code that take a REXML::Element in parameter. if no block is given, it return an Array of REXML::Element.
|
|
99
|
+
#
|
|
100
|
+
#
|
|
101
|
+
# ==Examples
|
|
102
|
+
# <b>Side effect</b>
|
|
103
|
+
# >> rsp = Response.parse('<?xml version="1.0" encoding="UTF-8"?><rsp><langListUser nb="4"/><myLang lang="fr"/><myLang lang="us"/><myLang lang="uk"/><myLang lang="de"/></rsp>')
|
|
104
|
+
# => #<Response::LangListUser:0x2b16c5e17510 @xml=<UNDEFINED> ... </>>
|
|
105
|
+
# >> rsp.get_all(:myLang) do |e|
|
|
106
|
+
# >> puts "you can use '#{e.attribute('lang').value}'"
|
|
107
|
+
# >> end
|
|
108
|
+
# you can use 'fr'
|
|
109
|
+
# you can use 'us'
|
|
110
|
+
# you can use 'uk'
|
|
111
|
+
# you can use 'de'
|
|
112
|
+
# => [nil, nil, nil, nil]
|
|
113
|
+
#
|
|
114
|
+
# <b>usage of returned value</b>
|
|
115
|
+
# >> langs = rsp.get_all(:myLang) { |e| e.attribute('lang').value }
|
|
116
|
+
# => ["fr", "us", "uk", "de"]
|
|
117
|
+
def get_all name
|
|
118
|
+
# REXML::XPath.match(@xml, element).collect do |e| <= this one is for a recursive search.
|
|
119
|
+
@xml.root.elements.collect(name.to_s) do |e|
|
|
120
|
+
if block_given? then yield(e) else e end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# here some magic code :)
|
|
125
|
+
def method_missing(name) #:nodoc:
|
|
126
|
+
# this method to transforme REXML::Element into text or hash
|
|
127
|
+
filter = Proc.new do |e|
|
|
128
|
+
e.text || e.attributes.to_hash
|
|
129
|
+
end
|
|
130
|
+
# raise an error when there are no results and method_missing is not a question
|
|
131
|
+
check = Proc.new do |ary|
|
|
132
|
+
if ary.empty?
|
|
133
|
+
raise NameError.new("undefined local variable or method #{$1} for #{self.inspect}")
|
|
134
|
+
else
|
|
135
|
+
ary
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
case name.to_s
|
|
140
|
+
when /^has_many_(.+)s\?$/ then get_all($1).size > 1
|
|
141
|
+
when /^has_(.+)\?$/ then get_all($1).size > 0
|
|
142
|
+
when /(.*)s$/ then check.call( get_all($1).collect(&filter) )
|
|
143
|
+
when /(.*)/ then check.call( get_all($1).collect(&filter) ).first
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# superclass of error messages. They're 'simple', they only have a message and a comment element.
|
|
151
|
+
# see http://api.nabaztag.com/docs/home.html#messages
|
|
152
|
+
class BadServerRsp < ServerRsp; end
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# superclass of messages with infos (no error).
|
|
156
|
+
class GoodServerRsp < ServerRsp; end
|
|
157
|
+
|
|
158
|
+
end # module Response::Base
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# superclass of messages with no infos.
|
|
163
|
+
class EmptyServerRsp < Base::ServerRsp; end
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
#
|
|
167
|
+
# Errors messages from server
|
|
168
|
+
#
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# Too much requests sent
|
|
172
|
+
# rsp.message # => "ABUSESENDING"
|
|
173
|
+
# rsp.comment # => "Too much message sending,try later"
|
|
174
|
+
class AbuseSending < Base::BadServerRsp; end
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# Wrong token or serial number
|
|
178
|
+
# rsp.message # => "NOGOODTOKENORSERIAL"
|
|
179
|
+
# rsp.comment # => "Your token or serial number are not correct !"
|
|
180
|
+
class NoGoodTokenOrSerial < Base::BadServerRsp; end
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# Wrong music id (either not in your personal MP3s list or not existing)
|
|
184
|
+
# rsp.message # => "MESSAGENOTSEND"
|
|
185
|
+
# rsp.comment # => "Your idmessage is not correct or is private"
|
|
186
|
+
class MessageNotSend < Base::BadServerRsp; end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# Nabcast not posted because music id is not part of your personal MP3s or because the nabcast id does not belong
|
|
190
|
+
# to you or is not existing
|
|
191
|
+
# rsp.message # => "NABCASTNOTSEND"
|
|
192
|
+
# rsp.comment # => "Your idmessage is private"
|
|
193
|
+
#
|
|
194
|
+
# rsp.message # => "NABCASTNOTSEND"
|
|
195
|
+
# rsp.comment # => "Your nabcast id is not correct or is private"
|
|
196
|
+
class NabCastNotSend < Base::BadServerRsp; end
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
# Message not sent
|
|
200
|
+
# rsp.message # => "MESSAGENOTSEND"
|
|
201
|
+
# rsp.comment # => "Your message could not be sent"
|
|
202
|
+
class MessageNotSend < Base::BadServerRsp; end
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# TTS creation problem or TTS not send
|
|
206
|
+
# rsp.message # => "TTSNOTSEND"
|
|
207
|
+
# rsp.comment # => "Your text could not be sent"
|
|
208
|
+
#
|
|
209
|
+
# rsp.message # => "TTSNOTSEND"
|
|
210
|
+
# rsp.comment # => "Your text could not be sent"
|
|
211
|
+
class TtsNotSend < Base::BadServerRsp; end
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
# Choregraphy message not sent because the "chor" command was incorrect
|
|
215
|
+
# rsp.message # => "CHORNOTSEND"
|
|
216
|
+
# rsp.comment # => "Your chor could not be sent (bad chor)"
|
|
217
|
+
class ChorNotSend < Base::BadServerRsp; end
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
# Ears position not sent because the given position is incorrect
|
|
221
|
+
# rsp.message # => "EARPOSITIONNOTSEND"
|
|
222
|
+
# rsp.comment # => "Your ears command could not be sent"
|
|
223
|
+
class EarPositionNotSend < Base::BadServerRsp; end
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
# URL was not sent (api_stream)
|
|
227
|
+
# rsp.message # => "WEBRADIONOTSEND"
|
|
228
|
+
# rsp.comment # => "Your webradio could not be sent"
|
|
229
|
+
class WebRadioNotSend < Base::BadServerRsp; end
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
# urlList parameter missing (api_stream)
|
|
233
|
+
# rsp.message # => "NOCORRECTPARAMETERS"
|
|
234
|
+
# rsp.comment # => "Please check urlList parameter !"
|
|
235
|
+
class NoCorrectParameters < Base::BadServerRsp; end
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
# The rabbit is not a Nabaztag/tag
|
|
239
|
+
# rsp.message # => "NOTV2RABBIT"
|
|
240
|
+
# rsp.comment # => "V2 rabbit can use this action"
|
|
241
|
+
class NotV2Rabbit < Base::BadServerRsp; end
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
#
|
|
245
|
+
# Infos messages from server
|
|
246
|
+
#
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
# Nabcast posted
|
|
250
|
+
# rsp.message # => "NABCASTSEND"
|
|
251
|
+
# rsp.comment # => "Your nabcast has been sent"
|
|
252
|
+
class NabCastSend < Base::GoodServerRsp; end
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# Message sent
|
|
256
|
+
# rsp.message # => "MESSAGESEND"
|
|
257
|
+
# rsp.comment # => "Your message has been sent"
|
|
258
|
+
class MessageSend < Base::GoodServerRsp; end
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
# TTS message sent
|
|
262
|
+
# rsp.message # => "TTSSEND"
|
|
263
|
+
# rsp.comment # => "Your text has been sent"
|
|
264
|
+
class TtsSend < Base::GoodServerRsp; end
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
# Choregraphy message sent
|
|
268
|
+
# rsp.message # => "CHORSEND"
|
|
269
|
+
# rsp.comment # => "Your chor has been sent"
|
|
270
|
+
class ChorSend < Base::GoodServerRsp; end
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
# Ears position sent
|
|
274
|
+
# rsp.message # => "EARPOSITIONSEND"
|
|
275
|
+
# rsp.comment # => "Your ears command has been sent"
|
|
276
|
+
class EarPositionSend < Base::GoodServerRsp; end
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
# URL was sent (api_stream)
|
|
280
|
+
# rsp.message # => "WEBRADIOSEND"
|
|
281
|
+
# rsp.comment # => "Your webradio has been sent"
|
|
282
|
+
class WebRadioSend < Base::GoodServerRsp; end
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
# Getting the ears position
|
|
286
|
+
# rsp.message # => "POSITIONEAR"
|
|
287
|
+
# rsp.leftposition # => "8"
|
|
288
|
+
# rsp.rightposition # => "10"
|
|
289
|
+
class PositionEar < Base::GoodServerRsp; end
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
# Preview the TTS or music (with music id) without sending it
|
|
293
|
+
# rsp.message # => "LINKPREVIEW"
|
|
294
|
+
# rsp.comment # => "XXXX"
|
|
295
|
+
class LinkPreview < Base::GoodServerRsp; end
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
# Getting friends list
|
|
299
|
+
# rsp.listfriend # => {:nb=>"2"}
|
|
300
|
+
# rsp.friends # => [{:name=>"toto"}, {:name=>"titi"}]
|
|
301
|
+
class ListFriend < Base::GoodServerRsp; end
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# a count and the list of the messages in your inbox
|
|
305
|
+
# rsp.listreceivedmsg # => {:nb=>"1"}
|
|
306
|
+
# rsp.msg # => {:title=>"my message", :date=>"today 11:59", :from=>"toto", :url=>"broad/001/948.mp3"}
|
|
307
|
+
class ListReceivedMsg < Base::GoodServerRsp; end
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
# the timezone in which your Nabaztag is set
|
|
311
|
+
# rsp.timezone # => "(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London"
|
|
312
|
+
class Timezone < Base::GoodServerRsp; end
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
# the signature defined for the Nabaztag
|
|
316
|
+
# rsp.signature # => "i'm Ruby powered !"
|
|
317
|
+
class Signature < Base::GoodServerRsp; end
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
# a count and the list of people in your blacklist
|
|
321
|
+
# rsp.blacklist # => {:nb=>"2"}
|
|
322
|
+
# rsp.pseudos # => [{:name=>"toto"}, {:name=>"tata"}]
|
|
323
|
+
class Blacklist < Base::GoodServerRsp; end
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
# to know if the Nabaztag is sleeping
|
|
327
|
+
# rsp.rabbitSleep # => "YES"
|
|
328
|
+
class RabbitSleep < Base::GoodServerRsp; end
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
# to know if the Nabaztag is a Nabaztag (V1) or a Nabaztag/tag (V2)
|
|
332
|
+
# rsp.rabbitVersion # => "V2"
|
|
333
|
+
class RabbitVersion < Base::GoodServerRsp; end
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
# a list of all supported languages/voices for TTS (text to speach) engine
|
|
337
|
+
# rsp.voiceListTTS # => {:nb=>"2"}
|
|
338
|
+
# rsp.voices # => [{:command=>"claire22k", :lang=>"fr"}, {:command=>"helga22k", :lang=>"de"}]
|
|
339
|
+
class VoiceListTts < Base::GoodServerRsp; end
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
# the name of the Nabaztag
|
|
343
|
+
# rsp.rabbitName # => "nabmaster"
|
|
344
|
+
class RabbitName < Base::GoodServerRsp; end
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
# Get the languages selected for the Nabaztag
|
|
348
|
+
# rsp.langListUser # => {"nb"=>"4"}
|
|
349
|
+
# rsp.myLang # => {:lang=>"fr"}
|
|
350
|
+
# rsp.myLangs # => [{:lang=>"fr"}, {:lang=>"us"}, {:lang=>"uk"}, {:lang=>"de"}]
|
|
351
|
+
class LangListUser < Base::GoodServerRsp; end
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
# Command has been send.
|
|
355
|
+
# rsp.message # => "COMMANDSEND"
|
|
356
|
+
# rsp.comment # => "You rabbit will change status"
|
|
357
|
+
#
|
|
358
|
+
# see Request::SET_RABBIT_ASLEEP and Request::SET_RABBIT_AWAKE
|
|
359
|
+
class CommandSend < Base::GoodServerRsp; end
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
# ==Summary
|
|
363
|
+
# parse given raw (xml text) and return a new ServerRsp from the corresponding class.
|
|
364
|
+
#
|
|
365
|
+
# Violet messages aren't
|
|
366
|
+
# easy to identify, because there is not id. So we have to study the xml content if there are no message
|
|
367
|
+
# element (easier to detect the response type).
|
|
368
|
+
#
|
|
369
|
+
#
|
|
370
|
+
# ==Arguments
|
|
371
|
+
# the xml response of the Violet Server.
|
|
372
|
+
#
|
|
373
|
+
#
|
|
374
|
+
# ==Exceptions
|
|
375
|
+
# this method raise a ProtocolExcepion if it's fail to detect the
|
|
376
|
+
# kind of the server's response.
|
|
377
|
+
#
|
|
378
|
+
#
|
|
379
|
+
# ==Examples
|
|
380
|
+
# >> rsp = Response.parse('<?xml version="1.0" encoding="UTF-8"?><rsp><rabbitSleep>YES</rabbitSleep></rsp>')
|
|
381
|
+
# => #<Response::RabbitSleep:0x2b16c5e476e8 @xml=<UNDEFINED> ... </>>
|
|
382
|
+
# >> rsp.class
|
|
383
|
+
# => Response::RabbitSleep
|
|
384
|
+
#
|
|
385
|
+
# >> rsp = Response.parse('<?xml version="1.0" encoding="UTF-8"?><rsp><rabbitVersion>V1</rabbitVersion></rsp>')
|
|
386
|
+
# => #<Response::RabbitVersion:0x2b16c5e154b8 @xml=<UNDEFINED> ... </>>
|
|
387
|
+
# >> rsp.class
|
|
388
|
+
# => Response::RabbitVersion
|
|
389
|
+
#
|
|
390
|
+
def Response.parse raw
|
|
391
|
+
tmp = Base::ServerRsp.new raw # we shouldn't create ServerRsp instances, but act as if you didn't see ;)
|
|
392
|
+
klassname = if raw =~ %r|<rsp>\s*</rsp>|i
|
|
393
|
+
'EmptyServerRsp'
|
|
394
|
+
elsif tmp.has_message?
|
|
395
|
+
/^#{tmp.message}$/i
|
|
396
|
+
else
|
|
397
|
+
/^#{tmp.xml.root.elements[1].name}$/i # REXML::Elements#[] has index 1-based and not 0-based, so we really fetch the first element's name
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
klass = nil
|
|
401
|
+
begin
|
|
402
|
+
klass = Helpers.constantize "#{self}::#{Response.constants.grep(klassname).first}"
|
|
403
|
+
raise if klass.nil?
|
|
404
|
+
rescue
|
|
405
|
+
raise ProtocolExcepion.new("unknown server's response : #{raw}")
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
klass.new raw
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
end # module Response
|
|
412
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module FakeVioletSrv
|
|
5
|
+
require 'webrick'
|
|
6
|
+
include WEBrick
|
|
7
|
+
|
|
8
|
+
# used to check serial
|
|
9
|
+
SERIAL_MATCHER = /^[0-9A-F]+$/i
|
|
10
|
+
# used to check token
|
|
11
|
+
TOKEN_MATCHER = /^[0-9]+$/
|
|
12
|
+
|
|
13
|
+
# errors messages list
|
|
14
|
+
ERRORS = {
|
|
15
|
+
:WrongSerialOrToken => '<message>NOGOODTOKENORSERIAL</message><comment>Your token or serial number are not correct !</comment>'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# action list
|
|
19
|
+
ACTIONS = [
|
|
20
|
+
'', # array index begin to 0, but our action API begin to 1
|
|
21
|
+
'<message>LINKPREVIEW</message><comment>XXXX</comment>',
|
|
22
|
+
'<listfriend nb="1"/><friend name="toto"/>',
|
|
23
|
+
'<listreceivedmsg nb="1"/><msg from="toto" title="my message" date="today 11:59" url="broad/001/948.mp3"/>',
|
|
24
|
+
'<timezone>(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London</timezone>',
|
|
25
|
+
'<signature>XXXXX</signature>',
|
|
26
|
+
'<blacklist nb="1"/><pseudo name="toto"/>',
|
|
27
|
+
'<rabbitSleep>YES</rabbitSleep>',
|
|
28
|
+
'<rabbitVersion>V1</rabbitVersion>',
|
|
29
|
+
'<voiceListTTS nb="2"/><voice lang="fr" command="claire22k"/><voice lang="de" command="helga22k"/>',
|
|
30
|
+
'<rabbitName>nabmaster</rabbitName>',
|
|
31
|
+
'<langListUser nb="4"/><myLang lang="fr"/><myLang lang="us"/><myLang lang="uk"/><myLang lang="de"/>' ,
|
|
32
|
+
'<message>LINKPREVIEW</message><comment>XXXX</comment>',
|
|
33
|
+
'<message>COMMANDSEND</message><comment>You rabbit will change status</comment>',
|
|
34
|
+
'<message>COMMANDSEND</message><comment>You rabbit will change status</comment>'
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
class VioletApiServelet < HTTPServlet::AbstractServlet
|
|
38
|
+
def do_GET(req, res)
|
|
39
|
+
res['Content-Type'] = 'text/plain'
|
|
40
|
+
|
|
41
|
+
# getting options.
|
|
42
|
+
opts = parse_opts(req)
|
|
43
|
+
|
|
44
|
+
if opts[:sn] !~ SERIAL_MATCHER or opts[:token] !~ TOKEN_MATCHER
|
|
45
|
+
rsp = ERRORS[:WrongSerialOrToken]
|
|
46
|
+
elsif opts[:action]
|
|
47
|
+
rsp = ACTIONS[opts[:action].to_i]
|
|
48
|
+
elsif opts[:ears] == 'ok'
|
|
49
|
+
rsp = '<message>POSITIONEAR</message><leftposition>8</leftposition><rightposition>10</rightposition>'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
res.body = <<-EOF
|
|
53
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
54
|
+
<rsp>
|
|
55
|
+
#{rsp}
|
|
56
|
+
</rsp>
|
|
57
|
+
EOF
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def debug msg
|
|
63
|
+
puts "\033[31;01mDEBUG:\033[00m #{msg}" if $DEBUG
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def parse_opts(req)
|
|
67
|
+
req.unparsed_uri.split(/&|\?/).inject(Hash.new) { |h,opt| if opt =~ /(.+)=(.+)/ then h[$1.to_sym] = $2 end; h }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def FakeVioletSrv.start(port=3000, logfile=false)
|
|
74
|
+
if logfile
|
|
75
|
+
log = File.open(logfile, 'w')
|
|
76
|
+
$stderr = log
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
s = HTTPServer.new(
|
|
80
|
+
:Port => port,
|
|
81
|
+
:charset => 'UTF-8'
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
s.mount('/api.jsp', VioletApiServelet)
|
|
85
|
+
s.mount('/api_stream.jsp', VioletApiServelet)
|
|
86
|
+
|
|
87
|
+
trap('INT') { s.shutdown }
|
|
88
|
+
s.start
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
FakeVioletSrv.start if $0 == __FILE__
|
|
94
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def from_this_file_path *args
|
|
5
|
+
File.join( File.dirname(__FILE__), *args )
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require from_this_file_path('..', 'lib', 'violet', 'helpers.rb')
|
|
10
|
+
|
|
11
|
+
require 'rexml/document'
|
|
12
|
+
require 'test/unit'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class HelpersTest < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
def test_attributes_to_hash
|
|
19
|
+
xml = REXML::Document.new '<?xml version="1.0" encoding="UTF-8"?><rsp><listreceivedmsg nb="1"/><msg from="toto" title="my message" date="today 11:59" url="broad/001/948.mp3"/></rsp>'
|
|
20
|
+
xml.root.elements.each('msg') do |e|
|
|
21
|
+
assert_equal({:from => 'toto', :title => 'my message', :date => 'today 11:59', :url => 'broad/001/948.mp3'}, e.attributes.to_hash)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
CONSTANT_TEST = 42
|
|
27
|
+
def test_constantize
|
|
28
|
+
assert_equal RUBY_VERSION, Helpers.constantize('RUBY_VERSION')
|
|
29
|
+
assert_equal CONSTANT_TEST, Helpers.constantize("#{self.class}::CONSTANT_TEST")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def from_this_file_path *args
|
|
5
|
+
File.join( File.dirname(__FILE__), *args )
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require from_this_file_path('..', 'lib', 'violet', 'request.rb')
|
|
10
|
+
require from_this_file_path('..', 'lib', 'violet', 'response.rb')
|
|
11
|
+
|
|
12
|
+
require 'test/unit'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RequestTest < Test::Unit::TestCase
|
|
17
|
+
def test_dummy_test
|
|
18
|
+
# still todo :)
|
|
19
|
+
end
|
|
20
|
+
end
|