libastag 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/BUGS +10 -0
  2. data/CHANGES +8 -1
  3. data/MIT-LICENSE +2 -1
  4. data/README +7 -3
  5. data/Rakefile +3 -2
  6. data/TODO +4 -7
  7. data/doc/classes/Helpers.html +16 -20
  8. data/doc/classes/Helpers/REXML.html +4 -4
  9. data/doc/classes/Helpers/REXML/Attributes.html +10 -10
  10. data/doc/classes/Libastag.html +5 -5
  11. data/doc/classes/Libastag/Rabbit.html +56 -56
  12. data/doc/classes/Libastag/RabitEar.html +4 -4
  13. data/doc/classes/Libastag/RabitLed.html +4 -4
  14. data/doc/classes/Request.html +33 -37
  15. data/doc/classes/Request/Action.html +34 -34
  16. data/doc/classes/Request/AudioStream.html +313 -0
  17. data/doc/classes/Request/Base.html +13 -10
  18. data/doc/classes/Request/Base/Event.html +58 -23
  19. data/doc/classes/Request/Base/EventCollection.html +35 -32
  20. data/doc/classes/Request/Choregraphy.html +500 -0
  21. data/doc/classes/Request/Choregraphy/BadChorDesc.html +135 -0
  22. data/doc/classes/Request/Choregraphy/Ears.html +130 -0
  23. data/doc/classes/Request/Choregraphy/Ears/Directions.html +141 -0
  24. data/doc/classes/Request/Choregraphy/Ears/Positions.html +146 -0
  25. data/doc/classes/Request/Choregraphy/Leds.html +130 -0
  26. data/doc/classes/Request/Choregraphy/Leds/Colors.html +171 -0
  27. data/doc/classes/Request/Choregraphy/Leds/Positions.html +161 -0
  28. data/doc/classes/Request/GET_EARS_POSITION.html +17 -14
  29. data/doc/classes/Request/IdMessage.html +234 -0
  30. data/doc/classes/Request/Query.html +80 -55
  31. data/doc/classes/Request/SetEarsPosition.html +58 -36
  32. data/doc/classes/Request/TtsMessage.html +74 -50
  33. data/doc/classes/Response.html +55 -124
  34. data/doc/classes/Response/AbuseSending.html +34 -34
  35. data/doc/classes/Response/Base.html +34 -34
  36. data/doc/classes/Response/Base/BadServerRsp.html +34 -34
  37. data/doc/classes/Response/Base/GoodServerRsp.html +34 -34
  38. data/doc/classes/Response/Base/ServerRsp.html +53 -53
  39. data/doc/classes/Response/Blacklist.html +34 -34
  40. data/doc/classes/Response/ChorNotSend.html +34 -34
  41. data/doc/classes/Response/ChorSend.html +34 -34
  42. data/doc/classes/Response/CommandSend.html +34 -34
  43. data/doc/classes/Response/EarPositionNotSend.html +34 -34
  44. data/doc/classes/Response/EarPositionSend.html +34 -34
  45. data/doc/classes/Response/EmptyServerRsp.html +34 -34
  46. data/doc/classes/Response/LangListUser.html +34 -34
  47. data/doc/classes/Response/LinkPreview.html +34 -34
  48. data/doc/classes/Response/ListFriend.html +34 -34
  49. data/doc/classes/Response/ListReceivedMsg.html +34 -34
  50. data/doc/classes/Response/MessageNotSend.html +34 -34
  51. data/doc/classes/Response/MessageSend.html +34 -34
  52. data/doc/classes/Response/NabCastNotSend.html +34 -34
  53. data/doc/classes/Response/NabCastSend.html +34 -34
  54. data/doc/classes/Response/NoCorrectParameters.html +34 -34
  55. data/doc/classes/Response/NoGoodTokenOrSerial.html +34 -34
  56. data/doc/classes/Response/NotV2Rabbit.html +34 -34
  57. data/doc/classes/Response/PositionEar.html +34 -34
  58. data/doc/classes/Response/ProtocolExcepion.html +35 -35
  59. data/doc/classes/Response/RabbitName.html +34 -34
  60. data/doc/classes/Response/RabbitSleep.html +34 -34
  61. data/doc/classes/Response/RabbitVersion.html +34 -34
  62. data/doc/classes/Response/Signature.html +34 -34
  63. data/doc/classes/Response/Timezone.html +34 -34
  64. data/doc/classes/Response/TtsNotSend.html +34 -34
  65. data/doc/classes/Response/TtsSend.html +34 -34
  66. data/doc/classes/Response/VoiceListTts.html +34 -34
  67. data/doc/classes/Response/WebRadioNotSend.html +34 -34
  68. data/doc/classes/Response/WebRadioSend.html +34 -34
  69. data/doc/created.rid +1 -1
  70. data/doc/dot/f_0.png +0 -0
  71. data/doc/dot/f_5.dot +13 -445
  72. data/doc/dot/f_5.png +0 -0
  73. data/doc/dot/f_6.dot +445 -11
  74. data/doc/dot/f_6.png +0 -0
  75. data/doc/dot/f_7.dot +30 -5
  76. data/doc/dot/f_7.png +0 -0
  77. data/doc/dot/f_8.dot +39 -0
  78. data/doc/dot/f_8.png +0 -0
  79. data/doc/files/{lib/violet/violetapi_rb.html → BUGS.html} +17 -9
  80. data/doc/files/CHANGES.html +15 -2
  81. data/doc/files/MIT-LICENSE.html +2 -2
  82. data/doc/files/README.html +13 -3
  83. data/doc/files/TODO.html +5 -8
  84. data/doc/files/lib/libastag_rb.html +12 -10
  85. data/doc/files/lib/violet/helpers_rb.html +5 -5
  86. data/doc/files/lib/violet/request_rb.html +16 -12
  87. data/doc/files/lib/violet/response_rb.html +36 -35
  88. data/doc/fr_class_index.html +10 -1
  89. data/doc/fr_file_index.html +1 -1
  90. data/doc/fr_method_index.html +25 -12
  91. data/examples/morse.rb +72 -0
  92. data/lib/libastag.rb +6 -2
  93. data/lib/violet/helpers.rb +4 -2
  94. data/lib/violet/request.rb +501 -47
  95. data/lib/violet/response.rb +5 -2
  96. data/test/fake_violet_srv.rb +1 -1
  97. data/test/test_helpers.rb +3 -5
  98. data/test/{test_send.rb → test_query_and_actions.rb} +27 -10
  99. data/test/test_request_base.rb +76 -0
  100. data/test/test_request_chor.rb +162 -0
  101. data/test/test_request_stuff.rb +171 -0
  102. data/test/test_response.rb +3 -4
  103. metadata +45 -20
  104. data/doc/classes/VioletAPI.html +0 -118
  105. data/doc/dot/f_4.dot +0 -57
  106. data/doc/dot/f_4.png +0 -0
  107. data/lib/violet/violetapi.rb +0 -14
  108. data/test/test_request.rb +0 -20
@@ -29,10 +29,20 @@
29
29
  <a href="classes/Libastag/RabitLed.html">Libastag::RabitLed</a><br />
30
30
  <a href="classes/Request.html">Request</a><br />
31
31
  <a href="classes/Request/Action.html">Request::Action</a><br />
32
+ <a href="classes/Request/AudioStream.html">Request::AudioStream</a><br />
32
33
  <a href="classes/Request/Base.html">Request::Base</a><br />
33
34
  <a href="classes/Request/Base/Event.html">Request::Base::Event</a><br />
34
35
  <a href="classes/Request/Base/EventCollection.html">Request::Base::EventCollection</a><br />
36
+ <a href="classes/Request/Choregraphy.html">Request::Choregraphy</a><br />
37
+ <a href="classes/Request/Choregraphy/BadChorDesc.html">Request::Choregraphy::BadChorDesc</a><br />
38
+ <a href="classes/Request/Choregraphy/Ears.html">Request::Choregraphy::Ears</a><br />
39
+ <a href="classes/Request/Choregraphy/Ears/Directions.html">Request::Choregraphy::Ears::Directions</a><br />
40
+ <a href="classes/Request/Choregraphy/Ears/Positions.html">Request::Choregraphy::Ears::Positions</a><br />
41
+ <a href="classes/Request/Choregraphy/Leds.html">Request::Choregraphy::Leds</a><br />
42
+ <a href="classes/Request/Choregraphy/Leds/Colors.html">Request::Choregraphy::Leds::Colors</a><br />
43
+ <a href="classes/Request/Choregraphy/Leds/Positions.html">Request::Choregraphy::Leds::Positions</a><br />
35
44
  <a href="classes/Request/GET_EARS_POSITION.html">Request::GET_EARS_POSITION</a><br />
45
+ <a href="classes/Request/IdMessage.html">Request::IdMessage</a><br />
36
46
  <a href="classes/Request/Query.html">Request::Query</a><br />
37
47
  <a href="classes/Request/SetEarsPosition.html">Request::SetEarsPosition</a><br />
38
48
  <a href="classes/Request/TtsMessage.html">Request::TtsMessage</a><br />
@@ -72,7 +82,6 @@
72
82
  <a href="classes/Response/VoiceListTts.html">Response::VoiceListTts</a><br />
73
83
  <a href="classes/Response/WebRadioNotSend.html">Response::WebRadioNotSend</a><br />
74
84
  <a href="classes/Response/WebRadioSend.html">Response::WebRadioSend</a><br />
75
- <a href="classes/VioletAPI.html">VioletAPI</a><br />
76
85
  </div>
77
86
  </div>
78
87
  </body>
@@ -20,6 +20,7 @@
20
20
  <div id="index">
21
21
  <h1 class="section-bar">Files</h1>
22
22
  <div id="index-entries">
23
+ <a href="files/BUGS.html">BUGS</a><br />
23
24
  <a href="files/CHANGES.html">CHANGES</a><br />
24
25
  <a href="files/MIT-LICENSE.html">MIT-LICENSE</a><br />
25
26
  <a href="files/README.html">README</a><br />
@@ -28,7 +29,6 @@
28
29
  <a href="files/lib/violet/helpers_rb.html">lib/violet/helpers.rb</a><br />
29
30
  <a href="files/lib/violet/request_rb.html">lib/violet/request.rb</a><br />
30
31
  <a href="files/lib/violet/response_rb.html">lib/violet/response.rb</a><br />
31
- <a href="files/lib/violet/violetapi_rb.html">lib/violet/violetapi.rb</a><br />
32
32
  </div>
33
33
  </div>
34
34
  </body>
@@ -20,34 +20,47 @@
20
20
  <div id="index">
21
21
  <h1 class="section-bar">Methods</h1>
22
22
  <div id="index-entries">
23
+ <a href="classes/Request/AudioStream.html#M000027">+ (Request::AudioStream)</a><br />
23
24
  <a href="classes/Request/Base/Event.html#M000020">+ (Request::Base::Event)</a><br />
25
+ <a href="classes/Request/AudioStream.html#M000028">== (Request::AudioStream)</a><br />
26
+ <a href="classes/Request/Choregraphy.html#M000032">== (Request::Choregraphy)</a><br />
24
27
  <a href="classes/Libastag/Rabbit.html#M000010">asleep? (Libastag::Rabbit)</a><br />
25
28
  <a href="classes/Libastag/Rabbit.html#M000012">awake? (Libastag::Rabbit)</a><br />
26
29
  <a href="classes/Response/Base/ServerRsp.html#M000006">bad? (Response::Base::ServerRsp)</a><br />
30
+ <a href="classes/Request/Choregraphy.html#M000031">bubble (Request::Choregraphy)</a><br />
27
31
  <a href="classes/Helpers.html#M000001">constantize (Helpers)</a><br />
28
32
  <a href="classes/Request/Base/EventCollection.html#M000017">each (Request::Base::EventCollection)</a><br />
29
33
  <a href="classes/Response/Base/ServerRsp.html#M000007">get_all (Response::Base::ServerRsp)</a><br />
30
34
  <a href="classes/Response/Base/ServerRsp.html#M000005">good? (Response::Base::ServerRsp)</a><br />
35
+ <a href="classes/Request/Choregraphy.html#M000034">move (Request::Choregraphy)</a><br />
31
36
  <a href="classes/Libastag/Rabbit.html#M000009">name (Libastag::Rabbit)</a><br />
37
+ <a href="classes/Request/AudioStream.html#M000025">new (Request::AudioStream)</a><br />
38
+ <a href="classes/Request/Base/EventCollection.html#M000016">new (Request::Base::EventCollection)</a><br />
39
+ <a href="classes/Request/TtsMessage.html#M000038">new (Request::TtsMessage)</a><br />
40
+ <a href="classes/Request/Query.html#M000035">new (Request::Query)</a><br />
41
+ <a href="classes/Request/Base/Event.html#M000019">new (Request::Base::Event)</a><br />
32
42
  <a href="classes/Response/Base/ServerRsp.html#M000004">new (Response::Base::ServerRsp)</a><br />
33
- <a href="classes/Request/Query.html#M000024">new (Request::Query)</a><br />
34
43
  <a href="classes/Libastag/Rabbit.html#M000008">new (Libastag::Rabbit)</a><br />
35
- <a href="classes/Request/Action.html#M000022">new (Request::Action)</a><br />
36
- <a href="classes/Request/SetEarsPosition.html#M000029">new (Request::SetEarsPosition)</a><br />
37
- <a href="classes/Request/Base/Event.html#M000019">new (Request::Base::Event)</a><br />
38
- <a href="classes/Request/TtsMessage.html#M000027">new (Request::TtsMessage)</a><br />
39
- <a href="classes/Request/Base/EventCollection.html#M000016">new (Request::Base::EventCollection)</a><br />
44
+ <a href="classes/Request/SetEarsPosition.html#M000042">new (Request::SetEarsPosition)</a><br />
45
+ <a href="classes/Request/Action.html#M000023">new (Request::Action)</a><br />
46
+ <a href="classes/Request/IdMessage.html#M000040">new (Request::IdMessage)</a><br />
47
+ <a href="classes/Request/Choregraphy.html#M000029">new (Request::Choregraphy)</a><br />
40
48
  <a href="classes/Response.html#M000003">parse (Response)</a><br />
41
- <a href="classes/Request/Query.html#M000026">send! (Request::Query)</a><br />
49
+ <a href="classes/Request/Query.html#M000037">send! (Request::Query)</a><br />
50
+ <a href="classes/Request/Choregraphy.html#M000033">set (Request::Choregraphy)</a><br />
42
51
  <a href="classes/Libastag/Rabbit.html#M000011">sleep! (Libastag::Rabbit)</a><br />
52
+ <a href="classes/Request/Base/Event.html#M000022">streamed? (Request::Base::Event)</a><br />
43
53
  <a href="classes/Helpers/REXML/Attributes.html#M000002">to_hash (Helpers::REXML::Attributes)</a><br />
54
+ <a href="classes/Request/Query.html#M000036">to_url (Request::Query)</a><br />
55
+ <a href="classes/Request/Action.html#M000024">to_url (Request::Action)</a><br />
56
+ <a href="classes/Request/Base/Event.html#M000021">to_url (Request::Base::Event)</a><br />
44
57
  <a href="classes/Request/Base/EventCollection.html#M000018">to_url (Request::Base::EventCollection)</a><br />
45
- <a href="classes/Request/Action.html#M000023">to_url (Request::Action)</a><br />
58
+ <a href="classes/Request/AudioStream.html#M000026">to_url (Request::AudioStream)</a><br />
59
+ <a href="classes/Request/IdMessage.html#M000041">to_url (Request::IdMessage)</a><br />
60
+ <a href="classes/Request/SetEarsPosition.html#M000043">to_url (Request::SetEarsPosition)</a><br />
61
+ <a href="classes/Request/TtsMessage.html#M000039">to_url (Request::TtsMessage)</a><br />
62
+ <a href="classes/Request/Choregraphy.html#M000030">to_url (Request::Choregraphy)</a><br />
46
63
  <a href="classes/Request/GET_EARS_POSITION.html#M000015">to_url (Request::GET_EARS_POSITION)</a><br />
47
- <a href="classes/Request/Query.html#M000025">to_url (Request::Query)</a><br />
48
- <a href="classes/Request/Base/Event.html#M000021">to_url (Request::Base::Event)</a><br />
49
- <a href="classes/Request/TtsMessage.html#M000028">to_url (Request::TtsMessage)</a><br />
50
- <a href="classes/Request/SetEarsPosition.html#M000030">to_url (Request::SetEarsPosition)</a><br />
51
64
  <a href="classes/Libastag/Rabbit.html#M000014">version (Libastag::Rabbit)</a><br />
52
65
  <a href="classes/Libastag/Rabbit.html#M000013">wakeup! (Libastag::Rabbit)</a><br />
53
66
  </div>
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join( File.dirname(__FILE__), '..', 'lib', 'violet', 'request.rb' )
4
+
5
+
6
+ class String
7
+
8
+ MORSE_TABLE = {'a'=> %|.-|,'b'=> %|-...|,'c'=> %|-.-.|,'d'=> %|-..|,'e'=> %|.|,'f'=> %|..-.|,'g'=> %|--.|,'h'=> %|....|,'i'=> %|..|,'j'=> %|.---|,'k'=> %|-.-|,'l'=> %|.-..|,'m'=> %|--|,'n'=> %|-.|,'o'=> %|---|,'p'=> %|.--.|,'q'=> %|--.-|,'r'=> %|.-.|,'s'=> %|...|,'t'=> %|-|,'u'=> %|..-|,'v'=> %|...-|,'w'=> %|.--|,'x'=> %|-..-|,'y'=> %|-.--|,'z'=> %|--..|,'0'=> %|-----|,'1'=> %|.----|,'2'=> %|..---|,'3'=> %|...--|,'4'=> %|....-|,'5'=> %|.....|,'6'=> %|-....|,'7'=> %|--...|,'8'=> %|---..|,'9'=> %|----.| }
9
+
10
+ # "translate" a String into Morse code
11
+ def to_morse
12
+ self.downcase.scan(/./).collect do |c|
13
+ MORSE_TABLE[c]
14
+ end.join
15
+ end
16
+ end
17
+
18
+
19
+ # time in sec of a dot .
20
+ DOT_TIME = 0.1
21
+ # time in sec of a dash - (usually 3*DOT_TIME)
22
+ DASH_TIME = 3 * DOT_TIME
23
+ # time in sec of space between morses . or -
24
+ SPACE_TIME = DOT_TIME
25
+
26
+ # asking user
27
+ def ask question
28
+ print question
29
+ gets.chomp
30
+ end
31
+
32
+
33
+ def debug
34
+ yield if $DEBUG
35
+ end
36
+
37
+ # get user's name and convert it in morse code
38
+ morse = ask("what's your name ? ").to_morse
39
+ # get naba's infos
40
+
41
+ infos = ask('token: '), ask('serial: ')
42
+
43
+ c = Request::Choregraphy.new do
44
+ # initialize the timer
45
+ timer = 0
46
+
47
+ # each dot or dash
48
+ morse.scan(/./).each do |m|
49
+ # choose the good duration time
50
+ time_to_display = if m == '.' then DOT_TIME else DASH_TIME end
51
+ # choose colors at random :)
52
+ random_colors = [rand(255), rand(255), rand(255)]
53
+
54
+ at time timer
55
+ set top led to random_colors
56
+
57
+ at time (timer + time_to_display)
58
+ set top led off
59
+
60
+ timer = timer + time_to_display + SPACE_TIME
61
+ end
62
+ end
63
+
64
+ q = Request::Query.new :token => infos.first,
65
+ :serial => infos.last,
66
+ :event => c
67
+
68
+ debug { puts q.inspect }
69
+ rsp = q.send!
70
+ debug { puts rsp }
71
+
72
+ puts (rsp.good? ? 'OK ! sended !' : 'Woaw. arg.')
@@ -1,10 +1,14 @@
1
1
 
2
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) or $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+
2
5
 
3
6
  # Handy class/methods to control a Nabastag.
4
7
  module Libastag
5
- VERSION = '0.0.1'
8
+ VERSION = '0.0.2'
6
9
 
7
- require File.join( File.dirname(__FILE__), 'violet', 'violetapi.rb' )
10
+ require 'violet/response.rb'
11
+ require 'violet/request.rb'
8
12
 
9
13
  # this class store all attribute of a Nabaztag.
10
14
  # it receive events and retrieve information
@@ -3,8 +3,9 @@
3
3
  some handy class/methods and modifications.
4
4
  =end
5
5
 
6
+ require 'rexml/document'
7
+
6
8
  module Helpers
7
- require 'rexml/document'
8
9
 
9
10
 
10
11
  # REXML::Attributes#to_hash seems to be broken.
@@ -23,7 +24,8 @@ module Helpers
23
24
 
24
25
 
25
26
  # ==Credits
26
- # taken from active_support/inflector.rb,
27
+ # Copyright (c) 2005 David Heinemeier Hansson
28
+ # taken from active_support/inflector.rb (MIT licence)
27
29
  # see http://rubyforge.org/projects/activesupport
28
30
  #
29
31
  #
@@ -6,8 +6,13 @@ but other Event derivated class are used to create objects.
6
6
 
7
7
  =end
8
8
 
9
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) or $:.include?(File.expand_path(File.dirname(__FILE__)))
10
+
11
+ require 'response.rb'
12
+ require 'helpers.rb'
13
+
14
+
9
15
  module Request
10
- require File.join( File.dirname(__FILE__), 'response.rb' )
11
16
 
12
17
  # the VioletAPI url where we send request.
13
18
  API_URL = 'http://api.nabaztag.com/vl/FR/api.jsp'
@@ -27,8 +32,10 @@ module Request
27
32
  raise NotImplementedError
28
33
  end
29
34
 
30
- # it's possible to send multiples events on a single request.
35
+ # it's possible to send multiples events on a single request. this method return a new EventCollection object,
36
+ # that cotains +self+ and +other+.
31
37
  def + other
38
+ raise ArgumentError.new("#{other.inspect} is a Streamed Event") if other.streamed?
32
39
  EventCollection.new self, other
33
40
  end
34
41
 
@@ -36,6 +43,11 @@ module Request
36
43
  def to_url
37
44
  raise NotImplementedError
38
45
  end
46
+
47
+ # return +true+ if self is a Stream Event (that use APISTREAM_URL instead of API_URL), +false+ otherwise.
48
+ def streamed?
49
+ self.class.to_s =~ /Stream$/
50
+ end
39
51
  end
40
52
 
41
53
 
@@ -66,7 +78,7 @@ module Request
66
78
 
67
79
  # override Event#to_url.
68
80
  def to_url
69
- @childrens.collect { |e| e.to_url }.join('&')
81
+ @childrens.collect { |e| e.to_url }.flatten
70
82
  end
71
83
  end
72
84
 
@@ -74,16 +86,20 @@ module Request
74
86
 
75
87
 
76
88
 
77
- # this class is used to "translate" our Events into URLs.
78
- # Examples:
79
- # TODO
89
+ # this class is used to "translate" our Events into URLs. a query contains an event to send and the serial/token
90
+ # of the target Rabbit. That way, you can send the same event to many nabaztag easily.
91
+ #
80
92
  # see http://api.nabaztag.com/docs/home.html
93
+ #
94
+ # ==Examples
95
+ # q = Query.new :token => "my_token", :serial => "my_serial", :event => GET_RABBIT_NAME # => #<Request::Query:0x2aaaaaee10b8 @event=#<Request::Action:0x2b74bb47f828 @id=10>, @token="my_token", @serial="my_serial">
81
96
  class Query
82
97
  require 'open-uri'
83
98
 
84
99
  # create a new Query object with the give parameters. +serial+ and +token+ parameters should be checked at
85
100
  # a higher level. +event+ parameter is usually an Event object, but you can give any Object that respond to
86
- # to_url.
101
+ # to_url, it should return a string that contains some GET parameters like "foo=bar&oni=2", or an array of
102
+ # GET options like [ "foo=bar", "oni=2" ].
87
103
  def initialize h
88
104
  raise ArgumentError.new('event parameter has no "to_url" method or is empty') unless h[:event] and h[:event].respond_to?(:to_url)
89
105
  raise ArgumentError.new('need a :serial') unless h[:serial]
@@ -92,14 +108,27 @@ module Request
92
108
  @event, @serial, @token = h[:event], h[:serial], h[:token]
93
109
  end
94
110
 
95
- # return the complet url: API_URL with the +serial+, +token+ and options.
111
+ # return the complet url
96
112
  def to_url
97
- API_URL+'?' << [ "token=#{@token}", "sn=#{@serial}", @event.to_url ].join('&')
113
+ opts = @event.to_url
114
+ if opts.respond_to?(:join) then opts = opts.join('&') end
115
+
116
+ base_url = if @event.streamed? then APISTREAM_URL else API_URL end
117
+
118
+ "#{base_url}?" << [ "sn=#{@serial}", "token=#{@token}", opts ].join('&')
98
119
  end
99
120
 
100
- # TODO
121
+ # send the query to the server. it return a ServerRsp object from the corresponding class if no args is given.
122
+ #
123
+ # ==Arguments
124
+ # [:xml] the raw xml server's response
125
+ #
126
+ # ==Examples
127
+ # q = Query.new :token => "my_token", :serial => "my_serial", :event => GET_RABBIT_NAME # => #<Request::Query:0x2aaaaaee10b8 @event=#<Request::Action:0x2b74bb47f828 @id=10>, @token="my_token", @serial="my_serial">
128
+ # q.send! # => #<Response::RabbitName:0x2b74b8c38798 @xml=<UNDEFINED> ... </>>
129
+ # q.send!(:xml) # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rsp><rabbitName>Makoto</rabbitName></rsp>\n"
130
+ #
101
131
  def send! response_type=nil
102
- # TODO: rescue ?
103
132
  rsp = open(self.to_url) { |rsp| rsp.read }
104
133
  if response_type == :xml then rsp else Response.parse(rsp) end
105
134
  end
@@ -107,10 +136,19 @@ module Request
107
136
 
108
137
 
109
138
 
139
+ # SetEarsPosition events change your rabbit's ears positions.
140
+ # you can set left ear position, or right ear position, or both.
141
+ #
142
+ # =Examples
143
+ # SetEarsPosition.new :posleft => 12 # => #<Request::SetEarsPosition:0x2ad0b2c79680 @h={:posleft=>12}>
144
+ # SetEarsPosition.new :posright => 1 # => #<Request::SetEarsPosition:0x2ad0b2c70260 @h={:posright=>1}>
145
+ # SetEarsPosition.new :posright => 5, :posleft => 5 # => #<Request::SetEarsPosition:0x2ad0b2c5e330 @h={:posleft=>5, :posright=>5}>
110
146
  class SetEarsPosition < Base::Event
111
147
  MIN_POS = 0
112
148
  MAX_POS = 16
113
149
 
150
+ # take an hash in parameter, with <tt>:posright</tt> and/or <tt>:posleft</tt> keys. values should be between
151
+ # SetEarsPosition::MIN_POS and SetEarsPosition::MAX_POS.
114
152
  def initialize h
115
153
  @h = h.dup
116
154
  raise ArgumentError.new('at least :posright or :posleft must be set') unless @h[:posleft] or @h[:posright]
@@ -118,59 +156,475 @@ module Request
118
156
  raise ArgumentError.new(":posleft must be between #{MIN_POS} and #{MAX_POS}") if @h[:posleft ] and not @h[:posleft ].to_i.between?(MIN_POS,MAX_POS)
119
157
  end
120
158
 
121
-
122
159
  def to_url
123
160
  url = Array.new
124
- url << "posleft=#{h[:posleft].to_i}" if h[:posleft]
125
- url << "posright=#{h[:posright].to_i}" if h[:posright]
126
- url.join('&')
161
+ url << "posleft=#{@h[:posleft].to_i}" if @h[:posleft]
162
+ url << "posright=#{@h[:posright].to_i}" if @h[:posright]
163
+ url.sort
127
164
  end
128
165
  end
129
166
 
130
167
 
168
+ # TtsMessage events are used to Text-To-Speach messages.
169
+ #
170
+ # =Examples
171
+ # TtsMessage.new :tts => "oups!" # => #<Request::TtsMessage:0x2ab1ba3cd8e0 @h={:tts=>"oups!"}>
172
+ # TtsMessage.new :tts => "allez hop !", :speed => 200, :voice => "caroline22k" # => #<Request::TtsMessage:0x2ab1ba3b8e40 @h={:tts=>"allez%20hop%20!", :speed=>200, :voice=>"caroline22k"}>
173
+ # TtsMessage.new :tts => "GNU is Not Unix", :speed => 200, :pitch => 400 # => #<Request::TtsMessage:0x2ab1ba3a9580 @h={:tts=>"GNU%20is%20Not%20Unix", :speed=>200, :pitch=>400}>
131
174
  class TtsMessage < Base::Event
132
- require 'cgi'
133
175
  MIN_SPEED = 1
134
- MAX_SPEED = 32000
176
+ MAX_SPEED = 32_000
135
177
 
136
178
  MIN_PITCH = 1
137
- MAX_PITCH = 32000
138
-
179
+ MAX_PITCH = 32_000
139
180
 
181
+ # take an hash in parameter, with at least <tt>:tts</tt> key. the <tt>:tts</tt> key must be a string encoded
182
+ # in UTF-8. Optionals parameters are <tt>:speed</tt> and <tt>:pitch</tt>, they must be between MIN_SPEED and
183
+ # MAX_SPEED (MIN_PITCH and MAX_PITCH respectively). Default values for speed/pitch is 100.
140
184
  def initialize h
141
- raise ArgumentError.new('no text given') unless h[:tts]
185
+ raise ArgumentError.new('no :tts given') unless h[:tts]
142
186
  @h = h.dup
143
187
 
144
- [:speed,:pitch].each do |p|
145
- min = Helpers.constantize("#{self.class}::MIN_#{p.to_s.upcase}")
146
- max = Helpers.constantize("#{self.class}::MAX_#{p.to_s.upcase}")
188
+ [:speed,:pitch].each do |k|
189
+ min = Helpers.constantize("#{self.class}::MIN_#{k.to_s.upcase}")
190
+ max = Helpers.constantize("#{self.class}::MAX_#{k.to_s.upcase}")
147
191
 
148
- unless @h[p].to_i.between?(min,max)
149
- raise ArgumentError.new("#{p} values must be between #{min} and #{max}")
192
+ unless @h[k].to_i.between?(min,max)
193
+ raise ArgumentError.new("#{k} values must be between #{min} and #{max}")
150
194
  else
151
- @h[p] = @h[p].to_i
152
- end if @h[p]
195
+ @h[k] = @h[k].to_i
196
+ end if @h[k]
153
197
  end
154
198
 
155
- @h[:tts] = CGI.escape @h[:tts]
199
+ # to have a well formatted url
200
+ @h[:tts] = URI.escape @h[:tts]
201
+ @h[:nabcasttitle] = URI.escape @h[:nabcasttitle] if @h[:nabcasttitle]
156
202
  end
157
203
 
158
204
  def to_url
159
- for p in [:tts,:voice,:speed,:pitch] do
160
- (url ||= Array.new) << "#{p}=#{@h[p]}" if @h[p]
205
+ for key,val in @h
206
+ (url ||= Array.new) << "#{key}=#{val}" if val
161
207
  end
208
+ url.sort
209
+ end
210
+ end
211
+
212
+
213
+ # IdMessage events are used with a message id from Library or a personal MP3 file.
214
+ # Library can be seen here : http://my.nabaztag.com/vl/action/myMessagesBiblio.do
215
+ #
216
+ # =Example (Batman)
217
+ # IdMessage.new :idmessage => 10282 # => #<Request::IdMessage:0x2b28ec730128 @h={:idmessage=>10282}>
218
+ class IdMessage < Base::Event
219
+ MIN_IDMESSAGE = 1
162
220
 
163
- url.join('&')
221
+ # take an Hash in parameter, with at least <tt>:idmessage</tt> key. the <tt>:idmessage</tt> must respond_to
222
+ # to_i and have a to_i representation greater or equal than IdMessage::MIN_IDMESSAGE.
223
+ def initialize h
224
+ @h = h.dup
225
+
226
+ raise ArgumentError.new('no :idmessage given') unless @h[:idmessage]
227
+ raise ArgumentError.new(":idmessage must be greater than #{MIN_IDMESSAGE}") unless @h[:idmessage].to_i >= MIN_IDMESSAGE
228
+
229
+ @h[:idmessage] = @h[:idmessage].to_i
230
+
231
+ @h[:nabcasttitle] = URI.escape @h[:nabcasttitle] if @h[:nabcasttitle]
232
+ @h[:nabcast] = @h[:nabcast].to_i if @h[:nabcast]
233
+ end
234
+
235
+ def to_url
236
+ url = Array.new
237
+ @h.each_pair do |key,val|
238
+ url << "#{key}=#{val}" if val
239
+ end
240
+ url
164
241
  end
165
242
  end
166
243
 
167
244
 
245
+ # AudioStream events are used with MP3 hyperlinks to make your rabbit play podcasts or webradio.
246
+ # Your rabbit has to be a tag/tag to use AudioStream events (it should be checked at higher level, this class won't do that for you :))
247
+ #
248
+ # see http://api.nabaztag.com/docs/home.html#sendurl
249
+ #
250
+ # =Examples
251
+ # you can give a String argument, or an Array of String if you want to play several urls, or a Hash with a
252
+ # <tt>:url_list</tt> key.
253
+ # AudioStream.new "http://my_streamed_url.com" # => #<Request::AudioStream:0x2b44fafd52e0 @args=["http://my_streamed_url.com"]>
254
+ # AudioStream.new :url_list => "http://my_streamed_url.com" # => #<Request::AudioStream:0x2b52a24acf70 @args=["http://my_streamed_url.com"]>
255
+ #
256
+ # AudioStream.new "http://my_streamed_url.com", "http://plop.test" # => #<Request::AudioStream:0x2b44fafc9058 @args=["http://my_streamed_url.com", "http://plop.test"]>
257
+ # AudioStream.new ["http://my_streamed_url.com", "http://plop.test"] # => #<Request::AudioStream:0x2b44fafbdc30 @args=["http://my_streamed_url.com", "http://plop.test"]>
258
+ # AudioStream.new :url_list => ["http://my_streamed_url.com", "http://plop.test"] # => #<Request::AudioStream:0x2b52a24a28e0 @args=["http://my_streamed_url.com", "http://plop.test"]>
259
+ class AudioStream < Base::Event
260
+
261
+ # take an Array of String or many Strings arguments, each String is a URL to play. Another way to create
262
+ # AudioStream is to give a Hash in argument, with the <tt>:url_list</tt> keys that contains an Array of Strings
263
+ # or a String. see examples.
264
+ def initialize *args
265
+ raise ArgumentError.new('no args given') if args.empty? or args.first.empty?
266
+ if args.first.is_a?(Hash)
267
+ args = [ args.first[:url_list] ]
268
+ raise ArgumentError.new('empty :url_list key in Hash argument') if args.first.nil? or args.first.empty?
269
+ end
270
+
271
+ @url_list = args.flatten
272
+ end
273
+
274
+ def to_url
275
+ "urlList=#{@url_list.join('|')}"
276
+ end
277
+
278
+ # AudioStream object can be added with other AudioStream objects. When you add first to second, the new
279
+ # AudioStream will play all the urls in first, then all the urls in second.
280
+ #
281
+ # ==Examples
282
+ # one = AudioStream.new "http://www.one.com" # => #<Request::AudioStream:0x2b2d075e0b28 @url_list=["http://www.one.com"]>
283
+ # two = AudioStream.new "http://www.two.com" # => #<Request::AudioStream:0x2b2d075db510 @url_list=["http://www.two.com"]>
284
+ # onetwo = one + two # => #<Request::AudioStream:0x2b2d075d7a78 @url_list=["http://www.one.com", "http://www.two.com"]>
285
+ # twoone = two + one # => #<Request::AudioStream:0x2b2d075cff80 @url_list=["http://www.two.com", "http://www.one.com"]>
286
+ def + other
287
+ raise ArgumentError.new("#{other.inspect} is not a Streamed Event") unless other.streamed?
288
+ AudioStream.new(self.url_list, other.url_list)
289
+ end
290
+
291
+ # compare two AudioStream. AudioStream are equals if and only if they have the same url list.
292
+ def == other
293
+ raise ArgumentError.new("#{other.inspect} is not a Streamed Event") unless other.streamed?
294
+ self.url_list == other.url_list
295
+ end
296
+
297
+ protected
298
+ attr_reader :url_list
299
+ end
300
+
301
+
302
+ # =Choregraphy
303
+ # Choregraphy in the Violet API looks like binary CSV code. It isn't really "user-friendly".
304
+ # We use a DSL (Domain Specific Language) to describe Choregraphy more easily, and then translate it in with
305
+ # this class. This allows us to create a more powerful language, making easy (for examples) to set all leds in
306
+ # one sentence, instead of five 90% redundant lines :
307
+ #
308
+ # 'set all to green' will we translated into 'chor=10,0,led,0,0,255,0,0,led,1,0,255,0,0,led,2,0,255,0,0,led,3,0,255,0,0,led,4,0,255,0'
309
+ #
310
+ # Moreover, if you think that a Choregraphy is a Set of Events (that are either an ear command either a led
311
+ # command), then we can use logic operations such as ==, \+, -, | and & on Choregraphy (code taken from test file
312
+ # test_request_chor.rb):
313
+ #
314
+ # one = Choregraphy.new { move left ear forward of degrees 42 }
315
+ # two = Choregraphy.new { move right ear forward of degrees 42 }
316
+ # onetwo = Choregraphy.new { move both ears forward of degrees 42 }
317
+ #
318
+ # assert_equal one | two, one + two
319
+ # assert_equal one & two, Choregraphy.new
320
+ # assert_equal one - two, one
321
+ # assert_equal two - one, two
322
+ # assert_equal onetwo, one + two
323
+ # assert_equal onetwo & two, two
324
+ # assert_equal onetwo & one, one
325
+ # assert_equal onetwo - two, one
326
+ # assert_equal onetwo - one, two
327
+ # assert_equal onetwo | two, onetwo
328
+ # assert_equal onetwo | one, onetwo
329
+ #
330
+ # =Choregraphy Creation
331
+ # see new
332
+ #
333
+ # =Choregraphy DSL description
334
+ # Here is the syntax description: [] are alternation with | or range with - and <> are optionals.
335
+ #
336
+ # at time 1.2 <do>
337
+ # move [right|left|both] <ear|ears> [backward|forward] <of> degrees [0-180]
338
+ # set [bottom|left|middle|right|top|all] <led|leds> to [off|red|green|blue|yellow|magenta|cyan|white|rgb([0-255],[0-255],[0-255])]
339
+ # <end>
340
+ #
341
+ # =Examples
342
+ # for examples, please see the test file (namely test_request_chor.rb), because there are a lot of possible
343
+ # chor description and I don't want to duplicate too much code :)
344
+ class Choregraphy < Base::Event
345
+
346
+
347
+ # Take some Choregraphy DSL code and translate it into a Choregraphy description of Violet API.
348
+ #
349
+ # ==Arguments
350
+ # (optionals) an Hash in argument with keys:
351
+ # [name] the chortitle
352
+ # [code] an array of String/Proc or a String/Proc that describe the Choregraphy in our DSL.
353
+ # (optionals) a block of code that describe the Choregraphy.
354
+ #
355
+ # ==Raise
356
+ # raise a Choregraphy::BadChorDesc if not happy.
357
+ #
358
+ # ==Examples (all results are equals)
359
+ # Request::Choregraphy.new { set all off; move right ear forward of degrees 180 } # => #<Request::Choregraphy:0x2b07a05f8ca0 @chor=["0,led,0,0,0,0", "0,led,1,0,0,0", "0,led,2,0,0,0", "0,led,3,0,0,0", "0,led,4,0,0,0", "0,motor,0,180,0,0"], @code=[#<Proc:0x00002b07a05f8d40@(irb):3>], @time=0>
360
+ # Request::Choregraphy.new :code => 'set all off; move right ear forward of degrees 180' # => #<Request::Choregraphy:0x2b07a05e84b8 @chor=["0,led,0,0,0,0", "0,led,1,0,0,0", "0,led,2,0,0,0", "0,led,3,0,0,0", "0,led,4,0,0,0", "0,motor,0,180,0,0"], @code=["set all off; move right ear forward of degrees 180"], @time=0>
361
+ # Request::Choregraphy.new :code => [ 'set all off', 'move right ear forward of degrees 180' ] # => #<Request::Choregraphy:0x2b07a05dae30 @chor=["0,led,0,0,0,0", "0,led,1,0,0,0", "0,led,2,0,0,0", "0,led,3,0,0,0", "0,led,4,0,0,0", "0,motor,0,180,0,0"], @code=["set all off", "move right ear forward of degrees 180"], @time=0>
362
+ #
363
+ def initialize(h=Hash.new, &block)
364
+ @name = h[:name] if h[:name]
365
+ @code = if block_given? then block else h[:code] end
366
+ __choreval__
367
+ @chor.sort! unless @chor.nil?
368
+ end
369
+
370
+ def to_url
371
+ raise BadChorDesc.new('no choregraphy given') unless @chor
372
+
373
+ url = Array.new
374
+ url << "chor=10," + @chor.join(',') unless @chor.nil?
375
+ url << "chortitle=#{@name}" unless @name.nil?
376
+ url
377
+ end
378
+
379
+ # define dummy methods for DSL
380
+ def self.bubble(*methods)
381
+ methods.each do |m|
382
+ define_method(m) { |args| args }
383
+ private(m.to_sym)
384
+ end
385
+ end
386
+
387
+ # raised when the Choregraphy DSL is not ok
388
+ class BadChorDesc < StandardError; end
389
+
390
+ # + has the same behaviour that |
391
+ %w[+ - & |].each do |op|
392
+ define_method(op) do |other|
393
+ new_chor = if self.chor.nil? then other.chor.method(op).call(self.chor).uniq.sort else self.chor.method(op).call(other.chor).uniq.sort end
394
+ ret = Choregraphy.new
395
+ ret.instance_eval { @chor = new_chor } # hacky !
396
+ ret
397
+ end
398
+ end
399
+
400
+ def == other
401
+ self.chor == other.chor
402
+ end
403
+
404
+ def set command
405
+ raise BadChorDesc.new('wrong Choregraphy description') unless command.is_a?(LedCommandStruct)
406
+ raise BadChorDesc.new('need an element') unless command.elements
407
+ command.elements.each do |e|
408
+ raise BadChorDesc.new('wrong element') unless e == :all or e.between?(Leds::Positions::BOTTOM,Leds::Positions::TOP)
409
+ end
410
+ raise BadChorDesc.new('need a time') unless command.time
411
+ raise BadChorDesc.new('time must be >= than zero') unless command.time.to_i >= 0
412
+ raise BadChorDesc.new('need a color') unless command.color
413
+ raise BadChorDesc.new('wrong size for rgb color array') unless command.color.size == 3
414
+ command.color.collect! do |c|
415
+ raise BadChorDesc.new('color code must be betwen 0 and 255') unless c.to_i.between?(0,255)
416
+ c.to_i
417
+ end
418
+
419
+ template = '%s,led,%s,%s'
420
+ command.color = command.color.join(',')
421
+
422
+ # remove trailling element if all is set
423
+ command.elements.uniq!
424
+ command.elements = [:all] if command.elements.include?(:all)
425
+
426
+ command.elements.each do |e|
427
+ if e == :all
428
+ (Leds::Positions.constants - ['ALL']).each do |cste_name|
429
+ cste = Helpers.constantize "#{self.class}::Leds::Positions::#{cste_name}"
430
+ @chor << template % [ command.time.to_i, cste, command.color ]
431
+ end
432
+ else
433
+ @chor << template % [ command.time.to_i, e, command.color ]
434
+ end
435
+ end
436
+ end
437
+
438
+ def move command
439
+ raise BadChorDesc.new('wrong Choregraphy description') unless command.is_a?(EarCommandStruct)
440
+ raise BadChorDesc.new('need a time') unless command.time
441
+ raise BadChorDesc.new('time must be >= zero') unless command.time.to_i >= 0
442
+ raise BadChorDesc.new('need an angle') unless command.angle
443
+ raise BadChorDesc.new('angle must be between 0 and 180') unless (0..180).include?(command.angle)
444
+ raise BadChorDesc.new('need a direction') unless command.direction
445
+ raise BadChorDesc.new('wrong direction') unless command.direction.between?(Ears::Directions::FORWARD,Ears::Directions::BACKWARD)
446
+ raise BadChorDesc.new('need an element') unless command.element
447
+ raise BadChorDesc.new('wrong element') unless command.element == :both or command.element.between?(Ears::Positions::RIGHT,Ears::Positions::LEFT)
448
+
449
+ template = '%s,motor,%s,%s,0,%s'
450
+
451
+ if command.element == :both
452
+ # we don't know, maybe your rabbit has more than two ears :)
453
+ (Ears::Positions.constants - ['BOTH']).each do |cste_name|
454
+ cste = Helpers.constantize "#{self.class}::Ears::Positions::#{cste_name}"
455
+ @chor << template % [ command.time.to_i, cste, command.angle, command.direction ]
456
+ end
457
+ else
458
+ @chor << template % [ command.time.to_i, command.element, command.angle, command.direction ]
459
+ end
460
+ end
461
+
462
+
463
+ #
464
+ # used internally
465
+ #
466
+
467
+ # Command Structs for ears
468
+ EarCommandStruct = Struct.new :element, :direction, :angle, :time
469
+ # Command Structs for leds
470
+ LedCommandStruct = Struct.new :elements, :color, :time
471
+
472
+ # used by operators == + - & |
473
+ protected
474
+ attr_reader :chor
475
+
476
+ private
477
+
478
+ # String of block evaluator
479
+ def __choreval__
480
+ @chor, @time = Array.new, 0
481
+
482
+ @code = [@code] unless @code.respond_to?(:each)
483
+ @code.each do |code|
484
+ if code.is_a?(Proc)
485
+ instance_eval(&code)
486
+ else
487
+ instance_eval(code.to_s, __FILE__, __LINE__)
488
+ end
489
+ end
490
+ end
491
+
492
+ # set the time and call block if any
493
+ def at time_formated
494
+ @time = time_formated
495
+ yield if block_given?
496
+ end
497
+
498
+ # format the time
499
+ def time t
500
+ (10 * t.to_f).round
501
+ end
502
+
503
+ # right/left hook, because they must be defined for ears and for leds.
504
+ [:right, :left].each do |m|
505
+ define_method(m) do |arg|
506
+ target = if arg.is_a?(EarCommandStruct) then :ear else :led end
507
+ method("__#{m}_for_#{target}__").call(arg)
508
+ end
509
+ end
510
+
511
+
512
+ module Leds
513
+ module Colors
514
+ RED = [255, 0, 0]
515
+ GREEN = [0, 255, 0]
516
+ BLUE = [0, 0, 255]
517
+ CYAN = [0, 255, 255]
518
+ MAGENTA = [255, 0, 255]
519
+ YELLOW = [255, 255, 0]
520
+ WHITE = [255, 255, 255]
521
+ OFF = [ 0, 0, 0]
522
+ end
523
+ module Positions
524
+ BOTTOM = 0
525
+ LEFT = 1
526
+ MIDDLE = 2
527
+ RIGHT = 3
528
+ TOP = 4
529
+ ALL = :all
530
+ end
531
+ end
532
+
533
+ # leds dummy methods setup
534
+ bubble :led, :leds
535
+
536
+ # make possible to write
537
+ # my_color = [1,2,3]
538
+ # set all to my_color
539
+ # and also
540
+ # set all to 1,2,3
541
+ def to *args
542
+ case i = args.first
543
+ when Array then rgb(*i)
544
+ when LedCommandStruct then i
545
+ else rgb(*args)
546
+ end
547
+ end
548
+
549
+ # check values and convert to array
550
+ def rgb(*color)
551
+ command = LedCommandStruct.new
552
+ command.time, command.color = @time, color[0..2]
553
+ command
554
+ end
555
+
556
+ # generate colors methods
557
+ Leds::Colors.constants.each do |cste_name|
558
+ cste = Helpers.constantize "#{self}::Leds::Colors::#{cste_name}"
559
+ define_method(cste_name.downcase) { |args| rgb(*cste) }
560
+ end
561
+
562
+ # generate leds positions methods
563
+ Leds::Positions.constants.each do |cste_name|
564
+ cste = Helpers.constantize "#{self}::Leds::Positions::#{cste_name}"
565
+ # right and left are specials cases
566
+ cste_name = "__#{cste_name}_for_led__" if cste_name =~ /^(LEFT|RIGHT)$/
567
+
568
+ define_method(cste_name.downcase) do |command|
569
+ (command.elements ||= Array.new) << cste
570
+ command
571
+ end
572
+ end
573
+
574
+
575
+ module Ears
576
+ module Positions
577
+ RIGHT = 0
578
+ LEFT = 1
579
+ BOTH = :both
580
+ end
581
+ module Directions
582
+ FORWARD = 0
583
+ BACKWARD = 1
584
+ end
585
+ end
586
+
587
+ # ears dummy methods setup
588
+ bubble :of, :ear, :ears
589
+
590
+ def degrees angle
591
+ angle = angle.to_i
592
+ command = EarCommandStruct.new
593
+ command.angle, command.time = angle, @time
594
+ command
595
+ end
596
+
597
+ Ears::Directions.constants.each do |cste_name|
598
+ cste = Helpers.constantize "#{self}::Ears::Directions::#{cste_name}"
599
+
600
+ define_method(cste_name.downcase) do |command|
601
+ command.direction = cste
602
+ command
603
+ end
604
+ end
605
+
606
+ Ears::Positions.constants.each do |cste_name|
607
+ cste = Helpers.constantize "#{self}::Ears::Positions::#{cste_name}"
608
+ # right and left are specials cases
609
+ cste_name = "__#{cste_name}_for_ear__" if cste_name =~ /^(LEFT|RIGHT)$/
610
+
611
+ define_method(cste_name.downcase) do |command|
612
+ command.element = cste
613
+ command
614
+ end
615
+ end
616
+
617
+ end # class Choregraphy
618
+
619
+
620
+
168
621
  #
169
622
  # Actions list.
170
623
  #
171
624
  # see http://api.nabaztag.com/docs/home.html#getinfo
172
625
  #
173
626
 
627
+
174
628
  # actions are used to retrieve informations about the Nabaztag or the Nabaztag's owners.
175
629
  # see constants of Request module, all Action are Request constant that begin with GET or
176
630
  # SET. Request::GET_EARS_POSITION is not an Action in the violet API, but we implement it as it was.
@@ -182,7 +636,6 @@ module Request
182
636
  @id = id
183
637
  end
184
638
 
185
- # Action have only action= option.
186
639
  def to_url
187
640
  "action=#{@id}"
188
641
  end
@@ -190,84 +643,84 @@ module Request
190
643
 
191
644
 
192
645
  # Preview the TTS or music (with music id) without sending it
193
- # Examples:
646
+ # Examples
194
647
  # Query.new(:event => GET_LINKPREVIEW, :serial => my_serial, :token => my_token).send! # => #<Response::LinkPreview:0x2aaaab100f88 @xml=<UNDEFINED> ... </>>
195
648
  # see Response::LinkPreview
196
649
  GET_LINKPREVIEW = Action.new 1
197
650
 
198
651
 
199
652
  # Get a list of your friends
200
- # Examples:
653
+ # Examples
201
654
  # Query.new(:event => GET_FRIENDS_LIST, :serial => my_serial, :token => my_token).send! # => #<Response::ListFriend:0x2af08fd53568 @xml=<UNDEFINED> ... </>>
202
655
  # see Response::ListFriend
203
656
  GET_FRIENDS_LIST = Action.new 2
204
657
 
205
658
 
206
659
  # Get a count and the list of the messages in your inbox
207
- # Examples:
660
+ # Examples
208
661
  # Query.new(:event => GET_INBOX_LIST, :serial => my_serial, :token => my_token).send! # => #<Response::ListReceivedMsg:0x2aaaab0e0be8 @xml=<UNDEFINED> ... </>>
209
662
  # see Response::ListReceivedMsg
210
663
  GET_INBOX_LIST = Action.new 3
211
664
 
212
665
 
213
666
  # Get the timezone in which your Nabaztag is set
214
- # Examples:
667
+ # Examples
215
668
  # Query.new(:event => GET_TIMEZONE, :serial => my_serial, :token => my_token).send! # => #<Response::Timezone:0x2af091e58f60 @xml=<UNDEFINED> ... </>>
216
669
  # see Response::Timezone
217
670
  GET_TIMEZONE = Action.new 4
218
671
 
219
672
 
220
673
  # Get the signature defined for the Nabaztag
221
- # Examples:
674
+ # Examples
222
675
  # Query.new(:event => GET_SIGNATURE, :serial => my_serial, :token => my_token).send! # => #<Response::Signature:0x2aaaab0c8c28 @xml=<UNDEFINED> ... </>>
223
676
  # see Response::Signature
224
677
  GET_SIGNATURE = Action.new 5
225
678
 
226
679
 
227
680
  # Get a count and the list of people in your blacklist
228
- # Examples:
681
+ # Examples
229
682
  # Query.new(:event => GET_BLACKLISTED, :serial => my_serial, :token => my_token).send! # => #<Response::Blacklist:0x2aaaab0b0ad8 @xml=<UNDEFINED> ... </>>
230
683
  # see Response::Blacklist
231
684
  GET_BLACKLISTED = Action.new 6
232
685
 
233
686
 
234
687
  # Get to know if the Nabaztag is sleeping (YES) or not (NO)
235
- # Examples:
688
+ # Examples
236
689
  # Query.new(:event => GET_RABBIT_STATUS, :serial => my_serial, :token => my_token).send! # => #<Response::RabbitSleep:0x2aaaab092a88 @xml=<UNDEFINED> ... </>>
237
690
  # see Response::RabbitSleep
238
691
  GET_RABBIT_STATUS = Action.new 7
239
692
 
240
693
 
241
694
  # Get to know if the Nabaztag is a Nabaztag (V1) or a Nabaztag/tag (V2)
242
- # Examples:
695
+ # Examples
243
696
  # Query.new(:event => GET_RABBIT_VERSION, :serial => my_serial, :token => my_token).send! # => #<Response::RabbitVersion:0x2aaaab07c418 @xml=<UNDEFINED> ... </>>
244
697
  # see Response::RabbitVersion
245
698
  GET_RABBIT_VERSION = Action.new 8
246
699
 
247
700
 
248
701
  # Get a list of all supported languages/voices for TTS (text to speach) engine
249
- # Examples:
702
+ # Examples
250
703
  # Query.new(:event => GET_LANG_VOICE, :serial => my_serial, :token => my_token).send! # => #<Response::VoiceListTts:0x2aaaab064368 @xml=<UNDEFINED> ... </>>
251
704
  # see Response::VoiceListTts
252
705
  GET_LANG_VOICE = Action.new 9
253
706
 
254
707
 
255
708
  # Get the name of the Nabaztag
256
- # Examples:
709
+ # Examples
257
710
  # Query.new(:event => GET_RABBIT_NAME, :serial => my_serial, :token => my_token).send! # => #<Response::RabbitName:0x2aaaab0459b8 @xml=<UNDEFINED> ... </>>
258
711
  # see Response::RabbitName
259
712
  GET_RABBIT_NAME = Action.new 10
260
713
 
261
714
 
262
715
  # Get the languages selected for the Nabaztag
263
- # Examples:
716
+ # Examples
264
717
  # Query.new(:event => GET_SELECTED_LANG, :serial => my_serial, :token => my_token).send! # => #<Response::LangListUser:0x2aaaab02bfb8 @xml=<UNDEFINED> ... </>>
265
718
  # see Response::LangListUser
266
719
  GET_SELECTED_LANG = Action.new 11
267
720
 
268
721
 
269
722
  # Get a preview of a message. This works only with the urlPlay parameter and URLs like broad/001/076/801/262.mp3
270
- # Examples:
723
+ # Examples
271
724
  # Query.new(:event => GET_MESSAGE_PREVIEW, :serial => my_serial, :token => my_token).send! # => #<Response::LinkPreview:0x2aaaab011258 @xml=<UNDEFINED> ... </>>
272
725
  # see Response::LinkPreview
273
726
  GET_MESSAGE_PREVIEW = Action.new 12
@@ -275,7 +728,7 @@ module Request
275
728
 
276
729
  # Get the position of the ears to your Nabaztag. this request is not an action in the Violet API but we do as
277
730
  # if it was because it's make more sens (to me).
278
- # Examples:
731
+ # Examples
279
732
  # Query.new(:event => GET_EARS_POSITION, :serial => my_serial, :token => my_token).send! # => #<Response::PositionEar:0x2aaaaaff6908 @xml=<UNDEFINED> ... </>>
280
733
  # see Response::PositionEar
281
734
  GET_EARS_POSITION = Action.new nil
@@ -286,16 +739,17 @@ module Request
286
739
 
287
740
 
288
741
  # Send your Rabbit to sleep
289
- # Examples:
742
+ # Examples
290
743
  # Query.new(:event => SET_RABBIT_ASLEEP, :serial => my_serial, :token => my_token).send! # => #<Response::CommandSend:0x2aaaaafbf980 @xml=<UNDEFINED> ... </>>
291
744
  # see Response::CommandSend
292
745
  SET_RABBIT_ASLEEP = Action.new 13
293
746
 
294
747
 
295
748
  # Wake up your Rabbit
296
- # Examples:
749
+ # Examples
297
750
  # Query.new(:event => SET_RABBIT_AWAKE, :serial => my_serial, :token => my_token).send! # => #<Response::CommandSend:0x2aaaaafa60c0 @xml=<UNDEFINED> ... </>>
298
751
  # see Response::CommandSend
299
752
  SET_RABBIT_AWAKE = Action.new 14
300
753
 
301
754
  end # module Request
755
+