punchblock 1.8.2 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +8 -0
  4. data/lib/punchblock/component/asterisk/agi/command.rb +0 -11
  5. data/lib/punchblock/connection/asterisk.rb +3 -3
  6. data/lib/punchblock/translator/asterisk/agi_command.rb +40 -0
  7. data/lib/punchblock/translator/asterisk/call.rb +56 -47
  8. data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +13 -37
  9. data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +24 -41
  10. data/lib/punchblock/translator/asterisk/component/input.rb +2 -1
  11. data/lib/punchblock/translator/asterisk/component/output.rb +16 -21
  12. data/lib/punchblock/translator/asterisk/component/record.rb +11 -19
  13. data/lib/punchblock/translator/asterisk/component.rb +12 -9
  14. data/lib/punchblock/translator/asterisk.rb +16 -22
  15. data/lib/punchblock/translator/dtmf_recognizer.rb +4 -4
  16. data/lib/punchblock/translator/freeswitch/component/input.rb +2 -1
  17. data/lib/punchblock/translator/input_component.rb +2 -2
  18. data/lib/punchblock/version.rb +1 -1
  19. data/punchblock.gemspec +1 -1
  20. data/spec/punchblock/connection/asterisk_spec.rb +8 -7
  21. data/spec/punchblock/translator/asterisk/call_spec.rb +262 -229
  22. data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +57 -29
  23. data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +40 -46
  24. data/spec/punchblock/translator/asterisk/component/input_spec.rb +7 -7
  25. data/spec/punchblock/translator/asterisk/component/output_spec.rb +84 -53
  26. data/spec/punchblock/translator/asterisk/component/record_spec.rb +55 -83
  27. data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +5 -1
  28. data/spec/punchblock/translator/asterisk/component_spec.rb +2 -10
  29. data/spec/punchblock/translator/asterisk_spec.rb +73 -100
  30. metadata +5 -10
@@ -17,7 +17,6 @@ module Punchblock
17
17
  include DeadActorSafety
18
18
 
19
19
  attr_reader :id, :call, :call_id
20
- attr_accessor :internal
21
20
 
22
21
  def initialize(component_node, call = nil)
23
22
  @component_node, @call = component_node, call
@@ -34,7 +33,7 @@ module Punchblock
34
33
  command.response = ProtocolError.new.setup 'command-not-acceptable', "Did not understand command for component #{id}", call_id, id
35
34
  end
36
35
 
37
- def send_complete_event(reason, recording = nil)
36
+ def send_complete_event(reason, recording = nil, should_terminate = true)
38
37
  return if @complete
39
38
  @complete = true
40
39
  event = Punchblock::Event::Complete.new.tap do |c|
@@ -42,17 +41,13 @@ module Punchblock
42
41
  c << recording if recording
43
42
  end
44
43
  send_event event
45
- terminate
44
+ terminate if should_terminate
46
45
  end
47
46
 
48
47
  def send_event(event)
49
48
  event.component_id = id
50
49
  event.target_call_id = call_id
51
- if internal
52
- @component_node.add_event event
53
- else
54
- safe_from_dead_actors { translator.handle_pb_event event }
55
- end
50
+ safe_from_dead_actors { translator.handle_pb_event event }
56
51
  end
57
52
 
58
53
  def logger_id
@@ -66,7 +61,11 @@ module Punchblock
66
61
  private
67
62
 
68
63
  def translator
69
- call.translator
64
+ @translator ||= call.translator
65
+ end
66
+
67
+ def ami_client
68
+ translator.ami_client
70
69
  end
71
70
 
72
71
  def set_node_response(value)
@@ -80,6 +79,10 @@ module Punchblock
80
79
  def with_error(name, text)
81
80
  set_node_response ProtocolError.new.setup(name, text)
82
81
  end
82
+
83
+ def complete_with_error(error)
84
+ send_complete_event Punchblock::Event::Complete::Error.new(details: error)
85
+ end
83
86
  end
84
87
  end
85
88
  end
@@ -10,6 +10,7 @@ module Punchblock
10
10
 
11
11
  extend ActiveSupport::Autoload
12
12
 
13
+ autoload :AGICommand
13
14
  autoload :Call
14
15
  autoload :Component
15
16
 
@@ -65,12 +66,8 @@ module Punchblock
65
66
  return unless event.is_a? RubyAMI::Event
66
67
 
67
68
  if event.name.downcase == "fullybooted"
68
- @fully_booted_count += 1
69
- if @fully_booted_count >= 2
70
- handle_pb_event Connection::Connected.new
71
- @fully_booted_count = 0
72
- run_at_fully_booted
73
- end
69
+ handle_pb_event Connection::Connected.new
70
+ run_at_fully_booted
74
71
  return
75
72
  end
76
73
 
@@ -122,11 +119,11 @@ module Punchblock
122
119
  def execute_global_command(command)
123
120
  case command
124
121
  when Punchblock::Component::Asterisk::AMI::Action
125
- component = Component::Asterisk::AMIAction.new command, current_actor
122
+ component = Component::Asterisk::AMIAction.new command, current_actor, ami_client
126
123
  register_component component
127
124
  component.async.execute
128
125
  when Punchblock::Command::Dial
129
- call = Call.new_link command.to, current_actor
126
+ call = Call.new_link command.to, current_actor, ami_client, connection
130
127
  register_call call
131
128
  call.async.dial command
132
129
  else
@@ -134,21 +131,14 @@ module Punchblock
134
131
  end
135
132
  end
136
133
 
137
- def send_ami_action(name, headers = {}, &block)
138
- ami_client.send_action name, headers, &block
139
- end
140
-
141
134
  def run_at_fully_booted
142
- send_ami_action('Command', {
143
- 'Command' => "dialplan add extension #{REDIRECT_EXTENSION},#{REDIRECT_PRIORITY},AGI,agi:async into #{REDIRECT_CONTEXT}"
144
- })
145
- send_ami_action('Command', {
146
- 'Command' => "dialplan show #{REDIRECT_CONTEXT}"
147
- }) do |result|
148
- if result.text_body =~ /failed/
149
- pb_logger.error "Punchblock failed to add the #{REDIRECT_EXTENSION} extension to the #{REDIRECT_CONTEXT} context. Please add a [#{REDIRECT_CONTEXT}] entry to your dialplan."
150
- end
135
+ send_ami_action 'Command', 'Command' => "dialplan add extension #{REDIRECT_EXTENSION},#{REDIRECT_PRIORITY},AGI,agi:async into #{REDIRECT_CONTEXT}"
136
+
137
+ result = send_ami_action 'Command', 'Command' => "dialplan show #{REDIRECT_CONTEXT}"
138
+ if result.text_body =~ /failed/
139
+ pb_logger.error "Punchblock failed to add the #{REDIRECT_EXTENSION} extension to the #{REDIRECT_CONTEXT} context. Please add a [#{REDIRECT_CONTEXT}] entry to your dialplan."
151
140
  end
141
+
152
142
  check_recording_directory
153
143
  end
154
144
 
@@ -168,6 +158,10 @@ module Punchblock
168
158
 
169
159
  private
170
160
 
161
+ def send_ami_action(name, headers = {})
162
+ ami_client.send_action name, headers
163
+ end
164
+
171
165
  def handle_varset_ami_event(event)
172
166
  return unless event.name == 'VarSet' && event['Variable'] == 'punchblock_call_id' && (call = call_with_id event['Value'])
173
167
 
@@ -213,7 +207,7 @@ module Punchblock
213
207
 
214
208
  return if env[:agi_extension] == 'h' || env[:agi_type] == 'Kill'
215
209
 
216
- call = Call.new event['Channel'], current_actor, env
210
+ call = Call.new event['Channel'], current_actor, ami_client, connection, env
217
211
  link call
218
212
  register_call call
219
213
  call.async.send_offer
@@ -3,10 +3,6 @@
3
3
  module Punchblock
4
4
  module Translator
5
5
  class DTMFRecognizer
6
- include Celluloid
7
-
8
- finalizer :finalize
9
-
10
6
  def initialize(responder, grammar, initial_timeout = nil, inter_digit_timeout = nil)
11
7
  @responder = responder
12
8
  self.grammar = grammar
@@ -45,6 +41,10 @@ module Punchblock
45
41
  @grammar.normalize_whitespace
46
42
  end
47
43
 
44
+ def after(*args, &block)
45
+ @responder.after *args, &block
46
+ end
47
+
48
48
  def initial_timeout=(other)
49
49
  raise OptionError, 'An initial timeout value that is negative (and not -1) is invalid.' if other < -1
50
50
  @initial_timeout = other
@@ -11,9 +11,10 @@ module Punchblock
11
11
  private
12
12
 
13
13
  def register_dtmf_event_handler
14
+ component = current_actor
14
15
  call.register_handler :es, :event_name => 'DTMF' do |event|
15
16
  safe_from_dead_actors do
16
- @recognizer << event[:dtmf_digit]
17
+ component.process_dtmf event[:dtmf_digit]
17
18
  end
18
19
  end
19
20
  end
@@ -6,8 +6,7 @@ module Punchblock
6
6
  def execute
7
7
  validate
8
8
 
9
- component = current_actor
10
- @recognizer = DTMFRecognizer.new current_actor,
9
+ @recognizer = DTMFRecognizer.new self,
11
10
  @component_node.grammar.value,
12
11
  (@component_node.initial_timeout || -1),
13
12
  (@component_node.inter_digit_timeout || -1)
@@ -54,6 +53,7 @@ module Punchblock
54
53
 
55
54
  def complete(reason)
56
55
  unregister_dtmf_event_handler
56
+ @recognizer.finalize if @recognizer
57
57
  send_complete_event reason
58
58
  end
59
59
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Punchblock
4
- VERSION = "1.8.2"
4
+ VERSION = "1.9.0"
5
5
  end
data/punchblock.gemspec CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  s.add_runtime_dependency %q<future-resource>, ["~> 1.0"]
31
31
  s.add_runtime_dependency %q<has-guarded-handlers>, ["~> 1.5"]
32
32
  s.add_runtime_dependency %q<celluloid>, ["~> 0.13"]
33
- s.add_runtime_dependency %q<ruby_ami>, ["~> 1.2", ">= 1.2.1"]
33
+ s.add_runtime_dependency %q<ruby_ami>, ["~> 2.0"]
34
34
  s.add_runtime_dependency %q<ruby_fs>, ["~> 1.0"]
35
35
  s.add_runtime_dependency %q<ruby_speech>, ["~> 1.0"]
36
36
 
@@ -25,7 +25,7 @@ module Punchblock
25
25
  subject.event_handler = mock_event_handler
26
26
  end
27
27
 
28
- its(:ami_client) { should be_a RubyAMI::Client }
28
+ its(:ami_client) { should be_a RubyAMI::Stream }
29
29
 
30
30
  it 'should set the connection on the translator' do
31
31
  subject.translator.connection.should be subject
@@ -36,15 +36,15 @@ module Punchblock
36
36
  end
37
37
 
38
38
  describe '#run' do
39
- it 'starts the RubyAMI::Client' do
40
- subject.ami_client.should_receive(:start).once
39
+ it 'starts the RubyAMI::Stream' do
40
+ subject.ami_client.should_receive(:run).once
41
41
  lambda { subject.run }.should raise_error DisconnectedError
42
42
  end
43
43
  end
44
44
 
45
45
  describe '#stop' do
46
- it 'stops the RubyAMI::Client' do
47
- subject.ami_client.should_receive(:stop).once
46
+ it 'stops the RubyAMI::Stream' do
47
+ subject.ami_client.should_receive(:terminate).once
48
48
  subject.stop
49
49
  end
50
50
 
@@ -55,9 +55,10 @@ module Punchblock
55
55
  end
56
56
 
57
57
  it 'sends events from RubyAMI to the translator' do
58
- event = mock 'RubyAMI::Event'
58
+ event = RubyAMI::Event.new 'FullyBooted'
59
59
  subject.translator.async.should_receive(:handle_ami_event).once.with event
60
- subject.ami_client.handle_event event
60
+ subject.translator.async.should_receive(:handle_ami_event).once.with RubyAMI::Stream::Disconnected.new
61
+ subject.ami_client.message_received event
61
62
  end
62
63
 
63
64
  describe '#write' do