libastag 0.0.1 → 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.
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
+