adhearsion 2.3.5 → 2.4.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +2 -0
  5. data/README.markdown +21 -2
  6. data/adhearsion.gemspec +5 -4
  7. data/features/cli_plugin.feature +41 -0
  8. data/features/cli_start.feature +12 -4
  9. data/features/step_definitions/cli_steps.rb +12 -0
  10. data/features/support/env.rb +1 -1
  11. data/features/support/utils.rb +0 -1
  12. data/lib/adhearsion.rb +4 -1
  13. data/lib/adhearsion/call.rb +92 -22
  14. data/lib/adhearsion/call_controller.rb +19 -15
  15. data/lib/adhearsion/call_controller/dial.rb +157 -25
  16. data/lib/adhearsion/call_controller/menu_dsl/menu_builder.rb +8 -0
  17. data/lib/adhearsion/call_controller/output/async_player.rb +1 -1
  18. data/lib/adhearsion/call_controller/output/formatter.rb +1 -1
  19. data/lib/adhearsion/call_controller/output/player.rb +1 -1
  20. data/lib/adhearsion/calls.rb +2 -0
  21. data/lib/adhearsion/cli_commands.rb +3 -163
  22. data/lib/adhearsion/cli_commands/ahn_command.rb +141 -0
  23. data/lib/adhearsion/cli_commands/plugin_command.rb +74 -0
  24. data/lib/adhearsion/cli_commands/thor_errors.rb +36 -0
  25. data/lib/adhearsion/console.rb +14 -6
  26. data/lib/adhearsion/generators/app/templates/spec/call_controllers/simon_game_spec.rb +36 -36
  27. data/lib/adhearsion/generators/controller/templates/spec/controller_spec.rb +1 -1
  28. data/lib/adhearsion/generators/plugin/templates/plugin-template.gemspec.tt +0 -1
  29. data/lib/adhearsion/generators/plugin/templates/spec/plugin-template/controller_methods_spec.rb.tt +1 -1
  30. data/lib/adhearsion/generators/plugin/templates/spec/spec_helper.rb.tt +0 -1
  31. data/lib/adhearsion/logging.rb +5 -1
  32. data/lib/adhearsion/outbound_call.rb +16 -0
  33. data/lib/adhearsion/punchblock_plugin.rb +0 -2
  34. data/lib/adhearsion/punchblock_plugin/initializer.rb +7 -12
  35. data/lib/adhearsion/version.rb +1 -1
  36. data/spec/adhearsion/call_controller/dial_spec.rb +785 -32
  37. data/spec/adhearsion/call_controller/menu_dsl/menu_builder_spec.rb +10 -0
  38. data/spec/adhearsion/call_controller/output/async_player_spec.rb +1 -1
  39. data/spec/adhearsion/call_controller/output/player_spec.rb +1 -1
  40. data/spec/adhearsion/call_controller/output_spec.rb +3 -3
  41. data/spec/adhearsion/call_controller/record_spec.rb +1 -1
  42. data/spec/adhearsion/call_controller_spec.rb +13 -9
  43. data/spec/adhearsion/call_spec.rb +216 -51
  44. data/spec/adhearsion/calls_spec.rb +1 -1
  45. data/spec/adhearsion/console_spec.rb +20 -9
  46. data/spec/adhearsion/outbound_call_spec.rb +40 -6
  47. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +9 -21
  48. data/spec/adhearsion/punchblock_plugin_spec.rb +1 -1
  49. data/spec/adhearsion/router_spec.rb +1 -1
  50. data/spec/spec_helper.rb +11 -15
  51. data/spec/support/call_controller_test_helpers.rb +2 -2
  52. data/spec/support/punchblock_mocks.rb +2 -2
  53. metadata +41 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce13923a79ebf09d66a57ac08187110885e8ab19
4
- data.tar.gz: 893aa45657fc58b288d44693b60afbe493449997
3
+ metadata.gz: 0e1b64f1b1643fc319f4203fbf8e6cf2452c444d
4
+ data.tar.gz: f533f739a9536421599852a4f049407b287b30b1
5
5
  SHA512:
6
- metadata.gz: 54bc58e3bef695e4a2edcdc29d15833ce9a5954fc8c0dabab4fd7fc35f3bfac52f74c09ad5ed591242740c53553af1728441288143b7d3028d1edafae7f1629b
7
- data.tar.gz: 0173249d5786ffdcf9e96884ec6b271e97b3f1cfacfd9c3674b392e0d73edb4379c163ab62d7d29bc03686a71c69a4c677387bc5466b1001b2ce246a4152a96c
6
+ metadata.gz: bb6cad9f60e451a309f4e98b5cdb61e19835032e44f053cba58598b9dc4b188abc1d089802d9c596566c3ebdc107e2fec1d61e5a4e26c5f0bfca24bb6f6e5ed8
7
+ data.tar.gz: 803b943cbebf981da00a580e46151dad0fc86bb188ccb89171e759461cbb03f889355c159e9b9ad67f77a2d5bb149717e85ae10ff96428128bdbff43aff528f5
@@ -10,7 +10,6 @@ matrix:
10
10
  allow_failures:
11
11
  - rvm: rbx-19mode
12
12
  - rvm: ruby-head
13
- - rvm: jruby-19mode
14
13
  env: ARUBA_TIMEOUT=120 RAILS_ENV=development AHN_ENV=development
15
14
  notifications:
16
15
  irc: "irc.freenode.org#adhearsion"
@@ -1,5 +1,19 @@
1
1
  # [develop](https://github.com/adhearsion/adhearsion)
2
2
 
3
+ # [2.4.0.beta1](https://github.com/adhearsion/adhearsion/compare/v2.3.5...v2.4.0.beta1) - [2013-08-20](https://rubygems.org/gems/adhearsion/versions/2.4.0.beta1)
4
+ * Feature: Add Call#wait_for_end, which blocks until the call ends and returns its end reason
5
+ * Feature: Add joined call attribute to dial status
6
+ * Feature: Track call start/end time and duration
7
+ * Feature: Add per-call join duration and disposition to DialStatus
8
+ * Feature: Add `CallController#dial_and_confirm` which allows parallel confirmation of outbound calls
9
+ * Feature: Add `#originate` method to console as alias for `Adhearsion::OutboundCall.originate`
10
+ * Feature: Allow the console to be disabled using `--no-console`
11
+ * Feature: Add CLI options to generate hooks for a plugin to register on [ahnhub.com](http://www.ahnhub.com)
12
+ * Bugfix: Removed unnecessary Mocha reference from generated plugin
13
+ * Bugfix: Call loggers should be deleted after a call finishes
14
+ * Bugfix: A menu definition's block context is now available
15
+ * Bugfix: Ensure call's command registry is not leaked outside the actor
16
+
3
17
  # [2.3.5](https://github.com/adhearsion/adhearsion/compare/v2.3.4...v2.3.5) - [2013-06-06](https://rubygems.org/gems/adhearsion/versions/2.3.5)
4
18
  * Bugfix: Fix race conditions in barging in before output start is acknowledged
5
19
  * Performance enhancement: Use Celluloid's thread pool for call controller threads to reduce thread setup overhead
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ gem 'activesupport', '~> 3.0' if RUBY_VERSION == "1.9.2"
@@ -1,3 +1,9 @@
1
+ [![Gem Version](https://badge.fury.io/rb/adhearsion.png)](https://rubygems.org/gems/adhearsion)
2
+ [![Build Status](https://secure.travis-ci.org/adhearsion/adhearsion.png?branch=develop)](http://travis-ci.org/adhearsion/adhearsion)
3
+ [![Dependency Status](https://gemnasium.com/adhearsion/adhearsion.png?travis)](https://gemnasium.com/adhearsion/adhearsion)
4
+ [![Code Climate](https://codeclimate.com/github/adhearsion/adhearsion.png)](https://codeclimate.com/github/adhearsion/adhearsion)
5
+ [![Coverage Status](https://coveralls.io/repos/adhearsion/adhearsion/badge.png?branch=develop)](https://coveralls.io/r/adhearsion/adhearsion)
6
+
1
7
  # Adhearsion
2
8
 
3
9
  Adhearsion is an open-source voice application development framework. Adhearsion users write applications atop the framework with Ruby and **call into their code**.
@@ -24,6 +30,12 @@ Adhearsion rests above a lower-level telephony platform, for example [Asterisk](
24
30
  * Prism 11+ with rayo-server
25
31
  * An interest in building cool new things
26
32
 
33
+ \* Support for Ruby 1.9.2 is deprecated, and requires locking your application to ActiveSupport 3.x as follows:
34
+
35
+ ```ruby
36
+ gem 'active_support', '~> 3.0'
37
+ ```
38
+
27
39
  ## Install
28
40
 
29
41
  `gem install adhearsion`
@@ -47,7 +59,14 @@ Visit [Adhearsion's website](http://adhearsion.com) for code examples and more i
47
59
 
48
60
  If you're having trouble, you may want to try asking your question on the IRC channel (#adhearsion on irc.freenode.net), [mailing list](http://groups.google.com/group/adhearsion) or, if you've found a bug, report it on the [bug tracker](https://github.com/adhearsion/adhearsion/issues).
49
61
 
50
- ## Author
62
+ ## Related Projects
63
+
64
+ These Open Source projects are also maintained by members of the Adhearsion team and may be useful when developing Adhearsion apps:
65
+
66
+ * [Telephony-Dev-Box](https://github.com/mojolingo/Telephony-Dev-Box) is a system for creating virtual machines that will preconfigure Adhearsion, Asterisk, FreeSWITCH and PRISM together. Just add a SIP client and start calling your app!
67
+ * [SippyCup](https://github.com/bklang/sippy_cup) makes generating [SIPp](http://sipp.sourceforge.net/) profiles and RTP media easy. Useful for load testing your apps and telephony infrastructure.
68
+
69
+ ## Authors
51
70
 
52
71
  Core team:
53
72
 
@@ -66,4 +85,4 @@ There is a pre-commit hook that runs encoding checks available in pre-commit. To
66
85
 
67
86
  ### Copyright
68
87
 
69
- Copyright (c) 2013 Adhearsion Foundation Inc. MIT LICENSE (see LICENSE for details).
88
+ Copyright (c) 2011-2013 Adhearsion Foundation Inc. MIT LICENSE (see LICENSE for details).
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
19
 
20
- s.add_runtime_dependency 'activesupport', ["~> 3.0"]
20
+ s.add_runtime_dependency 'activesupport', [">= 3.0.0", "< 5.0.0"]
21
21
  s.add_runtime_dependency 'adhearsion-loquacious', ["~> 1.9"]
22
22
  s.add_runtime_dependency 'bundler', ["~> 1.0"]
23
23
  s.add_runtime_dependency 'celluloid', ["~> 0.14"]
@@ -29,9 +29,9 @@ Gem::Specification.new do |s|
29
29
  s.add_runtime_dependency 'jruby-openssl' if RUBY_PLATFORM == 'java'
30
30
  s.add_runtime_dependency 'logging', ["~> 1.8"]
31
31
  s.add_runtime_dependency 'pry'
32
- s.add_runtime_dependency 'punchblock', ["~> 1.4"]
32
+ s.add_runtime_dependency 'punchblock', ["~> 2.0.0.beta1"]
33
33
  s.add_runtime_dependency 'rake'
34
- s.add_runtime_dependency 'ruby_speech', ["~> 1.0"]
34
+ s.add_runtime_dependency 'ruby_speech', ["~> 2.0"]
35
35
  s.add_runtime_dependency 'thor', "~> 0.18.0"
36
36
 
37
37
  s.add_development_dependency 'aruba', "~> 0.5"
@@ -40,8 +40,9 @@ Gem::Specification.new do |s|
40
40
  s.add_development_dependency 'guard-cucumber'
41
41
  s.add_development_dependency 'guard-rspec'
42
42
  s.add_development_dependency 'rspec', ["~> 2.11"]
43
- s.add_development_dependency 'ruby_gntp'
44
43
  s.add_development_dependency 'simplecov'
45
44
  s.add_development_dependency 'simplecov-rcov'
46
45
  s.add_development_dependency 'yard'
46
+ s.add_development_dependency 'coveralls'
47
+ s.add_development_dependency 'timecop'
47
48
  end
@@ -0,0 +1,41 @@
1
+ Feature: Adhearsion Ahn CLI (Plugin)
2
+ As an Adhearsion user
3
+ I want a cli command (ahn plugin)
4
+ So that I can perform actions for adhearsion plugins
5
+
6
+ Scenario: No arguments given
7
+ When I run `ahn plugin`
8
+ Then I should see the plugin usage message
9
+ And the exit status should be 0
10
+
11
+ Scenario: Unrecognized commands
12
+ When I run `ahn plugin alpha beta`
13
+ Then the output should contain:
14
+ """
15
+ Could not find command "alpha"
16
+ """
17
+ And the exit status should be 1
18
+
19
+ Scenario: Command help
20
+ When I run `ahn plugin help`
21
+ Then I should see the plugin usage message
22
+ And the exit status should be 0
23
+
24
+ Scenario: Command create_rubygem_hook
25
+ When I run `ahn plugin create_rubygem_hook` interactively
26
+ And I type "foobar"
27
+ And I type "SECRET_CODE"
28
+ Then the output should contain:
29
+ """
30
+ Access Denied. Please sign up for an account at http://rubygems.org
31
+ """
32
+
33
+ Scenario: Command create_github_hook
34
+ When I run `ahn plugin create_github_hook` interactively
35
+ And I type "username"
36
+ And I type "SECRET_CODE"
37
+ And I type "adhearsion/new_plugin"
38
+ Then the output should contain:
39
+ """
40
+ {"message":
41
+ """
@@ -12,8 +12,8 @@ Feature: Adhearsion Ahn CLI (start)
12
12
  And the exit status should be 1
13
13
 
14
14
  Scenario: Command start with no path inside of the app directory
15
- Given JRuby skip test
16
- Given that I create a valid app under "path/somewhere"
15
+ Given JRuby skip test because the console causes the process to never exit
16
+ And that I create a valid app under "path/somewhere"
17
17
  When I cd to "path/somewhere"
18
18
  And I run `ahn start` interactively
19
19
  And I wait for output to contain "Starting connection to server"
@@ -21,9 +21,17 @@ Feature: Adhearsion Ahn CLI (start)
21
21
  And the output should contain "Adhearsion shut down"
22
22
 
23
23
  Scenario: Command start with only path works properly
24
- Given JRuby skip test
25
- Given that I create a valid app under "path/somewhere"
24
+ Given JRuby skip test waiting for https://jira.codehaus.org/browse/JRUBY-6994
25
+ And that I create a valid app under "path/somewhere"
26
26
  When I run `ahn start path/somewhere` interactively
27
27
  And I wait for output to contain "Starting connection to server"
28
28
  Then the output should contain "Adhearsion::Console: Launching Adhearsion Console"
29
29
  And the output should contain "Adhearsion shut down"
30
+
31
+ Scenario: Starting without the console
32
+ Given that I create a valid app under "path/somewhere"
33
+ When I cd to "path/somewhere"
34
+ And I run `ahn start --no-console` interactively
35
+ And I wait for output to contain "Starting connection to server"
36
+ Then the output should not contain "Adhearsion::Console: Launching Adhearsion Console"
37
+ And the output should contain "Adhearsion shut down"
@@ -6,10 +6,19 @@ Then /^I should see the usage message$/ do
6
6
  Then the output should contain "ahn start"
7
7
  Then the output should contain "ahn daemon"
8
8
  Then the output should contain "ahn version"
9
+ Then the output should contain "ahn plugin"
9
10
  Then the output should contain "ahn help"
10
11
  }
11
12
  end
12
13
 
14
+ Then /^I should see the plugin usage message$/ do
15
+ steps %Q{
16
+ Then the output should contain "ahn plugin create_ahnhub_hooks"
17
+ Then the output should contain "ahn plugin create_github_hook"
18
+ Then the output should contain "ahn plugin create_rubygem_hook"
19
+ }
20
+ end
21
+
13
22
  When /^I wait (\d+) seconds?$/ do |arg1|
14
23
  sleep arg1.to_i
15
24
  end
@@ -19,6 +28,8 @@ Given /^that I create a valid app under "([^"]*)"$/ do |path|
19
28
  When I run `ahn create #{path}`
20
29
  Then there should be a valid adhearsion directory named "#{path}"
21
30
  }
31
+
32
+ remove_file "#{path}/Gemfile"
22
33
  end
23
34
 
24
35
  Then /^there should be a valid adhearsion directory named "([^"]*)"$/ do |path|
@@ -55,3 +66,4 @@ When /^I terminate the process using the pid file "([^"]*)"$/ do |pidfile|
55
66
  sleep 1
56
67
  end
57
68
  end
69
+
@@ -8,7 +8,7 @@ require 'aruba/cucumber'
8
8
  require 'adhearsion'
9
9
 
10
10
  Before do
11
- @aruba_timeout_seconds = ENV['ARUBA_TIMEOUT'] || RUBY_PLATFORM == 'java' ? 60 : 30
11
+ @aruba_timeout_seconds = ENV.has_key?('ARUBA_TIMEOUT') ? ENV['ARUBA_TIMEOUT'].to_i : (RUBY_PLATFORM == 'java' ? 60 : 30)
12
12
  ENV['AHN_PUNCHBLOCK_RECONNECT_ATTEMPTS'] = '0'
13
13
  ENV['AHN_PUNCHBLOCK_PORT'] = '1'
14
14
  end
@@ -4,7 +4,6 @@ Given /^PENDING/ do
4
4
  pending
5
5
  end
6
6
 
7
-
8
7
  Given /^JRuby skip test/ do
9
8
  pending "Daemonize not supported under JRuby" if RUBY_PLATFORM == 'java'
10
9
  end
@@ -73,7 +73,10 @@ module Adhearsion
73
73
  _config = Configuration.new
74
74
  env = ENV['AHN_ENV'] || ENV['RAILS_ENV']
75
75
  env = env.to_sym if env.respond_to? :to_sym
76
- env = nil unless _config.valid_environment? env
76
+ unless _config.valid_environment? env
77
+ puts "You tried to initialize with an invalid environment name #{env}. Valid values are #{_config.valid_environments}."
78
+ env = nil
79
+ end
77
80
  _config.platform.environment = env if env
78
81
  _config
79
82
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'has_guarded_handlers'
4
4
  require 'thread'
5
+ require 'active_support/hash_with_indifferent_access'
5
6
 
6
7
  module Adhearsion
7
8
  ##
@@ -17,6 +18,7 @@ module Adhearsion
17
18
  include HasGuardedHandlers
18
19
 
19
20
  execute_block_on_receiver :register_handler, :register_tmp_handler, :register_handler_with_priority, :register_event_handler, :on_joined, :on_unjoined, :on_end, :execute_controller
21
+ finalizer :finalize
20
22
 
21
23
  def self.new(*args, &block)
22
24
  super.tap do |proxy|
@@ -28,7 +30,7 @@ module Adhearsion
28
30
  end
29
31
  end
30
32
 
31
- attr_reader :end_reason, :commands, :controllers, :variables
33
+ attr_reader :end_reason, :controllers, :variables, :start_time, :end_time
32
34
 
33
35
  delegate :[], :[]=, :to => :variables
34
36
  delegate :to, :from, :to => :offer, :allow_nil => true
@@ -39,10 +41,12 @@ module Adhearsion
39
41
  @offer = nil
40
42
  @tags = []
41
43
  @commands = CommandRegistry.new
42
- @variables = {}
44
+ @variables = HashWithIndifferentAccess.new
43
45
  @controllers = []
44
46
  @end_reason = nil
47
+ @end_blocker = Celluloid::Condition.new
45
48
  @peers = {}
49
+ @duration = nil
46
50
 
47
51
  self << offer if offer
48
52
  end
@@ -54,6 +58,25 @@ module Adhearsion
54
58
  offer.target_call_id if offer
55
59
  end
56
60
 
61
+ #
62
+ # @return [String, nil] The domain on which the call resides
63
+ #
64
+ def domain
65
+ offer.domain if offer
66
+ end
67
+
68
+ #
69
+ # @return [String, nil] The uri at which the call resides
70
+ #
71
+ def uri
72
+ return nil unless id
73
+ s = ""
74
+ s << transport << ":" if transport
75
+ s << id
76
+ s << "@" << domain if domain
77
+ s
78
+ end
79
+
57
80
  #
58
81
  # @return [Array] The set of labels with which this call has been tagged.
59
82
  #
@@ -97,6 +120,18 @@ module Adhearsion
97
120
  @peers.clone
98
121
  end
99
122
 
123
+ #
124
+ # Wait for the call to end. Returns immediately if the call has already ended, else blocks until it does so.
125
+ # @return [Symbol] the reason for the call ending
126
+ #
127
+ def wait_for_end
128
+ if end_reason
129
+ end_reason
130
+ else
131
+ @end_blocker.wait
132
+ end
133
+ end
134
+
100
135
  def register_event_handler(*guards, &block)
101
136
  register_handler :event, *guards, &block
102
137
  end
@@ -107,46 +142,65 @@ module Adhearsion
107
142
  end
108
143
  alias << deliver_message
109
144
 
145
+ def commands
146
+ @commands.clone
147
+ end
148
+
110
149
  # @private
111
150
  def register_initial_handlers
112
151
  register_event_handler Punchblock::Event::Offer do |offer|
113
152
  @offer = offer
114
153
  @client = offer.client
154
+ @start_time = Time.now
115
155
  throw :pass
116
156
  end
117
157
 
118
158
  register_event_handler Punchblock::HasHeaders do |event|
119
- variables.merge! event.headers_hash
159
+ merge_headers event.headers
120
160
  throw :pass
121
161
  end
122
162
 
123
163
  on_joined do |event|
124
- target = event.call_id || event.mixer_name
164
+ target = event.call_uri || event.mixer_name
125
165
  @peers[target] = Adhearsion.active_calls[target]
126
166
  signal :joined, target
127
167
  end
128
168
 
129
169
  on_unjoined do |event|
130
- target = event.call_id || event.mixer_name
170
+ target = event.call_uri || event.mixer_name
131
171
  @peers.delete target
132
172
  signal :unjoined, target
133
173
  end
134
174
 
135
175
  on_end do |event|
136
- logger.info "Call ended"
176
+ logger.info "Call ended due to #{event.reason}"
177
+ @end_time = Time.now
178
+ @duration = @end_time - @start_time if @start_time
137
179
  clear_from_active_calls
138
180
  @end_reason = event.reason
139
- commands.terminate
181
+ @end_blocker.broadcast event.reason
182
+ @commands.terminate
140
183
  after(Adhearsion.config.platform.after_hangup_lifetime) { terminate }
141
184
  throw :pass
142
185
  end
143
186
  end
144
187
 
188
+ # @return [Float] The call duration until the current time, or until the call was disconnected, whichever is earlier
189
+ def duration
190
+ if @duration
191
+ @duration
192
+ elsif @start_time
193
+ Time.now - @start_time
194
+ else
195
+ 0.0
196
+ end
197
+ end
198
+
145
199
  ##
146
200
  # Registers a callback for when this call is joined to another call or a mixer
147
201
  #
148
202
  # @param [Call, String, Hash, nil] target the target to guard on. May be a Call object, a call ID (String, Hash) or a mixer name (Hash)
149
- # @option target [String] call_id The call ID to guard on
203
+ # @option target [String] call_uri The call ID to guard on
150
204
  # @option target [String] mixer_name The mixer name to guard on
151
205
  #
152
206
  def on_joined(target = nil, &block)
@@ -160,7 +214,7 @@ module Adhearsion
160
214
  # Registers a callback for when this call is unjoined from another call or a mixer
161
215
  #
162
216
  # @param [Call, String, Hash, nil] target the target to guard on. May be a Call object, a call ID (String, Hash) or a mixer name (Hash)
163
- # @option target [String] call_id The call ID to guard on
217
+ # @option target [String] call_uri The call ID to guard on
164
218
  # @option target [String] mixer_name The mixer name to guard on
165
219
  #
166
220
  def on_unjoined(target = nil, &block)
@@ -218,7 +272,7 @@ module Adhearsion
218
272
  # Joins this call to another call or a mixer
219
273
  #
220
274
  # @param [Call, String, Hash] target the target to join to. May be a Call object, a call ID (String, Hash) or a mixer name (Hash)
221
- # @option target [String] call_id The call ID to join to
275
+ # @option target [String] call_uri The call ID to join to
222
276
  # @option target [String] mixer_name The mixer to join to
223
277
  # @param [Hash, Optional] options further options to be joined with
224
278
  #
@@ -231,7 +285,7 @@ module Adhearsion
231
285
  # Unjoins this call from another call or a mixer
232
286
  #
233
287
  # @param [Call, String, Hash] target the target to unjoin from. May be a Call object, a call ID (String, Hash) or a mixer name (Hash)
234
- # @option target [String] call_id The call ID to unjoin from
288
+ # @option target [String] call_uri The call ID to unjoin from
235
289
  # @option target [String] mixer_name The mixer to unjoin from
236
290
  #
237
291
  def unjoin(target)
@@ -243,11 +297,11 @@ module Adhearsion
243
297
  def join_options_with_target(target)
244
298
  case target
245
299
  when Call
246
- { :call_id => target.id }
300
+ { :call_uri => target.uri }
247
301
  when String
248
- { :call_id => target }
302
+ { :call_uri => "#{transport}:#{target}@#{domain}" }
249
303
  when Hash
250
- abort ArgumentError.new "You cannot specify both a call ID and mixer name" if target.has_key?(:call_id) && target.has_key?(:mixer_name)
304
+ abort ArgumentError.new "You cannot specify both a call URI and mixer name" if target.has_key?(:call_uri) && target.has_key?(:mixer_name)
251
305
  target
252
306
  else
253
307
  abort ArgumentError.new "Don't know how to join to #{target.inspect}"
@@ -278,10 +332,11 @@ module Adhearsion
278
332
 
279
333
  # @private
280
334
  def write_and_await_response(command, timeout = 60)
281
- commands << command
335
+ @commands << command
282
336
  write_command command
283
337
 
284
- case (response = command.response timeout)
338
+ response = defer { command.response timeout }
339
+ case response
285
340
  when Punchblock::ProtocolError
286
341
  if response.name == :item_not_found
287
342
  abort Hangup.new(@end_reason)
@@ -295,21 +350,22 @@ module Adhearsion
295
350
  command
296
351
  rescue Timeout::Error
297
352
  abort CommandTimeout.new(command.to_s)
353
+ ensure
354
+ @commands.delete command
298
355
  end
299
356
 
300
357
  # @private
301
358
  def write_command(command)
302
359
  abort Hangup.new(@end_reason) unless active? || command.is_a?(Punchblock::Command::Hangup)
303
- variables.merge! command.headers_hash if command.respond_to? :headers_hash
360
+ merge_headers command.headers if command.respond_to? :headers
304
361
  logger.debug "Executing command #{command.inspect}"
305
- client.execute_command command, :call_id => id, :async => true
362
+ client.execute_command command, call_id: id, domain: domain, async: true
306
363
  end
307
364
 
308
365
  # @private
309
366
  def logger_id
310
- "#{self.class}: #{id}"
367
+ "#{self.class}: #{id}@#{domain}"
311
368
  end
312
-
313
369
  # @private
314
370
  def to_ary
315
371
  [current_actor]
@@ -320,7 +376,7 @@ module Adhearsion
320
376
  attrs = [:offer, :end_reason, :commands, :variables, :controllers, :to, :from].map do |attr|
321
377
  "#{attr}=#{send(attr).inspect}"
322
378
  end
323
- "#<#{self.class}:#{id} #{attrs.join ', '}>"
379
+ "#<#{self.class}:#{id}@#{domain} #{attrs.join ', '}>"
324
380
  end
325
381
 
326
382
  def execute_controller(controller = nil, completion_callback = nil, &block)
@@ -355,8 +411,22 @@ module Adhearsion
355
411
  @client
356
412
  end
357
413
 
414
+ def transport
415
+ offer.transport if offer
416
+ end
417
+
418
+ def merge_headers(headers)
419
+ headers.each do |name, value|
420
+ variables[name.to_s.downcase.gsub('-', '_')] = value
421
+ end
422
+ end
423
+
424
+ def finalize
425
+ ::Logging::Repository.instance.delete logger_id
426
+ end
427
+
358
428
  # @private
359
- class CommandRegistry < ThreadSafeArray
429
+ class CommandRegistry < Array
360
430
  def terminate
361
431
  hangup = Hangup.new
362
432
  each { |command| command.response = hangup if command.requested? }