adhearsion 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +4 -0
- data/lib/adhearsion/version.rb +1 -1
- data/lib/adhearsion/voip/asterisk/commands.rb +95 -5
- data/lib/adhearsion/voip/commands.rb +4 -0
- data/spec/voip/asterisk/commands_spec.rb +330 -37
- metadata +176 -111
data/CHANGELOG
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
1.1.1
|
2
|
+
- Command#play now returns false if audio failed to play
|
3
|
+
- Added new commands (#play!, #interruptible_play!, #input!) which raise PlaybackError if audio fails to play
|
4
|
+
|
1
5
|
1.1.0
|
2
6
|
- Added interactive call control console: ahn start console <path>
|
3
7
|
- Added centralized exception handler through eventing system
|
data/lib/adhearsion/version.rb
CHANGED
@@ -42,6 +42,8 @@ module Adhearsion
|
|
42
42
|
end
|
43
43
|
} unless defined? DYNAMIC_FEATURE_EXTENSIONS
|
44
44
|
|
45
|
+
PLAYBACK_SUCCESS = 'SUCCESS' unless defined? PLAYBACK_SUCCESS
|
46
|
+
|
45
47
|
# Utility method to write to pbx.
|
46
48
|
# @param [String] message raw message
|
47
49
|
def write(message)
|
@@ -197,12 +199,31 @@ module Adhearsion
|
|
197
199
|
# @example Play two sound files
|
198
200
|
# play "you-sound-cute", "what-are-you-wearing"
|
199
201
|
#
|
202
|
+
# @return [Boolean] true is returned if everything was successful. Otherwise, false indicates that
|
203
|
+
# some sound file(s) could not be played.
|
200
204
|
def play(*arguments)
|
205
|
+
result = true
|
206
|
+
unless play_time(arguments)
|
207
|
+
arguments.flatten.each do |argument|
|
208
|
+
# result starts off as true. But if the following command ever returns false, then result
|
209
|
+
# remains false.
|
210
|
+
result &= play_numeric(argument) || play_string(argument)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
result
|
214
|
+
end
|
215
|
+
|
216
|
+
# Same as {#play}, but immediately raises an exception if a sound file cannot be played.
|
217
|
+
#
|
218
|
+
# @return [true]
|
219
|
+
# @raise [Adhearsion::VoIP::PlaybackError] If a sound file cannot be played
|
220
|
+
def play!(*arguments)
|
201
221
|
unless play_time(arguments)
|
202
222
|
arguments.flatten.each do |argument|
|
203
|
-
play_numeric(argument) || play_string(argument)
|
223
|
+
play_numeric(argument) || play_string!(argument)
|
204
224
|
end
|
205
225
|
end
|
226
|
+
true
|
206
227
|
end
|
207
228
|
|
208
229
|
# Records a sound file with the given name. If no filename is specified a file named by Asterisk
|
@@ -478,13 +499,33 @@ module Adhearsion
|
|
478
499
|
# Note that when the digit limit is not specified the :accept_key becomes "#".
|
479
500
|
# Otherwise there would be no way to end the collection of digits. You can
|
480
501
|
# obviously override this by passing in a new key with :accept_key.
|
502
|
+
#
|
503
|
+
# @return [String] The keypad input received. An empty string is returned in the
|
504
|
+
# absense of input. If the :accept_key argument was pressed, it
|
505
|
+
# will not appear in the output.
|
481
506
|
def input(*args)
|
482
507
|
options = args.last.kind_of?(Hash) ? args.pop : {}
|
483
508
|
number_of_digits = args.shift
|
484
509
|
|
485
|
-
|
486
|
-
|
487
|
-
|
510
|
+
begin
|
511
|
+
input! number_of_digits, options
|
512
|
+
rescue PlaybackError => e
|
513
|
+
ahn_log.agi.warn { e }
|
514
|
+
retry # If sound playback fails, play the remaining sound files and wait for digits
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
# Same as {#input}, but immediately raises an exception if sound playback fails
|
519
|
+
#
|
520
|
+
# @return (see #input)
|
521
|
+
# @raise [Adhearsion::VoIP::PlaybackError] If a sound file cannot be played
|
522
|
+
def input!(*args)
|
523
|
+
options = args.last.kind_of?(Hash) ? args.pop : {}
|
524
|
+
number_of_digits = args.shift
|
525
|
+
|
526
|
+
options[:play] = [*options[:play]].compact
|
527
|
+
timeout = options[:timeout]
|
528
|
+
terminating_key = options[:accept_key]
|
488
529
|
terminating_key = if terminating_key
|
489
530
|
terminating_key.to_s
|
490
531
|
elsif number_of_digits.nil? && !terminating_key.equal?(false)
|
@@ -498,7 +539,17 @@ module Adhearsion
|
|
498
539
|
end
|
499
540
|
|
500
541
|
buffer = ''
|
501
|
-
|
542
|
+
if options[:play].any?
|
543
|
+
# Consume the sound files one at a time. In the event of playback failure, this
|
544
|
+
# tells us which files remain unplayed.
|
545
|
+
while file = options[:play].shift
|
546
|
+
key = interruptible_play! file
|
547
|
+
break if key
|
548
|
+
end
|
549
|
+
key ||= ''
|
550
|
+
else
|
551
|
+
key = wait_for_digit timeout || -1
|
552
|
+
end
|
502
553
|
loop do
|
503
554
|
return buffer if key.nil?
|
504
555
|
if terminating_key
|
@@ -921,6 +972,23 @@ module Adhearsion
|
|
921
972
|
nil
|
922
973
|
end
|
923
974
|
|
975
|
+
#
|
976
|
+
# Same as {#interruptible_play}, but immediately raises an exception if a sound file cannot be played.
|
977
|
+
#
|
978
|
+
# @return (see #interruptible_play)
|
979
|
+
# @raise [Adhearsion::VoIP::PlaybackError] If a sound file cannot be played
|
980
|
+
def interruptible_play!(*files)
|
981
|
+
startpos = 0
|
982
|
+
files.flatten.each do |file|
|
983
|
+
result = stream_file_result_from response("STREAM FILE", file, "1234567890*#")
|
984
|
+
if result[:endpos].to_i <= startpos
|
985
|
+
raise Adhearsion::VoIP::PlaybackError, "The sound file could not opened to stream. The parsed response was #{result.inspect}"
|
986
|
+
end
|
987
|
+
return result[:digit] unless result[:digit] == 0.chr
|
988
|
+
end
|
989
|
+
nil
|
990
|
+
end
|
991
|
+
|
924
992
|
##
|
925
993
|
# Executes the SayPhonetic command. This command will read the text passed in
|
926
994
|
# out load using the NATO phonetic alphabet.
|
@@ -1062,6 +1130,15 @@ module Adhearsion
|
|
1062
1130
|
digit.to_i.chr if digit && digit.to_s != "-1"
|
1063
1131
|
end
|
1064
1132
|
|
1133
|
+
def stream_file_result_from(response_string)
|
1134
|
+
raise ArgumentError, "Can't coerce nil into AGI response! This could be a bug!" unless response_string
|
1135
|
+
params = {}
|
1136
|
+
digit, endpos = response_string.match(/^#{response_prefix}(-?\d+) endpos=(\d+)/).values_at 1, 2
|
1137
|
+
params[:digit] = digit.to_i.chr if digit && digit.to_s != "-1"
|
1138
|
+
params[:endpos] = endpos.to_i if endpos
|
1139
|
+
params
|
1140
|
+
end
|
1141
|
+
|
1065
1142
|
def extract_input_from(result)
|
1066
1143
|
return false if error?(result)
|
1067
1144
|
# return false if input_timed_out?(result)
|
@@ -1091,6 +1168,19 @@ module Adhearsion
|
|
1091
1168
|
|
1092
1169
|
def play_string(argument)
|
1093
1170
|
execute(:playback, argument)
|
1171
|
+
get_variable('PLAYBACKSTATUS') == PLAYBACK_SUCCESS
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
# Like play_string(), but this will raise Exceptions if there's a problem.
|
1175
|
+
#
|
1176
|
+
# @return [true]
|
1177
|
+
# @raise [Adhearsion::VoIP::PlaybackError] If a sound file cannot be played
|
1178
|
+
# @see http://www.voip-info.org/wiki/view/Asterisk+cmd+Playback More information on the Asterisk Playback command
|
1179
|
+
def play_string!(argument)
|
1180
|
+
response = execute :playback, argument
|
1181
|
+
playback = get_variable 'PLAYBACKSTATUS'
|
1182
|
+
return true if playback == PLAYBACK_SUCCESS
|
1183
|
+
raise PlaybackError, "Playback failed with PLAYBACKSTATUS: #{playback.inspect}. The raw response was #{response.inspect}."
|
1094
1184
|
end
|
1095
1185
|
|
1096
1186
|
def play_sound_files_for_menu(menu_instance, sound_files)
|
@@ -114,6 +114,24 @@ module DialplanCommandTestHelpers
|
|
114
114
|
pbx_should_respond_with_success digit.kind_of?(String) ? digit[0] : digit
|
115
115
|
end
|
116
116
|
|
117
|
+
def pbx_should_respond_with_playback_success
|
118
|
+
pbx_should_respond_with pbx_raw_response
|
119
|
+
mock_call.should_receive(:get_variable).once.with('PLAYBACKSTATUS').and_return 'SUCCESS'
|
120
|
+
end
|
121
|
+
|
122
|
+
def pbx_should_respond_with_playback_failure
|
123
|
+
pbx_should_respond_with pbx_raw_response
|
124
|
+
mock_call.should_receive(:get_variable).once.with('PLAYBACKSTATUS').and_return 'FAILED'
|
125
|
+
end
|
126
|
+
|
127
|
+
def pbx_should_respond_with_stream_file_success(success_code = nil, endpos = '20000')
|
128
|
+
pbx_should_respond_with pbx_raw_stream_file_response(success_code, endpos)
|
129
|
+
end
|
130
|
+
|
131
|
+
def pbx_should_respond_with_stream_file_failure_on_open(endpos = nil)
|
132
|
+
pbx_should_respond_with pbx_raw_stream_file_response(nil, endpos)
|
133
|
+
end
|
134
|
+
|
117
135
|
def pbx_should_respond_with_a_wait_for_digit_timeout
|
118
136
|
pbx_should_respond_with_successful_background_response 0
|
119
137
|
end
|
@@ -122,10 +140,22 @@ module DialplanCommandTestHelpers
|
|
122
140
|
"200 result=#{success_code || default_success_code}"
|
123
141
|
end
|
124
142
|
|
143
|
+
def pbx_raw_response(code = nil)
|
144
|
+
"200 result=#{code || default_code}\n"
|
145
|
+
end
|
146
|
+
|
147
|
+
def pbx_raw_stream_file_response(code = nil, endpos = nil)
|
148
|
+
"200 result=#{code || default_code} endpos=#{endpos || default_code}\n"
|
149
|
+
end
|
150
|
+
|
125
151
|
def default_success_code
|
126
152
|
'1'
|
127
153
|
end
|
128
154
|
|
155
|
+
def default_code
|
156
|
+
'0'
|
157
|
+
end
|
158
|
+
|
129
159
|
def pbx_failure_response(failure_code = nil)
|
130
160
|
"200 result=#{failure_code || default_failure_code}"
|
131
161
|
end
|
@@ -153,6 +183,12 @@ module DialplanCommandTestHelpers
|
|
153
183
|
output_stream_matches(/sayunixtime "#{number}"/)
|
154
184
|
end
|
155
185
|
|
186
|
+
def pbx_was_asked_to_stream(*audio_files)
|
187
|
+
audio_files.flatten.each do |audio_file|
|
188
|
+
output_stream_matches /^STREAM FILE "#{audio_file}" "1234567890\*#"\n$/
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
156
192
|
def pbx_was_asked_to_execute(application, *options)
|
157
193
|
output_stream_matches(/exec saydigits "#{options.join('|')}"/i)
|
158
194
|
end
|
@@ -219,25 +255,121 @@ describe 'interruptible_play command' do
|
|
219
255
|
it 'should return a string for the digit that was pressed' do
|
220
256
|
digits = %w{0 1 # * 9}.map{|c| c.ord}
|
221
257
|
file = "file_doesnt_matter"
|
222
|
-
digits.each { |digit|
|
223
|
-
digits.map { |digit| mock_call.
|
258
|
+
digits.each { |digit| pbx_should_respond_with_stream_file_success digit }
|
259
|
+
digits.map { |digit| mock_call.interruptible_play file }.should == digits.map(&:chr)
|
260
|
+
pbx_was_asked_to_stream file
|
224
261
|
end
|
225
262
|
|
226
263
|
it "should return nil if no digit was pressed" do
|
227
|
-
|
228
|
-
|
264
|
+
pbx_should_respond_with_stream_file_success 0
|
265
|
+
file = 'foobar'
|
266
|
+
mock_call.interruptible_play(file).should be nil
|
267
|
+
pbx_was_asked_to_stream file
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'should return nil if no digit was pressed, even if the sound file is not found' do
|
271
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
272
|
+
file = 'foobar'
|
273
|
+
mock_call.interruptible_play(file).should be nil
|
274
|
+
pbx_was_asked_to_stream file
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should play a series of files, stopping the series when a digit is played" do
|
278
|
+
stubbed_keypad_input = [0, 0, ?3.ord]
|
279
|
+
stubbed_keypad_input.each do |digit|
|
280
|
+
pbx_should_respond_with_stream_file_success digit
|
281
|
+
end
|
282
|
+
|
283
|
+
play_files = (100..105).map &:to_s
|
284
|
+
played_files = (100..102).map &:to_s
|
285
|
+
mock_call.interruptible_play(*play_files).should == '3'
|
286
|
+
pbx_was_asked_to_stream played_files
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'should play a series of files, stopping the series when a digit is played, even if the sound files cannot be found' do
|
290
|
+
pbx_should_respond_with_stream_file_success 0
|
291
|
+
pbx_should_respond_with_stream_file_success 0
|
292
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
293
|
+
pbx_should_respond_with_stream_file_success ?9.ord
|
294
|
+
|
295
|
+
play_files = ('sound1'..'sound6').map &:to_s
|
296
|
+
played_files = ('sound1'..'sound4').map &:to_s
|
297
|
+
mock_call.interruptible_play(*play_files).should == '9'
|
298
|
+
pbx_was_asked_to_stream played_files
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
describe 'interruptible_play! command' do
|
304
|
+
include DialplanCommandTestHelpers
|
305
|
+
|
306
|
+
it 'should return a string for the digit that was pressed' do
|
307
|
+
digits = %w{0 1 # * 9}.map{|c| c.ord}
|
308
|
+
file = "file_doesnt_matter"
|
309
|
+
digits.each { |digit| pbx_should_respond_with_stream_file_success digit }
|
310
|
+
digits.map { |digit| mock_call.interruptible_play! file }.should == digits.map(&:chr)
|
311
|
+
pbx_was_asked_to_stream file
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should return nil if no digit was pressed" do
|
315
|
+
pbx_should_respond_with_stream_file_success 0
|
316
|
+
file = 'foobar'
|
317
|
+
mock_call.interruptible_play!(file).should be nil
|
318
|
+
pbx_was_asked_to_stream file
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'should raise an error when the sound file is not found' do
|
322
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
323
|
+
file = 'foobar'
|
324
|
+
the_following_code {
|
325
|
+
mock_call.interruptible_play! file
|
326
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
327
|
+
pbx_was_asked_to_stream file
|
229
328
|
end
|
230
329
|
|
231
330
|
it "should play a series of files, stopping the series when a digit is played" do
|
232
331
|
stubbed_keypad_input = [0, 0, ?3.ord]
|
233
332
|
stubbed_keypad_input.each do |digit|
|
234
|
-
|
333
|
+
pbx_should_respond_with_stream_file_success digit
|
235
334
|
end
|
236
335
|
|
237
|
-
|
238
|
-
|
336
|
+
play_files = (100..105).map &:to_s
|
337
|
+
played_files = (100..102).map &:to_s
|
338
|
+
mock_call.interruptible_play!(*play_files).should == '3'
|
339
|
+
pbx_was_asked_to_stream played_files
|
239
340
|
end
|
240
341
|
|
342
|
+
it 'should play a series of files, raising an error if a sound file cannot be found' do
|
343
|
+
pbx_should_respond_with_stream_file_success 0
|
344
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
345
|
+
|
346
|
+
play_files = ('sound1'..'sound6').map &:to_s
|
347
|
+
played_files = ('sound1'..'sound2').map &:to_s
|
348
|
+
the_following_code {
|
349
|
+
mock_call.interruptible_play! *play_files
|
350
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
351
|
+
pbx_was_asked_to_stream played_files
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should raise an error if an audio file cannot be found' do
|
355
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
356
|
+
audio_file = 'nixon-tapes'
|
357
|
+
the_following_code {
|
358
|
+
mock_call.interruptible_play! audio_file
|
359
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
360
|
+
pbx_was_asked_to_stream audio_file
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'should raise an error when audio files cannot be found' do
|
364
|
+
pbx_should_respond_with_stream_file_success
|
365
|
+
pbx_should_respond_with_stream_file_failure_on_open # 'paperz' is the only audio that is missing
|
366
|
+
audio_files = ['rock', 'paperz', 'scissors']
|
367
|
+
|
368
|
+
the_following_code {
|
369
|
+
mock_call.interruptible_play! audio_files
|
370
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
371
|
+
pbx_was_asked_to_stream ['rock', 'paperz'] # stop short before playing with scissors!
|
372
|
+
end
|
241
373
|
end
|
242
374
|
|
243
375
|
describe 'wait_for_digit command' do
|
@@ -307,60 +439,77 @@ describe 'play command' do
|
|
307
439
|
include DialplanCommandTestHelpers
|
308
440
|
|
309
441
|
it 'passing a single string to play results in the playback application being executed with that file name on the PBX' do
|
310
|
-
|
442
|
+
pbx_should_respond_with_playback_success
|
311
443
|
audio_file = "cents-per-minute"
|
312
|
-
mock_call.play
|
444
|
+
mock_call.play(audio_file).should be true
|
313
445
|
pbx_was_asked_to_play audio_file
|
314
446
|
end
|
315
447
|
|
316
448
|
it 'multiple strings can be passed to play, causing multiple playback commands to be issued' do
|
317
449
|
2.times do
|
318
|
-
|
450
|
+
pbx_should_respond_with_playback_success
|
319
451
|
end
|
320
452
|
audio_files = ["cents-per-minute", 'o-hai']
|
321
|
-
mock_call.play
|
453
|
+
mock_call.play(audio_files).should be true
|
454
|
+
pbx_was_asked_to_play audio_files
|
455
|
+
end
|
456
|
+
|
457
|
+
it 'should return false if an audio file cannot be found' do
|
458
|
+
pbx_should_respond_with_playback_failure
|
459
|
+
audio_file = 'nixon-tapes'
|
460
|
+
mock_call.play(audio_file).should be false
|
461
|
+
pbx_was_asked_to_play audio_file
|
462
|
+
end
|
463
|
+
|
464
|
+
it 'should return false when audio files cannot be found' do
|
465
|
+
pbx_should_respond_with_playback_success
|
466
|
+
pbx_should_respond_with_playback_failure # 'paperz' is the only audio that is missing
|
467
|
+
pbx_should_respond_with_playback_success
|
468
|
+
audio_files = ['rock', 'paperz', 'scissors']
|
469
|
+
|
470
|
+
mock_call.play(audio_files).should be false
|
322
471
|
pbx_was_asked_to_play audio_files
|
323
472
|
end
|
324
473
|
|
325
474
|
it 'If a number is passed to play(), the saynumber application is executed with the number as an argument' do
|
326
475
|
pbx_should_respond_with_success
|
327
|
-
mock_call.play
|
476
|
+
mock_call.play(123).should be true
|
328
477
|
pbx_was_asked_to_play_number(123)
|
329
478
|
end
|
330
479
|
|
331
480
|
it 'if a string representation of a number is passed to play(), the saynumber application is executed with the number as an argument' do
|
332
481
|
pbx_should_respond_with_success
|
333
|
-
mock_call.play
|
482
|
+
mock_call.play('123').should be true
|
334
483
|
pbx_was_asked_to_play_number(123)
|
335
484
|
end
|
336
485
|
|
337
486
|
it 'If a Time is passed to play(), the SayUnixTime application will be executed with the time since the UNIX epoch in seconds as an argument' do
|
338
487
|
time = Time.parse("12/5/2000")
|
339
488
|
pbx_should_respond_with_success
|
340
|
-
mock_call.play
|
489
|
+
mock_call.play(time).should be true
|
341
490
|
pbx_was_asked_to_play_time(time.to_i)
|
342
491
|
end
|
343
492
|
|
344
493
|
it 'If a Date is passed to play(), the SayUnixTime application will be executed with the date passed in' do
|
345
494
|
date = Date.parse('2011-01-23')
|
346
|
-
mock_call.should_receive(:execute).once.with(:sayunixtime, date.to_time.to_i, "",'BdY').and_return
|
347
|
-
mock_call.play
|
495
|
+
mock_call.should_receive(:execute).once.with(:sayunixtime, date.to_time.to_i, "",'BdY').and_return pbx_raw_response
|
496
|
+
mock_call.play(date).should be true
|
348
497
|
end
|
349
498
|
|
350
499
|
it 'If a Date or Time is passed to play_time(), the SayUnixTime application will be executed with the date and format passed in' do
|
351
500
|
date, format = Date.parse('2011-01-23'), 'ABdY'
|
352
|
-
mock_call.should_receive(:execute).once.with(:sayunixtime, date.to_time.to_i, "",format).and_return
|
353
|
-
mock_call.play_time
|
501
|
+
mock_call.should_receive(:execute).once.with(:sayunixtime, date.to_time.to_i, "",format).and_return "200 result=0\n"
|
502
|
+
mock_call.play_time(date, :format => format).should == pbx_raw_response
|
354
503
|
|
355
504
|
time, format = Time.at(875121313), 'BdY \'digits/at\' IMp'
|
356
|
-
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, "",format).and_return
|
357
|
-
mock_call.play_time
|
505
|
+
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, "",format).and_return pbx_raw_response
|
506
|
+
mock_call.play_time(time, :format => format).should == pbx_raw_response
|
358
507
|
end
|
359
508
|
|
360
509
|
it 'If a Time object is passed to play_time, the SayUnixTime application will be executed with the default parameters' do
|
361
510
|
time = Time.at(875121313)
|
362
|
-
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, "",'').and_return
|
363
|
-
mock_call.play_time
|
511
|
+
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, "",'').and_return pbx_raw_response
|
512
|
+
mock_call.play_time(time).should == pbx_raw_response
|
364
513
|
end
|
365
514
|
|
366
515
|
it 'If an object other than Time, DateTime, or Date is passed to play_time false will be returned' do
|
@@ -370,16 +519,16 @@ describe 'play command' do
|
|
370
519
|
|
371
520
|
it 'If an array containing a Date/DateTime/Time object and a hash is passed to play(), the SayUnixTime application will be executed with the object passed in with the specified format and timezone' do
|
372
521
|
date, format = Date.parse('2011-01-23'), 'ABdY'
|
373
|
-
mock_call.should_receive(:execute).once.with(:sayunixtime, date.to_time.to_i, "",format).and_return
|
374
|
-
mock_call.play
|
522
|
+
mock_call.should_receive(:execute).once.with(:sayunixtime, date.to_time.to_i, "",format).and_return pbx_raw_response
|
523
|
+
mock_call.play([date, {:format => format}]).should be true
|
375
524
|
|
376
525
|
time, timezone = Time.at(1295843084), 'US/Eastern'
|
377
|
-
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, timezone,'').and_return
|
378
|
-
mock_call.play
|
526
|
+
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, timezone,'').and_return pbx_raw_response
|
527
|
+
mock_call.play([time, {:timezone => timezone}]).should be true
|
379
528
|
|
380
529
|
time, timezone, format = Time.at(1295843084), 'US/Eastern', 'ABdY \'digits/at\' IMp'
|
381
|
-
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, timezone,format).and_return
|
382
|
-
mock_call.play
|
530
|
+
mock_call.should_receive(:execute).once.with(:sayunixtime, time.to_i, timezone,format).and_return pbx_raw_response
|
531
|
+
mock_call.play([time, {:timezone => timezone, :format => format}]).should be true
|
383
532
|
end
|
384
533
|
|
385
534
|
it 'If a string matching dollars and (optionally) cents is passed to play(), a series of command will be executed to read the dollar amount', :ignore => true do
|
@@ -388,6 +537,39 @@ describe 'play command' do
|
|
388
537
|
end
|
389
538
|
end
|
390
539
|
|
540
|
+
describe 'play! command' do
|
541
|
+
include DialplanCommandTestHelpers
|
542
|
+
|
543
|
+
it 'should accept multiple strings to play, causing multiple playback commands to be issued' do
|
544
|
+
2.times do
|
545
|
+
pbx_should_respond_with_playback_success
|
546
|
+
end
|
547
|
+
audio_files = ["cents-per-minute", 'o-hai']
|
548
|
+
mock_call.play!(audio_files).should be true
|
549
|
+
pbx_was_asked_to_play audio_files
|
550
|
+
end
|
551
|
+
|
552
|
+
it 'should raise an error if an audio file cannot be found' do
|
553
|
+
pbx_should_respond_with_playback_failure
|
554
|
+
audio_file = 'nixon-tapes'
|
555
|
+
the_following_code {
|
556
|
+
mock_call.play! audio_file
|
557
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
558
|
+
pbx_was_asked_to_play audio_file
|
559
|
+
end
|
560
|
+
|
561
|
+
it 'should raise an error when audio files cannot be found' do
|
562
|
+
pbx_should_respond_with_playback_success
|
563
|
+
pbx_should_respond_with_playback_failure # 'paperz' is the only audio that is missing
|
564
|
+
audio_files = ['rock', 'paperz', 'scissors']
|
565
|
+
|
566
|
+
the_following_code {
|
567
|
+
mock_call.play! audio_files
|
568
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
569
|
+
pbx_was_asked_to_play ['rock', 'paperz'] # stop short before playing with scissors!
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
391
573
|
describe 'input command' do
|
392
574
|
|
393
575
|
include DialplanCommandTestHelpers
|
@@ -402,14 +584,16 @@ describe 'input command' do
|
|
402
584
|
end
|
403
585
|
|
404
586
|
it 'input() calls wait_for_digit the specified number of times (when no sound files are given)' do
|
405
|
-
|
587
|
+
mock_call.should_receive(:interruptible_play!).never
|
406
588
|
mock_call.should_receive(:wait_for_digit).times(4).and_return('1', '2', '3', '4')
|
407
589
|
mock_call.input(4).should == '1234'
|
408
590
|
end
|
409
591
|
|
410
|
-
it 'should execute wait_for_digit if no digit is pressed during interruptible_play' do
|
592
|
+
it 'should execute wait_for_digit if no digit is pressed during interruptible_play!' do
|
411
593
|
sound_files = %w[one two three]
|
412
|
-
mock_call.should_receive(:interruptible_play).once.with(
|
594
|
+
mock_call.should_receive(:interruptible_play!).once.with('one').and_return nil
|
595
|
+
mock_call.should_receive(:interruptible_play!).once.with('two').and_return nil
|
596
|
+
mock_call.should_receive(:interruptible_play!).once.with('three').and_return nil
|
413
597
|
mock_call.should_receive(:wait_for_digit).once.and_throw :digit_request
|
414
598
|
should_throw(:digit_request) { mock_call.input(10, :play => sound_files) }
|
415
599
|
end
|
@@ -435,14 +619,16 @@ describe 'input command' do
|
|
435
619
|
end
|
436
620
|
|
437
621
|
it 'passes wait_for_digit the :timeout option when one is given' do
|
438
|
-
mock_call.should_receive(:interruptible_play).never
|
622
|
+
mock_call.should_receive(:interruptible_play!).never
|
439
623
|
mock_call.should_receive(:wait_for_digit).twice.and_return '1', '2'
|
440
624
|
mock_call.input(2, :timeout => 1.minute).should == '12'
|
441
625
|
end
|
442
626
|
|
443
|
-
it 'executes interruptible_play() with all of the files given to :play' do
|
627
|
+
it 'executes interruptible_play!() with all of the files given to :play' do
|
444
628
|
sound_files = %w[foo bar qaz]
|
445
|
-
mock_call.should_receive(:interruptible_play).once.with(
|
629
|
+
mock_call.should_receive(:interruptible_play!).once.with('foo').and_return nil
|
630
|
+
mock_call.should_receive(:interruptible_play!).once.with('bar').and_return nil
|
631
|
+
mock_call.should_receive(:interruptible_play!).once.with('qaz').and_return '#'
|
446
632
|
mock_call.should_receive(:wait_for_digit).once.and_return '*'
|
447
633
|
mock_call.input(2, :play => sound_files).should == '#*'
|
448
634
|
end
|
@@ -453,14 +639,121 @@ describe 'input command' do
|
|
453
639
|
end
|
454
640
|
|
455
641
|
it 'should execute wait_for_digit first if no sound files are given' do
|
456
|
-
mock_call.should_receive(:interruptible_play).never
|
642
|
+
mock_call.should_receive(:interruptible_play!).never
|
457
643
|
mock_call.should_receive(:wait_for_digit).once.and_throw :digit_request
|
458
644
|
should_throw(:digit_request) { mock_call.input(1) }
|
459
645
|
end
|
460
646
|
|
461
647
|
it "Input timing out when digits are pressed returns only the collected digits" do
|
462
|
-
|
463
|
-
mock_call.
|
648
|
+
timeout = 1.day
|
649
|
+
mock_call.should_receive(:wait_for_digit).twice.with(timeout).and_return '5', nil
|
650
|
+
mock_call.input(9, :timeout => timeout).should == '5'
|
651
|
+
end
|
652
|
+
|
653
|
+
it 'should execute wait_for_digit, even if some sound files are not found' do
|
654
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
655
|
+
file = 'foobar'
|
656
|
+
timeout = 1.hour
|
657
|
+
mock_call.should_receive(:wait_for_digit).twice.with(timeout).and_return '8', '9'
|
658
|
+
mock_call.input(2, :timeout => timeout, :play => file).should == '89'
|
659
|
+
pbx_was_asked_to_stream file
|
660
|
+
end
|
661
|
+
|
662
|
+
it 'should return an empty string if no keys are pressed, even if the sound file is not found' do
|
663
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
664
|
+
file = 'foobar'
|
665
|
+
timeout = 1.second
|
666
|
+
mock_call.should_receive(:wait_for_digit).once.with(timeout).and_return nil
|
667
|
+
mock_call.input(5, :timeout => timeout, :play => file).should == ''
|
668
|
+
pbx_was_asked_to_stream file
|
669
|
+
end
|
670
|
+
|
671
|
+
it 'should play a series of files, collecting digits even if some of the sound files cannot be found' do
|
672
|
+
pbx_should_respond_with_stream_file_success 0
|
673
|
+
pbx_should_respond_with_stream_file_success 0
|
674
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
675
|
+
pbx_should_respond_with_stream_file_success ?1.ord
|
676
|
+
|
677
|
+
play_files = ('sound1'..'sound6').map &:to_s
|
678
|
+
played_files = ('sound1'..'sound4').map &:to_s
|
679
|
+
timeout = 1.minute
|
680
|
+
mock_call.should_receive(:wait_for_digit).twice.with(timeout).and_return '2', '3'
|
681
|
+
mock_call.input(3, :timeout => timeout, :play => play_files).should == '123'
|
682
|
+
pbx_was_asked_to_stream played_files
|
683
|
+
end
|
684
|
+
|
685
|
+
it 'should play a series of 4 files, collecting digits even if some of the sound files cannot be found' do
|
686
|
+
pbx_should_respond_with_stream_file_success 0
|
687
|
+
pbx_should_respond_with_stream_file_success 0
|
688
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
689
|
+
pbx_should_respond_with_stream_file_success 0
|
690
|
+
pbx_should_respond_with_stream_file_success ?1.ord
|
691
|
+
|
692
|
+
play_files = ('sound1'..'sound8').map &:to_s
|
693
|
+
played_files = ('sound1'..'sound5').map &:to_s
|
694
|
+
timeout = 1.second
|
695
|
+
mock_call.should_receive(:wait_for_digit).times(3).with(timeout).and_return '2', '3', '4'
|
696
|
+
mock_call.input(4, :timeout => timeout, :play => play_files).should == '1234'
|
697
|
+
pbx_was_asked_to_stream played_files
|
698
|
+
end
|
699
|
+
|
700
|
+
end
|
701
|
+
|
702
|
+
describe 'input! command' do
|
703
|
+
|
704
|
+
include DialplanCommandTestHelpers
|
705
|
+
|
706
|
+
it 'should raise an error when the number of digits expected is -1 (this is deprecated behavior)' do
|
707
|
+
the_following_code {
|
708
|
+
mock_call.input! -1
|
709
|
+
}.should raise_error ArgumentError
|
710
|
+
end
|
711
|
+
|
712
|
+
it 'should execute wait_for_digit if no digit is pressed during interruptible_play!' do
|
713
|
+
sound_files = %w[one two three]
|
714
|
+
mock_call.should_receive(:interruptible_play!).once.with('one').and_return nil
|
715
|
+
mock_call.should_receive(:interruptible_play!).once.with('two').and_return nil
|
716
|
+
mock_call.should_receive(:interruptible_play!).once.with('three').and_return nil
|
717
|
+
mock_call.should_receive(:wait_for_digit).once.and_throw :digit_request
|
718
|
+
should_throw(:digit_request) { mock_call.input! 10, :play => sound_files }
|
719
|
+
end
|
720
|
+
|
721
|
+
it 'executes interruptible_play!() with all of the files given to :play' do
|
722
|
+
sound_files = %w[foo bar qaz]
|
723
|
+
mock_call.should_receive(:interruptible_play!).once.with('foo').and_return nil
|
724
|
+
mock_call.should_receive(:interruptible_play!).once.with('bar').and_return nil
|
725
|
+
mock_call.should_receive(:interruptible_play!).once.with('qaz').and_return '#'
|
726
|
+
mock_call.should_receive(:wait_for_digit).once.and_return '*'
|
727
|
+
mock_call.input!(2, :play => sound_files).should == '#*'
|
728
|
+
end
|
729
|
+
|
730
|
+
it 'should execute wait_for_digit first if no sound files are given' do
|
731
|
+
mock_call.should_receive(:interruptible_play!).never
|
732
|
+
mock_call.should_receive(:wait_for_digit).once.and_throw :digit_request
|
733
|
+
should_throw(:digit_request) { mock_call.input! 1 }
|
734
|
+
end
|
735
|
+
|
736
|
+
it 'should raise an error when the sound file is not found' do
|
737
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
738
|
+
file = 'foobar'
|
739
|
+
mock_call.should_receive(:wait_for_digit).never
|
740
|
+
the_following_code {
|
741
|
+
mock_call.input! 1, :play => file
|
742
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
743
|
+
pbx_was_asked_to_stream file
|
744
|
+
end
|
745
|
+
|
746
|
+
it 'should play a series of files, raising an error if a sound file cannot be found' do
|
747
|
+
pbx_should_respond_with_stream_file_success 0
|
748
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
749
|
+
mock_call.should_receive(:wait_for_digit).never
|
750
|
+
|
751
|
+
play_files = ('sound1'..'sound6').map &:to_s
|
752
|
+
played_files = ('sound1'..'sound2').map &:to_s
|
753
|
+
the_following_code {
|
754
|
+
mock_call.input! 10, :play => play_files, :timeout => 5.seconds
|
755
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
756
|
+
pbx_was_asked_to_stream played_files
|
464
757
|
end
|
465
758
|
|
466
759
|
end
|
metadata
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: adhearsion
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 1.1.1
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Jay Phillips
|
9
14
|
- Jason Goecke
|
10
15
|
- Ben Klang
|
@@ -12,150 +17,201 @@ authors:
|
|
12
17
|
autorequire:
|
13
18
|
bindir: bin
|
14
19
|
cert_chain: []
|
15
|
-
|
20
|
+
|
21
|
+
date: 2011-06-14 00:00:00 +01:00
|
16
22
|
default_executable:
|
17
|
-
dependencies:
|
18
|
-
- !ruby/object:Gem::Dependency
|
23
|
+
dependencies:
|
24
|
+
- !ruby/object:Gem::Dependency
|
19
25
|
name: bundler
|
20
|
-
|
26
|
+
prerelease: false
|
27
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
21
28
|
none: false
|
22
|
-
requirements:
|
23
|
-
- -
|
24
|
-
- !ruby/object:Gem::Version
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
hash: 3
|
33
|
+
segments:
|
34
|
+
- 1
|
35
|
+
- 0
|
36
|
+
- 10
|
25
37
|
version: 1.0.10
|
26
38
|
type: :runtime
|
27
|
-
|
28
|
-
|
29
|
-
- !ruby/object:Gem::Dependency
|
39
|
+
version_requirements: *id001
|
40
|
+
- !ruby/object:Gem::Dependency
|
30
41
|
name: log4r
|
31
|
-
|
42
|
+
prerelease: false
|
43
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
32
44
|
none: false
|
33
|
-
requirements:
|
34
|
-
- -
|
35
|
-
- !ruby/object:Gem::Version
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
hash: 29
|
49
|
+
segments:
|
50
|
+
- 1
|
51
|
+
- 0
|
52
|
+
- 5
|
36
53
|
version: 1.0.5
|
37
54
|
type: :runtime
|
38
|
-
|
39
|
-
|
40
|
-
- !ruby/object:Gem::Dependency
|
55
|
+
version_requirements: *id002
|
56
|
+
- !ruby/object:Gem::Dependency
|
41
57
|
name: activesupport
|
42
|
-
|
58
|
+
prerelease: false
|
59
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
43
60
|
none: false
|
44
|
-
requirements:
|
45
|
-
- -
|
46
|
-
- !ruby/object:Gem::Version
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 11
|
65
|
+
segments:
|
66
|
+
- 2
|
67
|
+
- 1
|
68
|
+
- 0
|
47
69
|
version: 2.1.0
|
48
70
|
type: :runtime
|
49
|
-
|
50
|
-
|
51
|
-
- !ruby/object:Gem::Dependency
|
71
|
+
version_requirements: *id003
|
72
|
+
- !ruby/object:Gem::Dependency
|
52
73
|
name: i18n
|
53
|
-
|
74
|
+
prerelease: false
|
75
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
54
76
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
hash: 3
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
59
84
|
type: :runtime
|
60
|
-
|
61
|
-
|
62
|
-
- !ruby/object:Gem::Dependency
|
85
|
+
version_requirements: *id004
|
86
|
+
- !ruby/object:Gem::Dependency
|
63
87
|
name: rubigen
|
64
|
-
|
88
|
+
prerelease: false
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
65
90
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 15
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 5
|
98
|
+
- 6
|
69
99
|
version: 1.5.6
|
70
100
|
type: :runtime
|
71
|
-
|
72
|
-
|
73
|
-
- !ruby/object:Gem::Dependency
|
101
|
+
version_requirements: *id005
|
102
|
+
- !ruby/object:Gem::Dependency
|
74
103
|
name: rake
|
75
|
-
|
104
|
+
prerelease: false
|
105
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
76
106
|
none: false
|
77
|
-
requirements:
|
78
|
-
- -
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
81
114
|
type: :runtime
|
82
|
-
|
83
|
-
|
84
|
-
- !ruby/object:Gem::Dependency
|
115
|
+
version_requirements: *id006
|
116
|
+
- !ruby/object:Gem::Dependency
|
85
117
|
name: pry
|
86
|
-
|
118
|
+
prerelease: false
|
119
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
87
120
|
none: false
|
88
|
-
requirements:
|
89
|
-
- -
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
hash: 3
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
92
128
|
type: :runtime
|
93
|
-
|
94
|
-
|
95
|
-
- !ruby/object:Gem::Dependency
|
129
|
+
version_requirements: *id007
|
130
|
+
- !ruby/object:Gem::Dependency
|
96
131
|
name: rubigen
|
97
|
-
|
132
|
+
prerelease: false
|
133
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
98
134
|
none: false
|
99
|
-
requirements:
|
100
|
-
- -
|
101
|
-
- !ruby/object:Gem::Version
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
hash: 15
|
139
|
+
segments:
|
140
|
+
- 1
|
141
|
+
- 5
|
142
|
+
- 6
|
102
143
|
version: 1.5.6
|
103
144
|
type: :development
|
104
|
-
|
105
|
-
|
106
|
-
- !ruby/object:Gem::Dependency
|
145
|
+
version_requirements: *id008
|
146
|
+
- !ruby/object:Gem::Dependency
|
107
147
|
name: rspec
|
108
|
-
|
148
|
+
prerelease: false
|
149
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
109
150
|
none: false
|
110
|
-
requirements:
|
111
|
-
- -
|
112
|
-
- !ruby/object:Gem::Version
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
hash: 31
|
155
|
+
segments:
|
156
|
+
- 2
|
157
|
+
- 4
|
158
|
+
- 0
|
113
159
|
version: 2.4.0
|
114
160
|
type: :development
|
115
|
-
|
116
|
-
|
117
|
-
- !ruby/object:Gem::Dependency
|
161
|
+
version_requirements: *id009
|
162
|
+
- !ruby/object:Gem::Dependency
|
118
163
|
name: flexmock
|
119
|
-
|
164
|
+
prerelease: false
|
165
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
120
166
|
none: false
|
121
|
-
requirements:
|
122
|
-
- -
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
hash: 3
|
171
|
+
segments:
|
172
|
+
- 0
|
173
|
+
version: "0"
|
125
174
|
type: :development
|
126
|
-
|
127
|
-
|
128
|
-
- !ruby/object:Gem::Dependency
|
175
|
+
version_requirements: *id010
|
176
|
+
- !ruby/object:Gem::Dependency
|
129
177
|
name: activerecord
|
130
|
-
|
178
|
+
prerelease: false
|
179
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
131
180
|
none: false
|
132
|
-
requirements:
|
133
|
-
- -
|
134
|
-
- !ruby/object:Gem::Version
|
135
|
-
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
hash: 3
|
185
|
+
segments:
|
186
|
+
- 0
|
187
|
+
version: "0"
|
136
188
|
type: :development
|
137
|
-
|
138
|
-
|
139
|
-
- !ruby/object:Gem::Dependency
|
189
|
+
version_requirements: *id011
|
190
|
+
- !ruby/object:Gem::Dependency
|
140
191
|
name: rake
|
141
|
-
|
192
|
+
prerelease: false
|
193
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
142
194
|
none: false
|
143
|
-
requirements:
|
144
|
-
- -
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
hash: 3
|
199
|
+
segments:
|
200
|
+
- 0
|
201
|
+
version: "0"
|
147
202
|
type: :development
|
148
|
-
|
149
|
-
version_requirements: *2153135140
|
203
|
+
version_requirements: *id012
|
150
204
|
description: Adhearsion is an open-source telephony development framework
|
151
205
|
email: dev&Adhearsion.com
|
152
|
-
executables:
|
206
|
+
executables:
|
153
207
|
- ahn
|
154
208
|
- ahnctl
|
155
209
|
- jahn
|
156
210
|
extensions: []
|
211
|
+
|
157
212
|
extra_rdoc_files: []
|
158
|
-
|
213
|
+
|
214
|
+
files:
|
159
215
|
- .gitignore
|
160
216
|
- CHANGELOG
|
161
217
|
- EVENTS
|
@@ -331,29 +387,38 @@ files:
|
|
331
387
|
has_rdoc: true
|
332
388
|
homepage: http://adhearsion.com
|
333
389
|
licenses: []
|
390
|
+
|
334
391
|
post_install_message:
|
335
392
|
rdoc_options: []
|
336
|
-
|
393
|
+
|
394
|
+
require_paths:
|
337
395
|
- lib
|
338
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
396
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
339
397
|
none: false
|
340
|
-
requirements:
|
341
|
-
- -
|
342
|
-
- !ruby/object:Gem::Version
|
343
|
-
|
344
|
-
|
398
|
+
requirements:
|
399
|
+
- - ">="
|
400
|
+
- !ruby/object:Gem::Version
|
401
|
+
hash: 3
|
402
|
+
segments:
|
403
|
+
- 0
|
404
|
+
version: "0"
|
405
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
345
406
|
none: false
|
346
|
-
requirements:
|
347
|
-
- -
|
348
|
-
- !ruby/object:Gem::Version
|
349
|
-
|
407
|
+
requirements:
|
408
|
+
- - ">="
|
409
|
+
- !ruby/object:Gem::Version
|
410
|
+
hash: 3
|
411
|
+
segments:
|
412
|
+
- 0
|
413
|
+
version: "0"
|
350
414
|
requirements: []
|
415
|
+
|
351
416
|
rubyforge_project: adhearsion
|
352
|
-
rubygems_version: 1.
|
417
|
+
rubygems_version: 1.4.2
|
353
418
|
signing_key:
|
354
419
|
specification_version: 2
|
355
420
|
summary: Adhearsion, open-source telephony development framework
|
356
|
-
test_files:
|
421
|
+
test_files:
|
357
422
|
- spec/ahn_command_spec.rb
|
358
423
|
- spec/component_manager_spec.rb
|
359
424
|
- spec/constants_spec.rb
|