punchblock 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # [develop](https://github.com/adhearsion/punchblock)
2
2
 
3
+ # [v1.5.0](https://github.com/adhearsion/punchblock/compare/v1.4.1...v1.5.0) - [2012-10-01](https://rubygems.org/gems/punchblock/versions/1.5.0)
4
+ * Feature: Input component now supports grammar URLs
5
+ * Bugfix: Hanging up Asterisk calls now correctly specifies normal clearing cause
6
+ * Doc: Fix a bunch of API documentation
7
+
3
8
  # [v1.4.1](https://github.com/adhearsion/punchblock/compare/v1.4.0...v1.4.1) - [2012-09-06](https://rubygems.org/gems/punchblock/versions/1.4.1)
4
9
  * Bugfix: Cleaning up DTMF handlers for input components with a dead call should not crash on FreeSWITCH
5
10
  * Bugfix: Reduced a race condition on FreeSWITCH when dispatching events from calls to dead components
data/README.markdown CHANGED
@@ -1,7 +1,7 @@
1
1
  # Punchblock
2
2
  Punchblock is a middleware library for telephony applications. Like Rack is to Rails and Sinatra, Punchblock provides a consistent API on top of several underlying third-party call control protocols.
3
3
 
4
- In the same spirit that inspired Rack, the Punchblock library is envisioned to be the single library for call control wiring. Frameworks and applications may take advantage of Punchblock's single API to write powerful code for managing calls. Punchblock is not and will not be an application framework; rather it only surfaces the various protocols and presents a consistent interface to its consumers.
4
+ In the same spirit that inspired Rack, the Punchblock library is envisioned to be the single library for call control wiring. Frameworks and applications may take advantage of Punchblock's single API to write powerful code for managing calls. Punchblock is not and will not be an application framework; rather it only surfaces the various protocols and presents a consistent interface to its consumers. NB: If you're looking to develop an application, you should take a look at the [Adhearsion](http://adhearsion.com) framework first. This library is much lower level.
5
5
 
6
6
  ## Installation
7
7
  gem install punchblock
@@ -14,6 +14,7 @@ The best available usage documentation available for Punchblock is by example, i
14
14
 
15
15
  * Rayo
16
16
  * Asterisk (AMI & AsyncAGI)
17
+ * FreeSWITCH (Inbound Event Socket)
17
18
 
18
19
  ## Links:
19
20
  * [Source](https://github.com/adhearsion/punchblock)
data/lib/punchblock.rb CHANGED
@@ -22,7 +22,6 @@ module Punchblock
22
22
  autoload :DisconnectedError
23
23
  autoload :HasHeaders
24
24
  autoload :Header
25
- autoload :MediaContainer
26
25
  autoload :MediaNode
27
26
  autoload :ProtocolError
28
27
  autoload :RayoNode
@@ -8,7 +8,7 @@ module Punchblock
8
8
  include HasHeaders
9
9
 
10
10
  ##
11
- # Create an Rayo accept command. This is equivalent to a SIP "180 Trying"
11
+ # Create a Rayo accept command. This is equivalent to a SIP "180 Trying"
12
12
  #
13
13
  # @param [Hash] options
14
14
  # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
@@ -8,7 +8,7 @@ module Punchblock
8
8
  include HasHeaders
9
9
 
10
10
  ##
11
- # Create an Rayo answer command. This is equivalent to a SIP "200 OK"
11
+ # Create a Rayo answer command. This is equivalent to a SIP "200 OK"
12
12
  #
13
13
  # @param [Hash] options
14
14
  # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
@@ -8,7 +8,7 @@ module Punchblock
8
8
  include HasHeaders
9
9
 
10
10
  ##
11
- # Create a dial message
11
+ # Create a dial command
12
12
  #
13
13
  # @param [Hash] options
14
14
  # @option options [String] :to destination to dial
@@ -8,7 +8,7 @@ module Punchblock
8
8
  include HasHeaders
9
9
 
10
10
  ##
11
- # Create an Rayo hangup message
11
+ # Create a Rayo hangup command
12
12
  #
13
13
  # @param [Hash] options
14
14
  # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
@@ -6,7 +6,7 @@ module Punchblock
6
6
  register :join, :core
7
7
 
8
8
  ##
9
- # Create a join message
9
+ # Create a join command
10
10
  #
11
11
  # @param [Hash] options
12
12
  # @option options [String, Optional] :call_id the call ID to join
@@ -8,7 +8,7 @@ module Punchblock
8
8
  include HasHeaders
9
9
 
10
10
  ##
11
- # Create an Rayo redirect message
11
+ # Create a Rayo redirect command
12
12
  #
13
13
  # @param [Hash] options
14
14
  # @option options [String] :to redirect target
@@ -10,7 +10,7 @@ module Punchblock
10
10
  VALID_REASONS = [:busy, :decline, :error].freeze
11
11
 
12
12
  ##
13
- # Create an Rayo reject message
13
+ # Create a Rayo reject command
14
14
  #
15
15
  # @param [Hash] options
16
16
  # @option options [Symbol] :reason for rejecting the call. Can be any one of VALID_REASONS. Defaults to :decline
@@ -6,7 +6,7 @@ module Punchblock
6
6
  register :unjoin, :core
7
7
 
8
8
  ##
9
- # Create an ujoin message
9
+ # Create an ujoin command
10
10
  #
11
11
  # @param [Hash] options
12
12
  # @option options [String, Optional] :call_id the call ID to unjoin
@@ -54,16 +54,16 @@ module Punchblock
54
54
  end
55
55
 
56
56
  ##
57
- # Create an Rayo stop message
57
+ # Create a Rayo stop message
58
58
  #
59
- # @return [Stop] an Rayo stop message
59
+ # @return [Stop] a Rayo stop message
60
60
  #
61
61
  def stop_action
62
62
  Stop.new :component_id => component_id, :target_call_id => target_call_id
63
63
  end
64
64
 
65
65
  ##
66
- # Sends an Rayo stop message for the current component
66
+ # Sends a Rayo stop message for the current component
67
67
  #
68
68
  def stop!(options = {})
69
69
  raise InvalidActionError, "Cannot stop a #{self.class.name.split("::").last} that is not executing" unless executing?
@@ -6,30 +6,29 @@ module Punchblock
6
6
  register :input, :input
7
7
 
8
8
  ##
9
- # Create an input message
9
+ # Create a input command
10
10
  #
11
- # @param [Hash] options for inputing/prompting a specific call
12
- # @option options [Choices, Hash] :choices to allow the user to input
13
- # @option options [Prompt, Hash, Optional] :prompt to play/read to the caller as the question
14
- # @option options [Symbol, Optional] :mode by which to accept input. Can be :speech, :dtmf or :any
15
- # @option options [Integer, Optional] :timeout to wait for user input
16
- # @option options [Boolean, Optional] :bargein wether or not to allow the caller to begin their response before the prompt finishes
17
- # @option options [String, Optional] :recognizer to use for speech recognition
18
- # @option options [String, Optional] :terminator by which to signal the end of input
19
- # @option options [Float, Optional] :min_confidence with which to consider a response acceptable
11
+ # @param [Hash] options
12
+ # @option options [Grammar, Hash] :grammar the grammar to activate
13
+ # @option options [Integer, optional] :max_silence the amount of time in milliseconds that an input command will wait until considered that a silence becomes a NO-MATCH
14
+ # @option options [Float, optional] :min_confidence with which to consider a response acceptable
15
+ # @option options [Symbol, optional] :mode by which to accept input. Can be :speech, :dtmf or :any
16
+ # @option options [String, optional] :recognizer to use for speech recognition
17
+ # @option options [String, optional] :terminator by which to signal the end of input
18
+ # @option options [Float, optional] :sensitivity Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
19
+ # @option options [Integer, optional] :initial_timeout Indicates the amount of time preceding input which may expire before a timeout is triggered.
20
+ # @option options [Integer, optional] :inter_digit_timeout Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
20
21
  #
21
22
  # @return [Command::Input] a formatted Rayo input command
22
23
  #
23
24
  # @example
24
- # input :prompt => {:text => 'Please enter your postal code.', :voice => 'simon'},
25
- # :choices => {:value => '[5 DIGITS]'},
26
- # :timeout => 30,
25
+ # input :grammar => {:value => '[5 DIGITS]', :content_type => 'application/grammar+voxeo'},
26
+ # :mode => :speech,
27
27
  # :recognizer => 'es-es'
28
28
  #
29
29
  # returns:
30
- # <input xmlns="urn:xmpp:tropo:input:1" timeout="30" recognizer="es-es">
31
- # <prompt voice='simon'>Please enter your postal code.</prompt>
32
- # <choices content-type="application/grammar+voxeo">[5 DIGITS]</choices>
30
+ # <input xmlns="urn:xmpp:rayo:input:1" mode="speech" recognizer="es-es">
31
+ # <grammar content-type="application/grammar+voxeo">[5 DIGITS]</choices>
33
32
  # </input>
34
33
  #
35
34
  def self.new(options = {})
@@ -38,20 +37,6 @@ module Punchblock
38
37
  end
39
38
  end
40
39
 
41
- ##
42
- # @return [Boolean] wether or not to allow the caller to begin their response before the prompt finishes
43
- #
44
- def max_digits
45
- read_attr :'max-digits', :to_i
46
- end
47
-
48
- ##
49
- # @param [Boolean] bargein wether or not to allow the caller to begin their response before the prompt finishes
50
- #
51
- def max_digits=(other)
52
- write_attr :'max-digits', other
53
- end
54
-
55
40
  ##
56
41
  # @return [Integer] the amount of time in milliseconds that an input command will wait until considered that a silence becomes a NO-MATCH
57
42
  #
@@ -123,91 +108,49 @@ module Punchblock
123
108
  end
124
109
 
125
110
  ##
126
- # @return [Integer] timeout to wait for user input
111
+ # @return [Float] Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
127
112
  #
128
113
  def sensitivity
129
114
  read_attr :sensitivity, :to_f
130
115
  end
131
116
 
132
117
  ##
133
- # @param [Integer] timeout to wait for user input
118
+ # @param [Float] other Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
134
119
  #
135
120
  def sensitivity=(other)
136
121
  write_attr :sensitivity, other
137
122
  end
138
123
 
139
124
  ##
140
- # @return [Integer] timeout to wait for user input
125
+ # @return [Integer] Indicates the amount of time preceding input which may expire before a timeout is triggered.
141
126
  #
142
127
  def initial_timeout
143
128
  read_attr :'initial-timeout', :to_i
144
129
  end
145
130
 
146
131
  ##
147
- # @param [Integer] timeout to wait for user input
132
+ # @param [Integer] timeout Indicates the amount of time preceding input which may expire before a timeout is triggered.
148
133
  #
149
134
  def initial_timeout=(other)
150
135
  write_attr :'initial-timeout', other
151
136
  end
152
137
 
153
138
  ##
154
- # @return [Integer] timeout to wait for user input
139
+ # @return [Integer] Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
155
140
  #
156
141
  def inter_digit_timeout
157
142
  read_attr :'inter-digit-timeout', :to_i
158
143
  end
159
144
 
160
145
  ##
161
- # @param [Integer] timeout to wait for user input
146
+ # @param [Integer] timeout Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
162
147
  #
163
148
  def inter_digit_timeout=(other)
164
149
  write_attr :'inter-digit-timeout', other
165
150
  end
166
151
 
167
152
  ##
168
- # @return [Integer] timeout to wait for user input
169
- #
170
- def term_timeout
171
- read_attr :'term-timeout', :to_i
172
- end
173
-
174
- ##
175
- # @param [Integer] timeout to wait for user input
176
- #
177
- def term_timeout=(other)
178
- write_attr :'term-timeout', other
179
- end
180
-
181
- ##
182
- # @return [Integer] timeout to wait for user input
183
- #
184
- def complete_timeout
185
- read_attr :'complete-timeout', :to_i
186
- end
187
-
188
- ##
189
- # @param [Integer] timeout to wait for user input
190
- #
191
- def complete_timeout=(other)
192
- write_attr :'complete-timeout', other
193
- end
194
-
195
- ##
196
- # @return [Integer] timeout to wait for user input
197
- #
198
- def incomplete_timeout
199
- read_attr :'incomplete-timeout', :to_i
200
- end
201
-
202
- ##
203
- # @param [Integer] timeout to wait for user input
204
- #
205
- def incomplete_timeout=(other)
206
- write_attr :'incomplete-timeout', other
207
- end
208
-
209
- ##
210
- # @return [Choices] the choices available
153
+ # @return [Grammar] the grammar to activate
211
154
  #
212
155
  def grammar
213
156
  node = find_first 'ns:grammar', :ns => self.class.registered_ns
@@ -215,9 +158,10 @@ module Punchblock
215
158
  end
216
159
 
217
160
  ##
218
- # @param [Hash] choices
219
- # @option choices [String] :content_type
220
- # @option choices [String] :value the choices available
161
+ # @param [Hash] other
162
+ # @option other [String] :content_type the document content type
163
+ # @option other [String] :value the grammar doucment
164
+ # @option other [String] :url the url from which to fetch the grammar
221
165
  #
222
166
  def grammar=(other)
223
167
  return unless other
@@ -227,14 +171,15 @@ module Punchblock
227
171
  end
228
172
 
229
173
  def inspect_attributes # :nodoc:
230
- [:mode, :terminator, :max_digits, :recognizer, :initial_timeout, :inter_digit_timeout, :term_timeout, :complete_timeout, :incomplete_timeout, :sensitivity, :min_confidence, :grammar] + super
174
+ [:mode, :terminator, :recognizer, :initial_timeout, :inter_digit_timeout, :sensitivity, :min_confidence, :grammar] + super
231
175
  end
232
176
 
233
177
  class Grammar < RayoNode
234
178
  ##
235
179
  # @param [Hash] options
236
- # @option options [String] :content_type
237
- # @option options [String] :value the choices available
180
+ # @option options [String] :content_type the document content type
181
+ # @option options [String] :value the grammar document
182
+ # @option options [String] :url the url from which to fetch the grammar
238
183
  #
239
184
  def self.new(options = {})
240
185
  super(:grammar).tap do |new_node|
@@ -244,12 +189,13 @@ module Punchblock
244
189
  when Hash
245
190
  new_node.content_type = options[:content_type]
246
191
  new_node.value = options[:value]
192
+ new_node.url = options[:url]
247
193
  end
248
194
  end
249
195
  end
250
196
 
251
197
  ##
252
- # @return [String] the choice content type
198
+ # @return [String] the document content type
253
199
  #
254
200
  def content_type
255
201
  read_attr 'content-type'
@@ -263,8 +209,9 @@ module Punchblock
263
209
  end
264
210
 
265
211
  ##
266
- # @return [String] the choices available
212
+ # @return [String, RubySpeech::GRXML::Grammar] the grammar document
267
213
  def value
214
+ return nil unless content.present?
268
215
  if grxml?
269
216
  RubySpeech::GRXML.import content
270
217
  else
@@ -273,7 +220,7 @@ module Punchblock
273
220
  end
274
221
 
275
222
  ##
276
- # @param [String] value the choices available
223
+ # @param [String, RubySpeech::GRXML::Grammar] value the grammar document
277
224
  def value=(value)
278
225
  return unless value
279
226
  if grxml? && !value.is_a?(RubySpeech::GRXML::Element)
@@ -284,15 +231,22 @@ module Punchblock
284
231
  end
285
232
  end
286
233
 
287
- # Compare two Choices objects by content type, and value
288
- # @param [Header] o the Choices object to compare against
289
- # @return [true, false]
290
- def eql?(o, *fields)
291
- super o, *(fields + [:content_type, :value])
234
+ ##
235
+ # @return [String] the URL from which the fetch the grammar
236
+ #
237
+ def url
238
+ read_attr 'url'
239
+ end
240
+
241
+ ##
242
+ # @param [String] other the URL from which the fetch the grammar
243
+ #
244
+ def url=(other)
245
+ write_attr 'url', other
292
246
  end
293
247
 
294
248
  def inspect_attributes # :nodoc:
295
- [:content_type, :value] + super
249
+ [:content_type, :value, :url] + super
296
250
  end
297
251
 
298
252
  private
@@ -5,8 +5,6 @@ module Punchblock
5
5
  class Output < ComponentNode
6
6
  register :output, :output
7
7
 
8
- include MediaContainer
9
-
10
8
  ##
11
9
  # Creates an Rayo Output command
12
10
  #
@@ -14,6 +12,12 @@ module Punchblock
14
12
  # @option options [String, Optional] :text to speak back
15
13
  # @option options [String, Optional] :voice with which to render TTS
16
14
  # @option options [String, Optional] :ssml document to render TTS
15
+ # @option options [Symbol] :interrupt_on input type on which to interrupt output. May be :speech, :dtmf or :any
16
+ # @option options [Integer] :start_offset Indicates some offset through which the output should be skipped before rendering begins.
17
+ # @option options [true, false] :start_paused Indicates wether or not the component should be started in a paused state to be resumed at a later time.
18
+ # @option options [Integer] :repeat_interval Indicates the duration of silence that should space repeats of the rendered document.
19
+ # @option options [Integer] :repeat_times Indicates the number of times the output should be played.
20
+ # @option options [Integer] :max_time Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
17
21
  #
18
22
  # @return [Command::Output] an Rayo "output" command
19
23
  #
@@ -21,13 +25,12 @@ module Punchblock
21
25
  # output :text => 'Hello brown cow.'
22
26
  #
23
27
  # returns:
24
- # <output xmlns="urn:xmpp:tropo:output:1">Hello brown cow.</output>
28
+ # <output xmlns="urn:xmpp:rayo:output:1">Hello brown cow.</output>
25
29
  #
26
30
  def self.new(options = {})
27
31
  super().tap do |new_node|
28
32
  case options
29
33
  when Hash
30
- new_node.voice = options.delete(:voice) if options[:voice]
31
34
  new_node.ssml = options.delete(:ssml) if options[:ssml]
32
35
  new_node << options.delete(:text) if options[:text]
33
36
  options.each_pair { |k,v| new_node.send :"#{k}=", v }
@@ -40,89 +43,122 @@ module Punchblock
40
43
  ##
41
44
  # @return [String] the TTS voice to use
42
45
  #
46
+ def voice
47
+ read_attr :voice
48
+ end
49
+
50
+ ##
51
+ # @param [String] voice to use when rendering TTS
52
+ #
53
+ def voice=(voice)
54
+ write_attr :voice, voice
55
+ end
56
+
57
+ ##
58
+ # @return [String] the SSML document to render TTS
59
+ #
60
+ def ssml
61
+ node = children.first
62
+ RubySpeech::SSML.import node if node
63
+ end
64
+
65
+ ##
66
+ # @param [String] ssml the SSML document to render TTS
67
+ #
68
+ def ssml=(ssml)
69
+ return unless ssml
70
+ unless ssml.is_a?(RubySpeech::SSML::Element)
71
+ ssml = RubySpeech::SSML.import ssml
72
+ end
73
+ self << ssml
74
+ end
75
+
76
+ ##
77
+ # @return [Symbol] input type on which to interrupt output
78
+ #
43
79
  def interrupt_on
44
80
  read_attr :'interrupt-on', :to_sym
45
81
  end
46
82
 
47
83
  ##
48
- # @param [String] voice to use when rendering TTS
84
+ # @param [Symbol] other input type on which to interrupt output. May be :speech, :dtmf or :any
49
85
  #
50
86
  def interrupt_on=(other)
51
87
  write_attr :'interrupt-on', other
52
88
  end
53
89
 
54
90
  ##
55
- # @return [String] the TTS voice to use
91
+ # @return [Integer] Indicates some offset through which the output should be skipped before rendering begins.
56
92
  #
57
93
  def start_offset
58
94
  read_attr :'start-offset', :to_i
59
95
  end
60
96
 
61
97
  ##
62
- # @param [String] voice to use when rendering TTS
98
+ # @param [Integer] other Indicates some offset through which the output should be skipped before rendering begins.
63
99
  #
64
100
  def start_offset=(other)
65
101
  write_attr :'start-offset', other
66
102
  end
67
103
 
68
104
  ##
69
- # @return [String] the TTS voice to use
105
+ # @return [true, false] Indicates wether or not the component should be started in a paused state to be resumed at a later time.
70
106
  #
71
107
  def start_paused
72
108
  read_attr(:'start-paused') == 'true'
73
109
  end
74
110
 
75
111
  ##
76
- # @param [String] voice to use when rendering TTS
112
+ # @param [true, false] other Indicates wether or not the component should be started in a paused state to be resumed at a later time.
77
113
  #
78
114
  def start_paused=(other)
79
115
  write_attr :'start-paused', other.to_s
80
116
  end
81
117
 
82
118
  ##
83
- # @return [String] the TTS voice to use
119
+ # @return [Integer] Indicates the duration of silence that should space repeats of the rendered document.
84
120
  #
85
121
  def repeat_interval
86
122
  read_attr :'repeat-interval', :to_i
87
123
  end
88
124
 
89
125
  ##
90
- # @param [String] voice to use when rendering TTS
126
+ # @param [Integer] other Indicates the duration of silence that should space repeats of the rendered document.
91
127
  #
92
128
  def repeat_interval=(other)
93
129
  write_attr :'repeat-interval', other
94
130
  end
95
131
 
96
132
  ##
97
- # @return [String] the TTS voice to use
133
+ # @return [Integer] Indicates the number of times the output should be played.
98
134
  #
99
135
  def repeat_times
100
136
  read_attr :'repeat-times', :to_i
101
137
  end
102
138
 
103
139
  ##
104
- # @param [String] voice to use when rendering TTS
140
+ # @param [Integer] other Indicates the number of times the output should be played.
105
141
  #
106
142
  def repeat_times=(other)
107
143
  write_attr :'repeat-times', other
108
144
  end
109
145
 
110
146
  ##
111
- # @return [String] the TTS voice to use
147
+ # @return [Integer] Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
112
148
  #
113
149
  def max_time
114
150
  read_attr :'max-time', :to_i
115
151
  end
116
152
 
117
153
  ##
118
- # @param [String] voice to use when rendering TTS
154
+ # @param [Integer] other Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
119
155
  #
120
156
  def max_time=(other)
121
157
  write_attr :'max-time', other
122
158
  end
123
159
 
124
160
  def inspect_attributes
125
- super + [:interrupt_on, :start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time]
161
+ super + [:voice, :ssml, :interrupt_on, :start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time]
126
162
  end
127
163
 
128
164
  state_machine :state do
@@ -143,7 +179,7 @@ module Punchblock
143
179
  # output_obj.pause_action.to_xml
144
180
  #
145
181
  # returns:
146
- # <pause xmlns="urn:xmpp:tropo:output:1"/>
182
+ # <pause xmlns="urn:xmpp:rayo:output:1"/>
147
183
  def pause_action
148
184
  Pause.new :component_id => component_id, :target_call_id => target_call_id
149
185
  end
@@ -168,7 +204,7 @@ module Punchblock
168
204
  # output_obj.resume_action.to_xml
169
205
  #
170
206
  # returns:
171
- # <resume xmlns="urn:xmpp:tropo:output:1"/>
207
+ # <resume xmlns="urn:xmpp:rayo:output:1"/>
172
208
  def resume_action
173
209
  Resume.new :component_id => component_id, :target_call_id => target_call_id
174
210
  end
@@ -9,11 +9,14 @@ module Punchblock
9
9
  # Creates an Rayo Record command
10
10
  #
11
11
  # @param [Hash] options
12
- # @option options [String, Optional] :text to speak back
13
- # @option options [String, Optional] :voice with which to render TTS
14
- # @option options [String, Optional] :ssml document to render TTS
12
+ # @option options [String] :format to use for recording
13
+ # @option options [Integer] :initial_timeout Controls how long the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
14
+ # @option options [Integer] :final_timeout Controls the length of a period of silence after callers have spoken to conclude they finished.
15
+ # @option options [Integer] :max_duration Indicates the maximum duration for the recording.
16
+ # @option options [true, false] :start_beep Indicates whether subsequent record will be preceded with a beep.
17
+ # @option options [true, false] :start_paused Whether subsequent record will start in PAUSE mode.
15
18
  #
16
- # @return [Command::Record] an Rayo "record" command
19
+ # @return [Command::Record] a Rayo "record" command
17
20
  #
18
21
  # @example
19
22
  # record :text => 'Hello brown cow.'
@@ -28,14 +31,14 @@ module Punchblock
28
31
  end
29
32
 
30
33
  ##
31
- # @return [String] the codec to use for recording
34
+ # @return [Integer] Controls the length of a period of silence after callers have spoken to conclude they finished.
32
35
  #
33
36
  def final_timeout
34
37
  read_attr :'final-timeout', :to_i
35
38
  end
36
39
 
37
40
  ##
38
- # @param [String] codec to use for recording
41
+ # @param [Integer] timeout Controls the length of a period of silence after callers have spoken to conclude they finished.
39
42
  #
40
43
  def final_timeout=(timeout)
41
44
  write_attr :'final-timeout', timeout
@@ -56,77 +59,63 @@ module Punchblock
56
59
  end
57
60
 
58
61
  ##
59
- # @return [String] the codec to use for recording
62
+ # @return [Integer] Controls how long the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
60
63
  #
61
64
  def initial_timeout
62
65
  read_attr :'initial-timeout', :to_i
63
66
  end
64
67
 
65
68
  ##
66
- # @param [String] codec to use for recording
69
+ # @param [Integer] timeout Controls how long the recognizer should wait after the end of the prompt for the caller to speak before sending a Recorder event.
67
70
  #
68
71
  def initial_timeout=(timeout)
69
72
  write_attr :'initial-timeout', timeout
70
73
  end
71
74
 
72
75
  ##
73
- # @return [String] the codec to use for recording
76
+ # @return [Integer] Indicates the maximum duration for the recording.
74
77
  #
75
78
  def max_duration
76
79
  read_attr :'max-duration', :to_i
77
80
  end
78
81
 
79
82
  ##
80
- # @param [String] codec to use for recording
83
+ # @param [Integer] other Indicates the maximum duration for the recording.
81
84
  #
82
85
  def max_duration=(other)
83
86
  write_attr :'max-duration', other
84
87
  end
85
88
 
86
89
  ##
87
- # @return [String] the codec to use for recording
90
+ # @return [true, false] Indicates whether subsequent record will be preceded with a beep.
88
91
  #
89
92
  def start_beep
90
93
  read_attr(:'start-beep') == 'true'
91
94
  end
92
95
 
93
96
  ##
94
- # @param [String] codec to use for recording
97
+ # @param [true, false] sb Indicates whether subsequent record will be preceded with a beep.
95
98
  #
96
99
  def start_beep=(sb)
97
100
  write_attr :'start-beep', sb
98
101
  end
99
102
 
100
103
  ##
101
- # @return [String] the codec to use for recording
102
- #
103
- def stop_beep
104
- read_attr(:'stop-beep') == 'true'
105
- end
106
-
107
- ##
108
- # @param [String] codec to use for recording
109
- #
110
- def stop_beep=(sb)
111
- write_attr :'stop-beep', sb
112
- end
113
-
114
- ##
115
- # @return [String] the codec to use for recording
104
+ # @return [true, false] Whether subsequent record will start in PAUSE mode.
116
105
  #
117
106
  def start_paused
118
107
  read_attr(:'start-paused') == 'true'
119
108
  end
120
109
 
121
110
  ##
122
- # @param [String] codec to use for recording
111
+ # @param [true, false] other Whether subsequent record will start in PAUSE mode.
123
112
  #
124
113
  def start_paused=(other)
125
114
  write_attr :'start-paused', other
126
115
  end
127
116
 
128
117
  def inspect_attributes # :nodoc:
129
- [:final_timeout, :format, :initial_timeout, :max_duration, :start_beep, :start_paused, :stop_beep] + super
118
+ [:final_timeout, :format, :initial_timeout, :max_duration, :start_beep, :start_paused] + super
130
119
  end
131
120
 
132
121
  state_machine :state do
@@ -191,15 +180,15 @@ module Punchblock
191
180
  ##
192
181
  # Directly returns the recording for the component
193
182
  # @return [Punchblock::Component::Record::Recording] The recording object
194
- #
183
+ #
195
184
  def recording
196
185
  complete_event.recording
197
186
  end
198
-
187
+
199
188
  ##
200
189
  # Directly returns the recording URI for the component
201
190
  # @return [String] The recording URI
202
- #
191
+ #
203
192
  def recording_uri
204
193
  recording.uri
205
194
  end
@@ -3,10 +3,6 @@
3
3
  module Punchblock
4
4
  class Event
5
5
  class Complete < Event
6
- # TODO: Validate response and return response type.
7
- # -----
8
- # <complete xmlns="urn:xmpp:rayo:ext:1"/>
9
-
10
6
  register :complete, :ext
11
7
 
12
8
  def reason
@@ -175,7 +175,7 @@ module Punchblock
175
175
  command.response = true
176
176
  end
177
177
  when Command::Hangup
178
- send_ami_action 'Hangup', 'Channel' => channel do |response|
178
+ send_ami_action 'Hangup', 'Channel' => channel, 'Cause' => 16 do |response|
179
179
  command.response = true
180
180
  end
181
181
  when Command::Join
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Punchblock
4
- VERSION = "1.4.1"
4
+ VERSION = "1.5.0"
5
5
  end
data/punchblock.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.add_runtime_dependency %q<state_machine>, ["~> 1.0"]
29
29
  s.add_runtime_dependency %q<future-resource>, ["~> 1.0"]
30
30
  s.add_runtime_dependency %q<has-guarded-handlers>, ["~> 1.3"]
31
- s.add_runtime_dependency %q<celluloid>, [">= 0.11.1"]
31
+ s.add_runtime_dependency %q<celluloid>, ["~> 0.11.1"]
32
32
  s.add_runtime_dependency %q<ruby_ami>, ["~> 1.2", ">= 1.2.1", "< 1.2.2"]
33
33
  s.add_runtime_dependency %q<ruby_fs>, ["~> 1.0", "< 1.0.1"]
34
34
  s.add_runtime_dependency %q<ruby_speech>, ["~> 1.0"]
@@ -14,14 +14,10 @@ module Punchblock
14
14
  Input.new :grammar => {:value => '[5 DIGITS]', :content_type => 'application/grammar+custom'},
15
15
  :mode => :speech,
16
16
  :terminator => '#',
17
- :max_digits => 10,
18
17
  :max_silence => 1000,
19
18
  :recognizer => 'en-US',
20
19
  :initial_timeout => 2000,
21
20
  :inter_digit_timeout => 2000,
22
- :term_timeout => 2000,
23
- :complete_timeout => 2000,
24
- :incomplete_timeout => 2000,
25
21
  :sensitivity => 0.5,
26
22
  :min_confidence => 0.5
27
23
  end
@@ -29,14 +25,10 @@ module Punchblock
29
25
  its(:grammar) { should be == Input::Grammar.new(:value => '[5 DIGITS]', :content_type => 'application/grammar+custom') }
30
26
  its(:mode) { should be == :speech }
31
27
  its(:terminator) { should be == '#' }
32
- its(:max_digits) { should be == 10 }
33
28
  its(:max_silence) { should be == 1000 }
34
29
  its(:recognizer) { should be == 'en-US' }
35
30
  its(:initial_timeout) { should be == 2000 }
36
31
  its(:inter_digit_timeout) { should be == 2000 }
37
- its(:term_timeout) { should be == 2000 }
38
- its(:complete_timeout) { should be == 2000 }
39
- its(:incomplete_timeout) { should be == 2000 }
40
32
  its(:sensitivity) { should be == 0.5 }
41
33
  its(:min_confidence) { should be == 0.5 }
42
34
  end
@@ -47,14 +39,10 @@ module Punchblock
47
39
  <input xmlns="urn:xmpp:rayo:input:1"
48
40
  mode="speech"
49
41
  terminator="#"
50
- max-digits="10"
51
42
  max-silence="1000"
52
43
  recognizer="en-US"
53
44
  initial-timeout="2000"
54
45
  inter-digit-timeout="2000"
55
- term-timeout="2000"
56
- complete-timeout="2000"
57
- incomplete-timeout="2000"
58
46
  sensitivity="0.5"
59
47
  min-confidence="0.5">
60
48
  <grammar content-type="application/grammar+custom">
@@ -71,14 +59,10 @@ module Punchblock
71
59
  its(:grammar) { should be == Input::Grammar.new(:value => '[5 DIGITS]', :content_type => 'application/grammar+custom') }
72
60
  its(:mode) { should be == :speech }
73
61
  its(:terminator) { should be == '#' }
74
- its(:max_digits) { should be == 10 }
75
62
  its(:max_silence) { should be == 1000 }
76
63
  its(:recognizer) { should be == 'en-US' }
77
64
  its(:initial_timeout) { should be == 2000 }
78
65
  its(:inter_digit_timeout) { should be == 2000 }
79
- its(:term_timeout) { should be == 2000 }
80
- its(:complete_timeout) { should be == 2000 }
81
- its(:incomplete_timeout) { should be == 2000 }
82
66
  its(:sensitivity) { should be == 0.5 }
83
67
  its(:min_confidence) { should be == 0.5 }
84
68
  end
@@ -132,6 +116,24 @@ module Punchblock
132
116
  it { should_not be == grammar4 }
133
117
  end
134
118
  end
119
+
120
+ describe 'with a grammar reference by URL' do
121
+ let(:url) { 'http://foo.com/bar.grxml' }
122
+
123
+ subject { Input::Grammar.new :url => url }
124
+
125
+ its(:url) { should be == url }
126
+
127
+ describe "comparison" do
128
+ it "should be the same with the same url" do
129
+ Input::Grammar.new(:url => url).should be == Input::Grammar.new(:url => url)
130
+ end
131
+
132
+ it "should be different with a different url" do
133
+ Input::Grammar.new(:url => url).should_not be == Input::Grammar.new(:url => 'http://doo.com/dah')
134
+ end
135
+ end
136
+ end
135
137
  end
136
138
 
137
139
  describe "actions" do
@@ -14,7 +14,6 @@ module Punchblock
14
14
  Record.new :format => 'WAV',
15
15
  :start_beep => true,
16
16
  :start_paused => false,
17
- :stop_beep => true,
18
17
  :max_duration => 500000,
19
18
  :initial_timeout => 10000,
20
19
  :final_timeout => 30000
@@ -23,7 +22,6 @@ module Punchblock
23
22
  its(:format) { should be == 'WAV' }
24
23
  its(:start_beep) { should be == true }
25
24
  its(:start_paused) { should be == false }
26
- its(:stop_beep) { should be == true }
27
25
  its(:max_duration) { should be == 500000 }
28
26
  its(:initial_timeout) { should be == 10000 }
29
27
  its(:final_timeout) { should be == 30000 }
@@ -36,7 +34,6 @@ module Punchblock
36
34
  format="WAV"
37
35
  start-beep="true"
38
36
  start-paused="false"
39
- stop-beep="true"
40
37
  max-duration="500000"
41
38
  initial-timeout="10000"
42
39
  final-timeout="30000"/>
@@ -50,7 +47,6 @@ module Punchblock
50
47
  its(:format) { should be == 'WAV' }
51
48
  its(:start_beep) { should be == true }
52
49
  its(:start_paused) { should be == false }
53
- its(:stop_beep) { should be == true }
54
50
  its(:max_duration) { should be == 500000 }
55
51
  its(:initial_timeout) { should be == 10000 }
56
52
  its(:final_timeout) { should be == 30000 }
@@ -76,7 +76,7 @@ module Punchblock
76
76
  offer.call_id = '9f00061'
77
77
  offer.to = 'sip:whatever@127.0.0.1'
78
78
  output = <<-MSG
79
- <output xmlns='urn:xmpp:tropo:say:1'>
79
+ <output xmlns='urn:xmpp:rayo:output:1'>
80
80
  <audio url='http://acme.com/greeting.mp3'>
81
81
  Thanks for calling ACME company
82
82
  </audio>
@@ -827,6 +827,7 @@ module Punchblock
827
827
  subject.execute_command command
828
828
  ami_action = subject.wrapped_object.instance_variable_get(:'@current_ami_action')
829
829
  ami_action.name.should be == "hangup"
830
+ ami_action.headers['Cause'].should be == 16
830
831
  ami_action << RubyAMI::Response.new
831
832
  command.response(0.5).should be true
832
833
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: punchblock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-09-06 00:00:00.000000000 Z
14
+ date: 2012-10-01 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: niceogiri
@@ -114,7 +114,7 @@ dependencies:
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  none: false
116
116
  requirements:
117
- - - ! '>='
117
+ - - ~>
118
118
  - !ruby/object:Gem::Version
119
119
  version: 0.11.1
120
120
  type: :runtime
@@ -122,7 +122,7 @@ dependencies:
122
122
  version_requirements: !ruby/object:Gem::Requirement
123
123
  none: false
124
124
  requirements:
125
- - - ! '>='
125
+ - - ~>
126
126
  - !ruby/object:Gem::Version
127
127
  version: 0.11.1
128
128
  - !ruby/object:Gem::Dependency
@@ -423,8 +423,6 @@ files:
423
423
  - lib/punchblock/has_headers.rb
424
424
  - lib/punchblock/header.rb
425
425
  - lib/punchblock/key_value_pair_node.rb
426
- - lib/punchblock/media_container.rb
427
- - lib/punchblock/media_node.rb
428
426
  - lib/punchblock/protocol_error.rb
429
427
  - lib/punchblock/rayo_node.rb
430
428
  - lib/punchblock/ref.rb
@@ -523,7 +521,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
523
521
  version: '0'
524
522
  segments:
525
523
  - 0
526
- hash: 1778552231483051908
524
+ hash: -689196999409732364
527
525
  required_rubygems_version: !ruby/object:Gem::Requirement
528
526
  none: false
529
527
  requirements:
@@ -1,42 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Punchblock
4
- module MediaContainer
5
- ##
6
- # @return [String] the TTS voice to use
7
- #
8
- def voice
9
- read_attr :voice
10
- end
11
-
12
- ##
13
- # @param [String] voice to use when rendering TTS
14
- #
15
- def voice=(voice)
16
- write_attr :voice, voice
17
- end
18
-
19
- ##
20
- # @return [String] the SSML document to render TTS
21
- #
22
- def ssml
23
- node = children.first
24
- RubySpeech::SSML.import node if node
25
- end
26
-
27
- ##
28
- # @param [String] ssml the SSML document to render TTS
29
- #
30
- def ssml=(ssml)
31
- return unless ssml
32
- unless ssml.is_a?(RubySpeech::SSML::Element)
33
- ssml = RubySpeech::SSML.import ssml
34
- end
35
- self << ssml
36
- end
37
-
38
- def inspect_attributes # :nodoc:
39
- [:voice, :ssml] + super
40
- end
41
- end
42
- end
@@ -1,19 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Punchblock
4
- class MediaNode < RayoNode
5
- include MediaContainer
6
-
7
- def self.new(options = {})
8
- super().tap do |new_node|
9
- case options
10
- when Hash
11
- new_node << options.delete(:text) if options[:text]
12
- options.each_pair { |k,v| new_node.send :"#{k}=", v }
13
- when Nokogiri::XML::Element
14
- new_node.inherit options
15
- end
16
- end
17
- end
18
- end
19
- end