punchblock 1.6.1 → 1.7.0
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.md +8 -0
- data/Guardfile +1 -1
- data/Rakefile +1 -1
- data/lib/punchblock/client.rb +5 -8
- data/lib/punchblock/client/component_registry.rb +8 -1
- data/lib/punchblock/component/component_node.rb +1 -0
- data/lib/punchblock/component/output.rb +15 -1
- data/lib/punchblock/translator/asterisk.rb +1 -1
- data/lib/punchblock/translator/asterisk/call.rb +1 -1
- data/lib/punchblock/translator/asterisk/component/output.rb +5 -1
- data/lib/punchblock/translator/freeswitch.rb +7 -1
- data/lib/punchblock/translator/freeswitch/call.rb +10 -6
- data/lib/punchblock/translator/freeswitch/component.rb +1 -1
- data/lib/punchblock/version.rb +1 -1
- data/punchblock.gemspec +1 -2
- data/spec/punchblock/client/component_registry_spec.rb +7 -0
- data/spec/punchblock/client_spec.rb +14 -12
- data/spec/punchblock/command_node_spec.rb +2 -2
- data/spec/punchblock/component/component_node_spec.rb +10 -3
- data/spec/punchblock/component/input_spec.rb +1 -1
- data/spec/punchblock/component/output_spec.rb +32 -27
- data/spec/punchblock/component/record_spec.rb +5 -5
- data/spec/punchblock/connection/asterisk_spec.rb +7 -7
- data/spec/punchblock/connection/freeswitch_spec.rb +8 -8
- data/spec/punchblock/connection/xmpp_spec.rb +9 -9
- data/spec/punchblock/translator/asterisk/call_spec.rb +65 -65
- data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +17 -20
- data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +13 -16
- data/spec/punchblock/translator/asterisk/component/input_spec.rb +9 -12
- data/spec/punchblock/translator/asterisk/component/output_spec.rb +62 -29
- data/spec/punchblock/translator/asterisk/component/record_spec.rb +38 -42
- data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +2 -2
- data/spec/punchblock/translator/asterisk/component_spec.rb +5 -5
- data/spec/punchblock/translator/asterisk_spec.rb +55 -55
- data/spec/punchblock/translator/freeswitch/call_spec.rb +80 -54
- data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +7 -10
- data/spec/punchblock/translator/freeswitch/component/input_spec.rb +8 -10
- data/spec/punchblock/translator/freeswitch/component/output_spec.rb +9 -12
- data/spec/punchblock/translator/freeswitch/component/record_spec.rb +31 -34
- data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +7 -10
- data/spec/punchblock/translator/freeswitch/component_spec.rb +6 -6
- data/spec/punchblock/translator/freeswitch_spec.rb +27 -27
- data/spec/punchblock_spec.rb +5 -6
- data/spec/spec_helper.rb +2 -3
- data/spec/support/mock_connection_with_event_handler.rb +8 -19
- metadata +5 -21
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# [develop](https://github.com/adhearsion/punchblock)
|
|
2
2
|
|
|
3
|
+
# [v1.7.0](https://github.com/adhearsion/punchblock/compare/v1.6.1...v1.7.0) - [2012-12-13](https://rubygems.org/gems/punchblock/versions/1.7.0)
|
|
4
|
+
* Feature: Support for the renderer attribute added to the Output component.
|
|
5
|
+
* Feature: FreeSWITCH and Asterisk translators now use the :renderer attribute on Output
|
|
6
|
+
* Bugfix: Fixed scenario where executing the ANSWER application on FreeSWITCH on an already answered call caused FS to stop accepting commands.
|
|
7
|
+
* Bugfix: Plug a severe memory leak
|
|
8
|
+
* Bugfix: Raise an error immediately if trying to execute an invalid media engine on Asterisk
|
|
9
|
+
* Bugfix: Handle a wider variety of types when configuring media engines on Asterisk and FreeSWITCH, such as Strings instead of Symbols
|
|
10
|
+
|
|
3
11
|
# [v1.6.1](https://github.com/adhearsion/punchblock/compare/v1.6.0...v1.6.1) - [2012-11-14](https://rubygems.org/gems/punchblock/versions/1.6.1)
|
|
4
12
|
* Bugfix: Safer component attribute writer conversion
|
|
5
13
|
|
data/Guardfile
CHANGED
data/Rakefile
CHANGED
|
@@ -7,7 +7,7 @@ require 'ci/reporter/rake/rspec'
|
|
|
7
7
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
8
8
|
spec.pattern = 'spec/**/*_spec.rb'
|
|
9
9
|
spec.rspec_opts = '--color'
|
|
10
|
-
spec.ruby_opts = "-w -r./spec/capture_warnings"
|
|
10
|
+
# spec.ruby_opts = "-w -r./spec/capture_warnings"
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
task :default => :spec
|
data/lib/punchblock/client.rb
CHANGED
|
@@ -19,7 +19,6 @@ module Punchblock
|
|
|
19
19
|
@event_queue = Queue.new
|
|
20
20
|
@connection = options[:connection]
|
|
21
21
|
@connection.event_handler = lambda { |event| self.handle_event event } if @connection
|
|
22
|
-
register_initial_handlers
|
|
23
22
|
@component_registry = ComponentRegistry.new
|
|
24
23
|
@write_timeout = options[:write_timeout] || 3
|
|
25
24
|
end
|
|
@@ -29,7 +28,7 @@ module Punchblock
|
|
|
29
28
|
if event.source
|
|
30
29
|
event.source.add_event event
|
|
31
30
|
else
|
|
32
|
-
trigger_handler
|
|
31
|
+
trigger_handler(:event, event) || event_queue.push(event)
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
|
|
@@ -37,12 +36,6 @@ module Punchblock
|
|
|
37
36
|
register_handler :event, *guards, &block
|
|
38
37
|
end
|
|
39
38
|
|
|
40
|
-
def register_initial_handlers
|
|
41
|
-
register_handler_with_priority :event, -10 do |event|
|
|
42
|
-
event_queue.push event
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
39
|
def register_component(component)
|
|
47
40
|
component_registry << component
|
|
48
41
|
end
|
|
@@ -51,6 +44,10 @@ module Punchblock
|
|
|
51
44
|
component_registry.find_by_id component_id
|
|
52
45
|
end
|
|
53
46
|
|
|
47
|
+
def delete_component_registration(component)
|
|
48
|
+
component_registry.delete component
|
|
49
|
+
end
|
|
50
|
+
|
|
54
51
|
def execute_command(command, options = {})
|
|
55
52
|
async = options.has_key?(:async) ? options.delete(:async) : true
|
|
56
53
|
command.client = self
|
|
@@ -7,7 +7,7 @@ module Punchblock
|
|
|
7
7
|
@mutex = Mutex.new
|
|
8
8
|
@components = Hash.new
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
def <<(component)
|
|
12
12
|
@mutex.synchronize do
|
|
13
13
|
@components[component.component_id] = component
|
|
@@ -19,6 +19,13 @@ module Punchblock
|
|
|
19
19
|
@components[component_id]
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
+
|
|
23
|
+
def delete(component)
|
|
24
|
+
@mutex.synchronize do
|
|
25
|
+
id = @components.key component
|
|
26
|
+
@components.delete id
|
|
27
|
+
end
|
|
28
|
+
end
|
|
22
29
|
end
|
|
23
30
|
end
|
|
24
31
|
end
|
|
@@ -157,8 +157,22 @@ module Punchblock
|
|
|
157
157
|
write_attr :'max-time', other, :to_i
|
|
158
158
|
end
|
|
159
159
|
|
|
160
|
+
##
|
|
161
|
+
# @return [String] the rendering engine requested by the component
|
|
162
|
+
#
|
|
163
|
+
def renderer
|
|
164
|
+
read_attr :renderer
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
##
|
|
168
|
+
# @param [String] the rendering engine to use with this component
|
|
169
|
+
#
|
|
170
|
+
def renderer=(renderer)
|
|
171
|
+
write_attr :renderer, renderer
|
|
172
|
+
end
|
|
173
|
+
|
|
160
174
|
def inspect_attributes
|
|
161
|
-
super + [:voice, :ssml, :interrupt_on, :start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time]
|
|
175
|
+
super + [:voice, :ssml, :interrupt_on, :start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time, :renderer]
|
|
162
176
|
end
|
|
163
177
|
|
|
164
178
|
state_machine :state do
|
|
@@ -27,7 +27,9 @@ module Punchblock
|
|
|
27
27
|
|
|
28
28
|
output_component = current_actor
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
rendering_engine = @component_node.renderer ? @component_node.renderer : @media_engine
|
|
31
|
+
|
|
32
|
+
case rendering_engine.to_sym
|
|
31
33
|
when :asterisk, nil
|
|
32
34
|
raise OptionError, "A voice value is unsupported on Asterisk." if @component_node.voice
|
|
33
35
|
raise OptionError, 'Interrupt digits are not allowed with early media.' if early && @component_node.interrupt_on
|
|
@@ -61,6 +63,8 @@ module Punchblock
|
|
|
61
63
|
@call.send_agi_action! 'EXEC Swift', swift_doc do |complete_event|
|
|
62
64
|
output_component.send_complete_event! success_reason
|
|
63
65
|
end
|
|
66
|
+
else
|
|
67
|
+
raise OptionError, 'The renderer foobar is unsupported.'
|
|
64
68
|
end
|
|
65
69
|
rescue UnrenderableDocError => e
|
|
66
70
|
with_error 'unrenderable document error', e.message
|
|
@@ -8,6 +8,7 @@ module Punchblock
|
|
|
8
8
|
class Freeswitch
|
|
9
9
|
include Celluloid
|
|
10
10
|
include HasGuardedHandlers
|
|
11
|
+
include DeadActorSafety
|
|
11
12
|
|
|
12
13
|
extend ActiveSupport::Autoload
|
|
13
14
|
|
|
@@ -65,6 +66,7 @@ module Punchblock
|
|
|
65
66
|
register_handler :es, [:has_key?, :other_leg_unique_id] => true do |event|
|
|
66
67
|
call = call_with_id event[:other_leg_unique_id]
|
|
67
68
|
call.handle_es_event! event if call
|
|
69
|
+
throw :pass
|
|
68
70
|
end
|
|
69
71
|
|
|
70
72
|
register_handler :es, lambda { |event| es_event_known_call? event } do |event|
|
|
@@ -78,7 +80,11 @@ module Punchblock
|
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def finalize
|
|
81
|
-
@calls.values.each
|
|
83
|
+
@calls.values.each do |call|
|
|
84
|
+
safe_from_dead_actors do
|
|
85
|
+
call.terminate
|
|
86
|
+
end
|
|
87
|
+
end
|
|
82
88
|
end
|
|
83
89
|
|
|
84
90
|
def handle_es_event(event)
|
|
@@ -68,6 +68,7 @@ module Punchblock
|
|
|
68
68
|
register_handler :es, :event_name => 'CHANNEL_ANSWER' do
|
|
69
69
|
@answered = true
|
|
70
70
|
send_pb_event Event::Answered.new
|
|
71
|
+
throw :pass
|
|
71
72
|
end
|
|
72
73
|
|
|
73
74
|
register_handler :es, :event_name => 'CHANNEL_STATE', [:[], :channel_call_state] => 'RINGING' do
|
|
@@ -99,7 +100,6 @@ module Punchblock
|
|
|
99
100
|
send_pb_event Event::Unjoined.new(:call_id => other_call_id)
|
|
100
101
|
end
|
|
101
102
|
|
|
102
|
-
|
|
103
103
|
register_handler :es, [:has_key?, :scope_variable_punchblock_component_id] => true do |event|
|
|
104
104
|
if component = component_with_id(event[:scope_variable_punchblock_component_id])
|
|
105
105
|
safe_from_dead_actors { component.handle_es_event event if component.alive? }
|
|
@@ -176,12 +176,15 @@ module Punchblock
|
|
|
176
176
|
application 'respond', '180 Ringing'
|
|
177
177
|
command.response = true
|
|
178
178
|
when Command::Answer
|
|
179
|
-
|
|
180
|
-
register_tmp_handler :es, :event_name => 'CHANNEL_ANSWER', [:[], :scope_variable_punchblock_command_id] => command_id do
|
|
181
|
-
@answered = true
|
|
179
|
+
if answered?
|
|
182
180
|
command.response = true
|
|
181
|
+
else
|
|
182
|
+
command_id = Punchblock.new_uuid
|
|
183
|
+
register_tmp_handler :es, :event_name => 'CHANNEL_ANSWER', [:[], :scope_variable_punchblock_command_id] => command_id do
|
|
184
|
+
command.response = true
|
|
185
|
+
end
|
|
186
|
+
application 'answer', "%[punchblock_command_id=#{command_id}]"
|
|
183
187
|
end
|
|
184
|
-
application 'answer', "%[punchblock_command_id=#{command_id}]"
|
|
185
188
|
when Command::Hangup
|
|
186
189
|
hangup
|
|
187
190
|
command.response = true
|
|
@@ -195,7 +198,8 @@ module Punchblock
|
|
|
195
198
|
hangup REJECT_TO_HANGUP_REASON[command.reason]
|
|
196
199
|
command.response = true
|
|
197
200
|
when Punchblock::Component::Output
|
|
198
|
-
|
|
201
|
+
media_renderer = command.renderer ? command.renderer : media_engine
|
|
202
|
+
case media_renderer.to_sym
|
|
199
203
|
when :freeswitch, :native, nil
|
|
200
204
|
execute_component Component::Output, command
|
|
201
205
|
when :flite
|
data/lib/punchblock/version.rb
CHANGED
data/punchblock.gemspec
CHANGED
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
|
27
27
|
s.add_runtime_dependency %q<activesupport>, ["~> 3.0"]
|
|
28
28
|
s.add_runtime_dependency %q<state_machine>, ["~> 1.0"]
|
|
29
29
|
s.add_runtime_dependency %q<future-resource>, ["~> 1.0"]
|
|
30
|
-
s.add_runtime_dependency %q<has-guarded-handlers>, ["~> 1.
|
|
30
|
+
s.add_runtime_dependency %q<has-guarded-handlers>, ["~> 1.5"]
|
|
31
31
|
s.add_runtime_dependency %q<celluloid>, ["~> 0.12", ">= 0.12.3"]
|
|
32
32
|
s.add_runtime_dependency %q<ruby_ami>, ["~> 1.2", ">= 1.2.1"]
|
|
33
33
|
s.add_runtime_dependency %q<ruby_fs>, ["~> 1.0"]
|
|
@@ -38,7 +38,6 @@ Gem::Specification.new do |s|
|
|
|
38
38
|
s.add_development_dependency %q<ci_reporter>, ["~> 1.6"]
|
|
39
39
|
s.add_development_dependency %q<yard>, ["~> 0.6"]
|
|
40
40
|
s.add_development_dependency %q<rake>, [">= 0"]
|
|
41
|
-
s.add_development_dependency %q<mocha>, [">= 0"]
|
|
42
41
|
s.add_development_dependency %q<i18n>, [">= 0"]
|
|
43
42
|
s.add_development_dependency %q<countdownlatch>, [">= 0"]
|
|
44
43
|
s.add_development_dependency %q<guard-rspec>
|
|
@@ -12,6 +12,13 @@ module Punchblock
|
|
|
12
12
|
subject << component
|
|
13
13
|
subject.find_by_id(component_id).should be component
|
|
14
14
|
end
|
|
15
|
+
|
|
16
|
+
it 'should allow deletion of components' do
|
|
17
|
+
subject << component
|
|
18
|
+
subject.find_by_id(component_id).should be component
|
|
19
|
+
subject.delete component
|
|
20
|
+
subject.find_by_id(component_id).should be_nil
|
|
21
|
+
end
|
|
15
22
|
end
|
|
16
23
|
end
|
|
17
24
|
end
|
|
@@ -13,27 +13,27 @@ module Punchblock
|
|
|
13
13
|
its(:component_registry) { should be_a Client::ComponentRegistry }
|
|
14
14
|
|
|
15
15
|
let(:call_id) { 'abc123' }
|
|
16
|
-
let(:mock_event) {
|
|
16
|
+
let(:mock_event) { stub('Event').as_null_object }
|
|
17
17
|
let(:component_id) { 'abc123' }
|
|
18
18
|
let(:mock_component) { stub 'Component', :component_id => component_id }
|
|
19
19
|
let(:mock_command) { stub 'Command' }
|
|
20
20
|
|
|
21
21
|
describe '#run' do
|
|
22
22
|
it 'should start up the connection' do
|
|
23
|
-
connection.
|
|
23
|
+
connection.should_receive(:run).once
|
|
24
24
|
subject.run
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
describe '#stop' do
|
|
29
29
|
it 'should stop the connection' do
|
|
30
|
-
connection.
|
|
30
|
+
connection.should_receive(:stop).once
|
|
31
31
|
subject.stop
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it 'should handle connection events' do
|
|
36
|
-
subject.
|
|
36
|
+
subject.should_receive(:handle_event).with(mock_event).once
|
|
37
37
|
connection.event_handler.call mock_event
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -46,8 +46,8 @@ module Punchblock
|
|
|
46
46
|
|
|
47
47
|
context 'if the event can be associated with a source component' do
|
|
48
48
|
before do
|
|
49
|
-
mock_event.
|
|
50
|
-
mock_component.
|
|
49
|
+
mock_event.stub :source => mock_component
|
|
50
|
+
mock_component.should_receive(:add_event).with mock_event
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it 'should not queue up the event' do
|
|
@@ -57,23 +57,25 @@ module Punchblock
|
|
|
57
57
|
|
|
58
58
|
it 'should not call event handlers' do
|
|
59
59
|
handler = mock 'handler'
|
|
60
|
-
handler.
|
|
60
|
+
handler.should_receive(:call).never
|
|
61
61
|
subject.register_event_handler do |event|
|
|
62
62
|
handler.call event
|
|
63
|
-
throw :halt
|
|
64
63
|
end
|
|
65
64
|
subject.handle_event mock_event
|
|
66
65
|
end
|
|
67
66
|
end
|
|
68
67
|
|
|
69
68
|
context 'if the event cannot be associated with a source component' do
|
|
69
|
+
before do
|
|
70
|
+
mock_event.stub :source => nil
|
|
71
|
+
end
|
|
72
|
+
|
|
70
73
|
context 'if event handlers have been set' do
|
|
71
74
|
it 'should call the event handler and not queue up the event' do
|
|
72
75
|
handler = mock 'handler'
|
|
73
|
-
handler.
|
|
76
|
+
handler.should_receive(:call).once.with mock_event
|
|
74
77
|
subject.register_event_handler do |event|
|
|
75
78
|
handler.call event
|
|
76
|
-
throw :halt
|
|
77
79
|
end
|
|
78
80
|
subject.handle_event mock_event
|
|
79
81
|
subject.event_queue.should be_empty
|
|
@@ -99,7 +101,7 @@ module Punchblock
|
|
|
99
101
|
let(:event) { Event::Complete.new }
|
|
100
102
|
|
|
101
103
|
before do
|
|
102
|
-
connection.
|
|
104
|
+
connection.should_receive(:write).once.with component, :call_id => call_id
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
let :execute_command do
|
|
@@ -116,7 +118,7 @@ module Punchblock
|
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
it "should handle a component's events" do
|
|
119
|
-
subject.
|
|
121
|
+
subject.should_receive(:trigger_handler).with(:event, event).once
|
|
120
122
|
execute_command
|
|
121
123
|
component.request!
|
|
122
124
|
component.execute!
|
|
@@ -70,12 +70,12 @@ module Punchblock
|
|
|
70
70
|
|
|
71
71
|
describe "#response=" do
|
|
72
72
|
it "should set the command to executing status" do
|
|
73
|
-
subject.
|
|
73
|
+
subject.should_receive(:execute!).once
|
|
74
74
|
subject.response = :foo
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
it "should be a no-op if the response has already been set" do
|
|
78
|
-
subject.
|
|
78
|
+
subject.should_receive(:execute!).once
|
|
79
79
|
subject.response = :foo
|
|
80
80
|
lambda { subject.response = :bar }.should_not raise_error
|
|
81
81
|
end
|
|
@@ -28,7 +28,7 @@ module Punchblock
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it "should call #complete!" do
|
|
31
|
-
subject.
|
|
31
|
+
subject.should_receive(:complete!).once
|
|
32
32
|
add_event
|
|
33
33
|
end
|
|
34
34
|
end
|
|
@@ -55,7 +55,7 @@ module Punchblock
|
|
|
55
55
|
let(:handler) { mock 'Response' }
|
|
56
56
|
|
|
57
57
|
before do
|
|
58
|
-
handler.
|
|
58
|
+
handler.should_receive(:call).once.with(event)
|
|
59
59
|
subject.register_event_handler { |event| handler.call event }
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -89,7 +89,9 @@ module Punchblock
|
|
|
89
89
|
describe "#complete_event=" do
|
|
90
90
|
before do
|
|
91
91
|
subject.request!
|
|
92
|
-
subject.
|
|
92
|
+
subject.client = Client.new
|
|
93
|
+
subject.response = Ref.new id: 'abc'
|
|
94
|
+
subject.client.find_component_by_id('abc').should be subject
|
|
93
95
|
end
|
|
94
96
|
|
|
95
97
|
it "should set the command to executing status" do
|
|
@@ -102,6 +104,11 @@ module Punchblock
|
|
|
102
104
|
lambda { subject.complete_event = :bar }.should_not raise_error
|
|
103
105
|
subject.complete_event(0.5).should be == :foo
|
|
104
106
|
end
|
|
107
|
+
|
|
108
|
+
it "should remove the component from the registry" do
|
|
109
|
+
subject.complete_event = :foo
|
|
110
|
+
subject.client.find_component_by_id('abc').should be_nil
|
|
111
|
+
end
|
|
105
112
|
end
|
|
106
113
|
end # ComponentNode
|
|
107
114
|
end # Component
|
|
@@ -163,7 +163,7 @@ module Punchblock
|
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
it "should send its command properly" do
|
|
166
|
-
mock_client.
|
|
166
|
+
mock_client.should_receive(:execute_command).with(command.stop_action, :target_call_id => '123abc', :component_id => 'abc123')
|
|
167
167
|
command.stop!
|
|
168
168
|
end
|
|
169
169
|
end
|