adhearsion 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/CHANGELOG.md +29 -0
- data/Gemfile +0 -2
- data/Guardfile +2 -2
- data/README.markdown +3 -6
- data/Rakefile +1 -1
- data/adhearsion.gemspec +7 -2
- data/features/cli_create.feature +85 -7
- data/features/plugin_generator.feature +4 -0
- data/features/step_definitions/app_generator_steps.rb +8 -1
- data/lib/adhearsion.rb +6 -3
- data/lib/adhearsion/call.rb +101 -30
- data/lib/adhearsion/call_controller.rb +40 -12
- data/lib/adhearsion/call_controller/dial.rb +119 -36
- data/lib/adhearsion/call_controller/input.rb +11 -5
- data/lib/adhearsion/call_controller/output.rb +47 -33
- data/lib/adhearsion/call_controller/output/async_player.rb +3 -2
- data/lib/adhearsion/call_controller/output/formatter.rb +7 -2
- data/lib/adhearsion/call_controller/output/player.rb +2 -2
- data/lib/adhearsion/call_controller/record.rb +16 -13
- data/lib/adhearsion/call_controller/utility.rb +3 -3
- data/lib/adhearsion/calls.rb +21 -8
- data/lib/adhearsion/cli_commands/ahn_command.rb +1 -0
- data/lib/adhearsion/configuration.rb +2 -2
- data/lib/adhearsion/console.rb +3 -2
- data/lib/adhearsion/generators.rb +7 -9
- data/lib/adhearsion/generators/app/app_generator.rb +12 -2
- data/lib/adhearsion/generators/app/templates/Gemfile.erb +7 -9
- data/lib/adhearsion/generators/app/templates/README.md +0 -19
- data/lib/adhearsion/generators/app/templates/adhearsion.erb +37 -0
- data/lib/adhearsion/generators/app/templates/config/environment.rb +6 -1
- data/lib/adhearsion/generators/app/templates/events.erb +18 -0
- data/lib/adhearsion/generators/app/templates/routes.erb +19 -0
- data/lib/adhearsion/generators/app/templates/{lib/simon_game.rb → simon_game.rb} +0 -0
- data/lib/adhearsion/generators/app/templates/{spec/call_controllers/simon_game_spec.rb → simon_game_spec.rb} +0 -0
- data/lib/adhearsion/generators/controller/controller_generator.rb +2 -2
- data/lib/adhearsion/generators/controller/templates/lib/{controller.rb → controller.rb.erb} +0 -0
- data/lib/adhearsion/generators/controller/templates/spec/{controller_spec.rb → controller_spec.rb.erb} +0 -0
- data/lib/adhearsion/generators/plugin/plugin_generator.rb +16 -15
- data/lib/adhearsion/generators/plugin/templates/gitignore +17 -0
- data/lib/adhearsion/generators/plugin/templates/spec/plugin-template/controller_methods_spec.rb.tt +1 -1
- data/lib/adhearsion/initializer.rb +14 -2
- data/lib/adhearsion/logging.rb +1 -0
- data/lib/adhearsion/outbound_call.rb +3 -7
- data/lib/adhearsion/punchblock_plugin/initializer.rb +3 -2
- data/lib/adhearsion/router/openended_route.rb +1 -1
- data/lib/adhearsion/router/route.rb +4 -3
- data/lib/adhearsion/version.rb +1 -1
- data/spec/adhearsion/call_controller/dial_spec.rb +811 -79
- data/spec/adhearsion/call_controller/output/formatter_spec.rb +13 -1
- data/spec/adhearsion/call_controller/output_spec.rb +35 -1
- data/spec/adhearsion/call_controller_spec.rb +174 -18
- data/spec/adhearsion/call_spec.rb +423 -39
- data/spec/adhearsion/calls_spec.rb +19 -3
- data/spec/adhearsion/outbound_call_spec.rb +88 -45
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +3 -3
- data/spec/adhearsion/router/route_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -0
- metadata +92 -77
- data/features/app_generator.feature +0 -49
- data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +0 -71
- data/lib/adhearsion/generators/plugin/templates/.gitignore +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9155fcf025c8ed90e014e5262b70387e46e31937
|
4
|
+
data.tar.gz: dcb5d1f0104f854e3b487f34cf199e3134d5d38d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00076ee1fdd8a0d208dc1895dbb74f33f5c0adc23a2348248c0c8938378715d2bd40b7f8bfe64e42b05d2cd3e9594a0159d00af5b64f8e3285e37d2336249011
|
7
|
+
data.tar.gz: 7b1e9f478d6860f662e485a1c5add9e69ed0d1c2cf0f1d038ed661c47e2fd791224855bd452d89c79c09b18ebec16988df30af6650fb03870b77cde1f190ab14
|
data/.travis.yml
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 1.9.2
|
4
3
|
- 1.9.3
|
5
4
|
- 2.0.0
|
5
|
+
- 2.1.0
|
6
6
|
- jruby-19mode
|
7
|
-
- rbx-
|
7
|
+
- rbx-2.1.1
|
8
8
|
- ruby-head
|
9
9
|
matrix:
|
10
10
|
allow_failures:
|
11
|
-
- rvm: rbx-
|
11
|
+
- rvm: rbx-2.1.1
|
12
12
|
- rvm: ruby-head
|
13
13
|
env: ARUBA_TIMEOUT=120 RAILS_ENV=development AHN_ENV=development
|
14
14
|
notifications:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
# [develop](https://github.com/adhearsion/adhearsion)
|
2
2
|
|
3
|
+
# [2.5.0](https://github.com/adhearsion/adhearsion/compare/v2.4.0...v2.5.0) - [2014-02-03](https://rubygems.org/gems/adhearsion/versions/2.5.0)
|
4
|
+
* **Change: Ruby 1.9.2 is no longer supported**
|
5
|
+
* Change: Set default call post-hangup lifetime to one second for better out of the box performance.
|
6
|
+
* Feature: Allow stopping all components executed by a controller when passing from it (`#hard_pass`) or at will (`#stop_all_components`)
|
7
|
+
* Feature: Generated plugins include a .gitignore file
|
8
|
+
* Feature: Detect something like "1234#" as characters instead of text
|
9
|
+
* Feature: Add `--empty` switch to app generator for power users. Generates an app with less fluff.
|
10
|
+
* Feature: Default generated applications with config appropriate for [Telephony Dev Box](http://github.com/mojolingo/Telephony-Dev-Box)
|
11
|
+
* Feature: Allow preventing automatic call hangup after controller completion. Set `Call#auto_hangup = false` prior to controller termination.
|
12
|
+
* Feature: Allow specifying a pre-join callback to #dial
|
13
|
+
* Feature: Allow specifying ringback to `#dial` as either a list or a proc
|
14
|
+
* Feature: Allow passing `:join_options` parameter to `#dial` to specify the kind of join to perform.
|
15
|
+
* Feature: Allow passing `:join_target` parameter to `#dial` to specify who to join to (eg a mixer).
|
16
|
+
* Feature: Generated apps now encourage storing most app code in `app/`, which is in the load path. Nothing in this directory is auto-loaded, but can be easily required without messy relative paths.
|
17
|
+
* Feature: Routes and event handlers are now split out of main config file for readability. They may be retained in the main config file for existing apps.
|
18
|
+
* Feature: Add `Call#end_code`, which specifies the platform code for the call end event.
|
19
|
+
* Feature: Allow XMPP messages to be sent via Punchblock
|
20
|
+
* Bugfix: Don't block shutdown waiting for the console to terminate
|
21
|
+
* Bugfix: Ensure that splitting a dial rejoined to an alternative target (eg a mixer) or merged with another dial can still be split properly.
|
22
|
+
* Bugfix: Ensure that hungup calls don't prevent dial splits/merges.
|
23
|
+
* Bugfix: Ensure that merged dials which are split and rejoined all get rejoined to the mixer.
|
24
|
+
* Bugfix: Ensure that `Call#peers` are correctly maintained - this was broken by Rayo moving to full call URIs in joined/unjoined events
|
25
|
+
* Bugfix: Ensure that failure to dial a call kills the actor
|
26
|
+
* Bugfix: Adhearsion call actors should do recursion detection on #inspect
|
27
|
+
* Bugfix: Fix controller block context on JRuby
|
28
|
+
* Bugfix: Require only Bundler groups appropriate to application environment
|
29
|
+
* Bugfix: Call event handlers now cannot crash the call, and no longer stop on return value
|
30
|
+
* Bugfix: Call controllers are gracefully terminated when a command is attempted against a dead call
|
31
|
+
|
3
32
|
# [2.4.0](https://github.com/adhearsion/adhearsion/compare/v2.3.5...v2.4.0) - [2013-08-29](https://rubygems.org/gems/adhearsion/versions/2.4.0)
|
4
33
|
* Deprecation: Ruby 1.9.2 support is deprecated and will be dropped in a future version of Adhearsion
|
5
34
|
* Deprecation: Some media options from Punchblock config are now overriden by other core config, and will eventually be removed.
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
ENV['SKIP_RCOV'] = 'true'
|
2
2
|
|
3
3
|
group 'rspec' do
|
4
|
-
guard 'rspec', :
|
4
|
+
guard 'rspec', cmd: 'bundle exec rspec' do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
7
|
watch('spec/spec_helper.rb') { "spec/" }
|
@@ -9,7 +9,7 @@ group 'rspec' do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
group 'cucumber' do
|
12
|
-
guard 'cucumber', :cli => '--profile guard' do
|
12
|
+
guard 'cucumber', :cli => '--profile guard', all_on_start: false do
|
13
13
|
watch(%r{^features/.+\.feature$})
|
14
14
|
watch(%r{^features/support/.+$}) { 'features' }
|
15
15
|
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
|
data/README.markdown
CHANGED
@@ -23,18 +23,15 @@ Adhearsion rests above a lower-level telephony platform, for example [Asterisk](
|
|
23
23
|
|
24
24
|
## Requirements
|
25
25
|
|
26
|
-
* Ruby 1.9.
|
26
|
+
* Ruby 1.9.3+ or JRuby 1.7.0+
|
27
|
+
* [ruby_speech dependencies](https://github.com/benlangfeld/ruby_speech#dependencies)
|
27
28
|
* A VoIP platform:
|
28
29
|
* Asterisk 1.8+
|
29
30
|
* FreeSWITCH
|
30
31
|
* A Rayo server (Prism 11+ with rayo-server, or FreeSWITCH with mod_rayo)
|
31
32
|
* An interest in building cool new things
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
```ruby
|
36
|
-
gem 'active_support', '~> 3.0'
|
37
|
-
```
|
34
|
+
**Ruby 1.9.2 is no longer supported by Adhearsion or the Ruby core team. You should upgrade to Ruby 1.9.3 or Ruby 2 as a matter of urgency in order to continue receiving security fixes.**
|
38
35
|
|
39
36
|
## Install
|
40
37
|
|
data/Rakefile
CHANGED
@@ -29,7 +29,7 @@ end
|
|
29
29
|
begin
|
30
30
|
require 'yard'
|
31
31
|
YARD::Rake::YardocTask.new do |t|
|
32
|
-
t.files = ['lib/**/*.rb']
|
32
|
+
t.files = ['lib/**/*.rb']
|
33
33
|
end
|
34
34
|
rescue LoadError
|
35
35
|
STDERR.puts "\nCould not require() YARD! Install with 'gem install yard' to get the 'yardoc' task\n\n"
|
data/adhearsion.gemspec
CHANGED
@@ -12,6 +12,10 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.summary = "Adhearsion, open-source telephony development framework"
|
13
13
|
s.description = "Adhearsion is an open-source telephony development framework"
|
14
14
|
|
15
|
+
s.license = 'MIT'
|
16
|
+
|
17
|
+
s.required_ruby_version = '>= 1.9.3'
|
18
|
+
|
15
19
|
s.files = `git ls-files`.split("\n")
|
16
20
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
21
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -25,11 +29,11 @@ Gem::Specification.new do |s|
|
|
25
29
|
s.add_runtime_dependency 'deep_merge'
|
26
30
|
s.add_runtime_dependency 'ffi', ["~> 1.0"]
|
27
31
|
s.add_runtime_dependency 'girl_friday'
|
28
|
-
s.add_runtime_dependency 'has-guarded-handlers', ["~> 1.
|
32
|
+
s.add_runtime_dependency 'has-guarded-handlers', ["~> 1.6"]
|
29
33
|
s.add_runtime_dependency 'jruby-openssl' if RUBY_PLATFORM == 'java'
|
30
34
|
s.add_runtime_dependency 'logging', ["~> 1.8"]
|
31
35
|
s.add_runtime_dependency 'pry'
|
32
|
-
s.add_runtime_dependency 'punchblock', ["~> 2.
|
36
|
+
s.add_runtime_dependency 'punchblock', ["~> 2.3"]
|
33
37
|
s.add_runtime_dependency 'rake'
|
34
38
|
s.add_runtime_dependency 'ruby_speech', ["~> 2.0"]
|
35
39
|
s.add_runtime_dependency 'thor', "~> 0.18.0"
|
@@ -43,6 +47,7 @@ Gem::Specification.new do |s|
|
|
43
47
|
s.add_development_dependency 'simplecov'
|
44
48
|
s.add_development_dependency 'simplecov-rcov'
|
45
49
|
s.add_development_dependency 'yard'
|
50
|
+
s.add_development_dependency 'guard-yard'
|
46
51
|
s.add_development_dependency 'coveralls'
|
47
52
|
s.add_development_dependency 'timecop'
|
48
53
|
end
|
data/features/cli_create.feature
CHANGED
@@ -3,18 +3,96 @@ Feature: Adhearsion Ahn CLI (Create)
|
|
3
3
|
I want the ahn command to allow creating an app
|
4
4
|
So that I can write an Adhearsion app
|
5
5
|
|
6
|
-
Scenario:
|
6
|
+
Scenario: Generate application with valid layout
|
7
7
|
When I run `ahn create path/somewhere`
|
8
8
|
And I cd to "path/somewhere"
|
9
|
-
Then the following
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
Then the following directories should exist:
|
10
|
+
| app/call_controllers |
|
11
|
+
| lib |
|
12
|
+
| config |
|
13
|
+
| script |
|
14
|
+
| spec |
|
15
|
+
| spec/call_controllers |
|
16
|
+
| spec/support |
|
17
|
+
|
18
|
+
And the following files should exist:
|
19
|
+
| .gitignore |
|
20
|
+
| .rspec |
|
21
|
+
| app/call_controllers/simon_game.rb |
|
22
|
+
| config/adhearsion.rb |
|
23
|
+
| config/environment.rb |
|
24
|
+
| config/events.rb |
|
25
|
+
| config/routes.rb |
|
26
|
+
| Gemfile |
|
27
|
+
| script/ahn |
|
28
|
+
| spec/spec_helper.rb |
|
29
|
+
| spec/call_controllers/simon_game_spec.rb |
|
30
|
+
| README.md |
|
31
|
+
| Rakefile |
|
32
|
+
| Procfile |
|
33
|
+
|
34
|
+
And the file "config/adhearsion.rb" should contain each of these content parts:
|
35
|
+
"""
|
36
|
+
Adhearsion.config
|
37
|
+
logging.level
|
38
|
+
config.punchblock
|
39
|
+
"""
|
40
|
+
And the file "config/events.rb" should contain each of these content parts:
|
41
|
+
"""
|
42
|
+
Adhearsion::Events.draw do
|
43
|
+
"""
|
44
|
+
And the file "config/routes.rb" should contain each of these content parts:
|
45
|
+
"""
|
46
|
+
Adhearsion.router
|
47
|
+
"""
|
48
|
+
And the file "README.md" should contain each of these content parts:
|
49
|
+
"""
|
50
|
+
Start your new app with
|
51
|
+
AGI(agi
|
52
|
+
"""
|
53
|
+
And the file "Rakefile" should contain "adhearsion/tasks"
|
54
|
+
And the file "Gemfile" should contain each of these content parts:
|
55
|
+
"""
|
56
|
+
source 'https://rubygems.org
|
57
|
+
gem 'adhearsion-asr'
|
58
|
+
"""
|
59
|
+
And the file "app/call_controllers/simon_game.rb" should contain "class SimonGame"
|
60
|
+
And the file "script/ahn" should contain "require 'adhearsion'"
|
61
|
+
|
62
|
+
Scenario: Generate application --empty
|
63
|
+
When I run `ahn create path/somewhere --empty`
|
64
|
+
And I cd to "path/somewhere"
|
65
|
+
Then the following directories should exist:
|
66
|
+
| app/call_controllers |
|
67
|
+
| lib |
|
68
|
+
| config |
|
69
|
+
| script |
|
70
|
+
| spec |
|
71
|
+
| spec/call_controllers |
|
72
|
+
| spec/support |
|
73
|
+
|
74
|
+
And the following files should exist:
|
75
|
+
| .gitignore |
|
76
|
+
| .rspec |
|
13
77
|
| config/adhearsion.rb |
|
14
78
|
| config/environment.rb |
|
79
|
+
| config/events.rb |
|
80
|
+
| config/routes.rb |
|
81
|
+
| Gemfile |
|
82
|
+
| script/ahn |
|
15
83
|
| spec/spec_helper.rb |
|
16
|
-
|
17
|
-
|
84
|
+
| README.md |
|
85
|
+
| Rakefile |
|
86
|
+
| Procfile |
|
87
|
+
|
88
|
+
And the following files should not exist:
|
89
|
+
| app/call_controllers/simon_game.rb |
|
90
|
+
| spec/call_controllers/simon_game_spec.rb |
|
91
|
+
|
92
|
+
And the file "config/events.rb" should not contain each of these content parts:
|
93
|
+
"""
|
94
|
+
# Register global handlers for events
|
95
|
+
"""
|
18
96
|
|
19
97
|
Scenario: Running create with no arguments
|
20
98
|
When I run `ahn create`
|
@@ -11,6 +11,7 @@ Feature: Adhearsion plugin generator
|
|
11
11
|
| test_plugin/lib/test_plugin |
|
12
12
|
| test_plugin/spec |
|
13
13
|
And the following files should exist:
|
14
|
+
| test_plugin/.gitignore |
|
14
15
|
| test_plugin/test_plugin.gemspec |
|
15
16
|
| test_plugin/Rakefile |
|
16
17
|
| test_plugin/README.md |
|
@@ -21,6 +22,7 @@ Feature: Adhearsion plugin generator
|
|
21
22
|
| test_plugin/lib/test_plugin/controller_methods.rb |
|
22
23
|
| test_plugin/spec/spec_helper.rb |
|
23
24
|
| test_plugin/spec/test_plugin/controller_methods_spec.rb |
|
25
|
+
And the file "test_plugin/.gitignore" should contain "Gemfile.lock"
|
24
26
|
And the file "test_plugin/test_plugin.gemspec" should contain "test_plugin/version"
|
25
27
|
And the file "test_plugin/README.md" should contain "TestPlugin"
|
26
28
|
And the file "test_plugin/lib/test_plugin.rb" should contain each of these content parts:
|
@@ -62,6 +64,7 @@ Feature: Adhearsion plugin generator
|
|
62
64
|
| test_plugin/lib/test_plugin |
|
63
65
|
| test_plugin/spec |
|
64
66
|
And the following files should exist:
|
67
|
+
| test_plugin/.gitignore |
|
65
68
|
| test_plugin/test_plugin.gemspec |
|
66
69
|
| test_plugin/Rakefile |
|
67
70
|
| test_plugin/README.md |
|
@@ -72,6 +75,7 @@ Feature: Adhearsion plugin generator
|
|
72
75
|
| test_plugin/lib/test_plugin/controller_methods.rb |
|
73
76
|
| test_plugin/spec/spec_helper.rb |
|
74
77
|
| test_plugin/spec/test_plugin/controller_methods_spec.rb |
|
78
|
+
And the file "test_plugin/.gitignore" should contain "Gemfile.lock"
|
75
79
|
And the file "test_plugin/test_plugin.gemspec" should contain "test_plugin/version"
|
76
80
|
And the file "test_plugin/README.md" should contain "TestPlugin"
|
77
81
|
And the file "test_plugin/lib/test_plugin.rb" should contain each of these content parts:
|
@@ -1,8 +1,15 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
Then /^the file "([^"]*)" should contain each of these content parts:$/ do |file, content_parts|
|
4
|
-
parts = content_parts.split
|
4
|
+
parts = content_parts.split("\n")
|
5
5
|
parts.each do |p|
|
6
6
|
steps %Q{Then the file "#{file}" should contain "#{p}"}
|
7
7
|
end
|
8
8
|
end
|
9
|
+
|
10
|
+
Then /^the file "([^"]*)" should not contain each of these content parts:$/ do |file, content_parts|
|
11
|
+
parts = content_parts.split("\n")
|
12
|
+
parts.each do |p|
|
13
|
+
steps %Q{Then the file "#{file}" should not contain "#{p}"}
|
14
|
+
end
|
15
|
+
end
|
data/lib/adhearsion.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
abort "ERROR: You are running Adhearsion on an unsupported version of Ruby (Ruby #{RUBY_VERSION} #{RUBY_RELEASE_DATE})! Please upgrade to at least Ruby v1.9.
|
3
|
+
abort "ERROR: You are running Adhearsion on an unsupported version of Ruby (Ruby #{RUBY_VERSION} #{RUBY_RELEASE_DATE})! Please upgrade to at least Ruby v1.9.3, JRuby 1.7.0 or Rubinius 2.0." if RUBY_VERSION < "1.9.3"
|
4
4
|
|
5
5
|
%w{
|
6
6
|
active_support/all
|
@@ -71,8 +71,7 @@ module Adhearsion
|
|
71
71
|
|
72
72
|
def initialize_config
|
73
73
|
_config = Configuration.new
|
74
|
-
env =
|
75
|
-
env = env.to_sym if env.respond_to? :to_sym
|
74
|
+
env = environment.to_sym if environment.respond_to? :to_sym
|
76
75
|
unless _config.valid_environment? env
|
77
76
|
puts "You tried to initialize with an invalid environment name #{env}. Valid values are #{_config.valid_environments}."
|
78
77
|
env = nil
|
@@ -81,6 +80,10 @@ module Adhearsion
|
|
81
80
|
_config
|
82
81
|
end
|
83
82
|
|
83
|
+
def environment
|
84
|
+
ENV['AHN_ENV'] || ENV['RAILS_ENV'] || :development
|
85
|
+
end
|
86
|
+
|
84
87
|
def environments
|
85
88
|
config.valid_environments
|
86
89
|
end
|
data/lib/adhearsion/call.rb
CHANGED
@@ -17,7 +17,7 @@ module Adhearsion
|
|
17
17
|
include Celluloid
|
18
18
|
include HasGuardedHandlers
|
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
|
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, *execute_block_on_receiver
|
21
21
|
finalizer :finalize
|
22
22
|
|
23
23
|
def self.new(*args, &block)
|
@@ -25,7 +25,7 @@ module Adhearsion
|
|
25
25
|
def proxy.method_missing(*args)
|
26
26
|
super
|
27
27
|
rescue Celluloid::DeadActorError
|
28
|
-
raise ExpiredError, "This call is expired and is no longer accessible"
|
28
|
+
raise ExpiredError, "This call is expired and is no longer accessible. See http://adhearsion.com/docs/calls for further details."
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -33,6 +33,9 @@ module Adhearsion
|
|
33
33
|
# @return [Symbol] the reason for the call ending
|
34
34
|
attr_reader :end_reason
|
35
35
|
|
36
|
+
# @return [String] the reason code for the call ending
|
37
|
+
attr_reader :end_code
|
38
|
+
|
36
39
|
# @return [Array<Adhearsion::CallController>] the set of call controllers executing on the call
|
37
40
|
attr_reader :controllers
|
38
41
|
|
@@ -45,8 +48,25 @@ module Adhearsion
|
|
45
48
|
# @return [Time] the time at which the call began. For inbound calls this is the time at which the call was offered to Adhearsion. For outbound calls it is the time at which the remote party answered.
|
46
49
|
attr_reader :end_time
|
47
50
|
|
51
|
+
# @return [true, false] wether or not the call should be automatically hung up after executing its controller
|
52
|
+
attr_accessor :auto_hangup
|
53
|
+
|
48
54
|
delegate :[], :[]=, :to => :variables
|
49
|
-
|
55
|
+
|
56
|
+
# @return [String] the value of the To header from the signaling protocol
|
57
|
+
delegate :to, to: :offer, allow_nil: true
|
58
|
+
|
59
|
+
# @return [String] the value of the From header from the signaling protocol
|
60
|
+
delegate :from, to: :offer, allow_nil: true
|
61
|
+
|
62
|
+
def self.uri(transport, id, domain)
|
63
|
+
return nil unless id
|
64
|
+
s = ""
|
65
|
+
s << transport << ":" if transport
|
66
|
+
s << id
|
67
|
+
s << "@" << domain if domain
|
68
|
+
s
|
69
|
+
end
|
50
70
|
|
51
71
|
def initialize(offer = nil)
|
52
72
|
register_initial_handlers
|
@@ -57,9 +77,11 @@ module Adhearsion
|
|
57
77
|
@variables = HashWithIndifferentAccess.new
|
58
78
|
@controllers = []
|
59
79
|
@end_reason = nil
|
80
|
+
@end_code = nil
|
60
81
|
@end_blocker = Celluloid::Condition.new
|
61
82
|
@peers = {}
|
62
83
|
@duration = nil
|
84
|
+
@auto_hangup = true
|
63
85
|
|
64
86
|
self << offer if offer
|
65
87
|
end
|
@@ -83,12 +105,7 @@ module Adhearsion
|
|
83
105
|
# @return [String, nil] The uri at which the call resides
|
84
106
|
#
|
85
107
|
def uri
|
86
|
-
|
87
|
-
s = ""
|
88
|
-
s << transport << ":" if transport
|
89
|
-
s << id
|
90
|
-
s << "@" << domain if domain
|
91
|
-
s
|
108
|
+
self.class.uri(transport, id, domain)
|
92
109
|
end
|
93
110
|
|
94
111
|
#
|
@@ -146,13 +163,26 @@ module Adhearsion
|
|
146
163
|
end
|
147
164
|
end
|
148
165
|
|
166
|
+
#
|
167
|
+
# Register a handler for events on this call. Note that Adhearsion::Call implements the has-guarded-handlers API, and all of its methods are available. Specifically, all Adhearsion events are available on the `:event` channel.
|
168
|
+
#
|
169
|
+
# @param [guards] guards take a look at the guards documentation
|
170
|
+
#
|
171
|
+
# @yield [Object] trigger_object the incoming event
|
172
|
+
#
|
173
|
+
# @return [String] handler ID for later manipulation
|
174
|
+
#
|
175
|
+
# @see http://adhearsion.github.io/has-guarded-handlers for more details
|
176
|
+
#
|
149
177
|
def register_event_handler(*guards, &block)
|
150
178
|
register_handler :event, *guards, &block
|
151
179
|
end
|
152
180
|
|
153
181
|
def deliver_message(message)
|
154
182
|
logger.debug "Receiving message: #{message.inspect}"
|
155
|
-
catching_standard_errors
|
183
|
+
catching_standard_errors do
|
184
|
+
trigger_handler :event, message, broadcast: true, exception_callback: ->(e) { Adhearsion::Events.trigger :exception, [e, logger] }
|
185
|
+
end
|
156
186
|
end
|
157
187
|
alias << deliver_message
|
158
188
|
|
@@ -166,12 +196,10 @@ module Adhearsion
|
|
166
196
|
@offer = offer
|
167
197
|
@client = offer.client
|
168
198
|
@start_time = Time.now
|
169
|
-
throw :pass
|
170
199
|
end
|
171
200
|
|
172
201
|
register_event_handler Punchblock::HasHeaders do |event|
|
173
202
|
merge_headers event.headers
|
174
|
-
throw :pass
|
175
203
|
end
|
176
204
|
|
177
205
|
on_joined do |event|
|
@@ -183,7 +211,8 @@ module Adhearsion
|
|
183
211
|
type = :mixer
|
184
212
|
end
|
185
213
|
logger.info "Joined to #{type} #{target}"
|
186
|
-
|
214
|
+
call = Adhearsion.active_calls.with_uri(target)
|
215
|
+
@peers[target] = call
|
187
216
|
signal :joined, target
|
188
217
|
end
|
189
218
|
|
@@ -206,10 +235,10 @@ module Adhearsion
|
|
206
235
|
@duration = @end_time - @start_time if @start_time
|
207
236
|
clear_from_active_calls
|
208
237
|
@end_reason = event.reason
|
238
|
+
@end_code = event.platform_code
|
209
239
|
@end_blocker.broadcast event.reason
|
210
240
|
@commands.terminate
|
211
241
|
after(Adhearsion.config.platform.after_hangup_lifetime) { terminate }
|
212
|
-
throw :pass
|
213
242
|
end
|
214
243
|
end
|
215
244
|
|
@@ -234,7 +263,6 @@ module Adhearsion
|
|
234
263
|
def on_joined(target = nil, &block)
|
235
264
|
register_event_handler Punchblock::Event::Joined, *guards_for_target(target) do |event|
|
236
265
|
block.call event
|
237
|
-
throw :pass
|
238
266
|
end
|
239
267
|
end
|
240
268
|
|
@@ -246,22 +274,16 @@ module Adhearsion
|
|
246
274
|
# @option target [String] mixer_name The mixer name to guard on
|
247
275
|
#
|
248
276
|
def on_unjoined(target = nil, &block)
|
249
|
-
register_event_handler Punchblock::Event::Unjoined, *guards_for_target(target)
|
250
|
-
block.call event
|
251
|
-
throw :pass
|
252
|
-
end
|
277
|
+
register_event_handler Punchblock::Event::Unjoined, *guards_for_target(target), &block
|
253
278
|
end
|
254
279
|
|
255
280
|
# @private
|
256
281
|
def guards_for_target(target)
|
257
|
-
target ? [join_options_with_target(target)] : []
|
282
|
+
target ? [target_from_join_options(join_options_with_target(target))] : []
|
258
283
|
end
|
259
284
|
|
260
285
|
def on_end(&block)
|
261
|
-
register_event_handler Punchblock::Event::End
|
262
|
-
block.call event
|
263
|
-
throw :pass
|
264
|
-
end
|
286
|
+
register_event_handler Punchblock::Event::End, &block
|
265
287
|
end
|
266
288
|
|
267
289
|
#
|
@@ -304,10 +326,29 @@ module Adhearsion
|
|
304
326
|
# @option target [String] mixer_name The mixer to join to
|
305
327
|
# @param [Hash, Optional] options further options to be joined with
|
306
328
|
#
|
329
|
+
# @return [Hash] where :command is the issued command, :joined_waiter is a #wait responder which is triggered when the join is complete, and :unjoined_waiter is a #wait responder which is triggered when the entities are unjoined
|
330
|
+
#
|
307
331
|
def join(target, options = {})
|
308
332
|
logger.info "Joining to #{target}"
|
333
|
+
|
334
|
+
joined_condition = CountDownLatch.new(1)
|
335
|
+
on_joined target do
|
336
|
+
joined_condition.countdown!
|
337
|
+
end
|
338
|
+
|
339
|
+
unjoined_condition = CountDownLatch.new(1)
|
340
|
+
on_unjoined target do
|
341
|
+
unjoined_condition.countdown!
|
342
|
+
end
|
343
|
+
|
344
|
+
on_end do
|
345
|
+
joined_condition.countdown!
|
346
|
+
unjoined_condition.countdown!
|
347
|
+
end
|
348
|
+
|
309
349
|
command = Punchblock::Command::Join.new options.merge(join_options_with_target(target))
|
310
350
|
write_and_await_response command
|
351
|
+
{command: command, joined_condition: joined_condition, unjoined_condition: unjoined_condition}
|
311
352
|
end
|
312
353
|
|
313
354
|
##
|
@@ -329,7 +370,7 @@ module Adhearsion
|
|
329
370
|
when Call
|
330
371
|
{ :call_uri => target.uri }
|
331
372
|
when String
|
332
|
-
{ :call_uri =>
|
373
|
+
{ :call_uri => self.class.uri(transport, target, domain) }
|
333
374
|
when Hash
|
334
375
|
abort ArgumentError.new "You cannot specify both a call URI and mixer name" if target.has_key?(:call_uri) && target.has_key?(:mixer_name)
|
335
376
|
target
|
@@ -338,6 +379,13 @@ module Adhearsion
|
|
338
379
|
end
|
339
380
|
end
|
340
381
|
|
382
|
+
# @private
|
383
|
+
def target_from_join_options(options)
|
384
|
+
call_uri = options[:call_uri]
|
385
|
+
return {call_uri: call_uri} if call_uri
|
386
|
+
{mixer_name: options[:mixer_name]}
|
387
|
+
end
|
388
|
+
|
341
389
|
def wait_for_joined(expected_target)
|
342
390
|
target = nil
|
343
391
|
until target == expected_target do
|
@@ -361,25 +409,27 @@ module Adhearsion
|
|
361
409
|
end
|
362
410
|
|
363
411
|
# @private
|
364
|
-
def write_and_await_response(command, timeout = 60)
|
412
|
+
def write_and_await_response(command, timeout = 60, fatal = false)
|
365
413
|
@commands << command
|
366
414
|
write_command command
|
367
415
|
|
416
|
+
error_handler = fatal ? ->(error) { raise error } : ->(error) { abort error }
|
417
|
+
|
368
418
|
response = defer { command.response timeout }
|
369
419
|
case response
|
370
420
|
when Punchblock::ProtocolError
|
371
421
|
if response.name == :item_not_found
|
372
|
-
|
422
|
+
error_handler[Hangup.new(@end_reason)]
|
373
423
|
else
|
374
|
-
|
424
|
+
error_handler[response]
|
375
425
|
end
|
376
426
|
when Exception
|
377
|
-
|
427
|
+
error_handler[response]
|
378
428
|
end
|
379
429
|
|
380
430
|
command
|
381
431
|
rescue Timeout::Error
|
382
|
-
|
432
|
+
error_handler[CommandTimeout.new(command.to_s)]
|
383
433
|
ensure
|
384
434
|
@commands.delete command
|
385
435
|
end
|
@@ -392,18 +442,39 @@ module Adhearsion
|
|
392
442
|
client.execute_command command, call_id: id, domain: domain, async: true
|
393
443
|
end
|
394
444
|
|
445
|
+
##
|
446
|
+
# Sends a message to the caller
|
447
|
+
#
|
448
|
+
# @param [String] body The message text.
|
449
|
+
# @param [Hash, Optional] options The message options.
|
450
|
+
# @option options [String] subject The message subject.
|
451
|
+
#
|
452
|
+
def send_message(body, options = {})
|
453
|
+
logger.debug "Sending message: #{body}"
|
454
|
+
client.send_message id, domain, body, options
|
455
|
+
end
|
456
|
+
|
395
457
|
# @private
|
396
458
|
def logger_id
|
397
459
|
"#{self.class}: #{id}@#{domain}"
|
398
460
|
end
|
399
461
|
# @private
|
400
462
|
def inspect
|
463
|
+
return "..." if Celluloid.detect_recursion
|
401
464
|
attrs = [:offer, :end_reason, :commands, :variables, :controllers, :to, :from].map do |attr|
|
402
465
|
"#{attr}=#{send(attr).inspect}"
|
403
466
|
end
|
404
467
|
"#<#{self.class}:#{id}@#{domain} #{attrs.join ', '}>"
|
405
468
|
end
|
406
469
|
|
470
|
+
#
|
471
|
+
# Execute a call controller asynchronously against this call.
|
472
|
+
#
|
473
|
+
# @param [Adhearsion::CallController] controller an instance of a controller initialized for this call
|
474
|
+
# @param [Proc] a callback to be executed when the controller finishes execution
|
475
|
+
#
|
476
|
+
# @yield execute the current block as the body of a controller by specifying no controller instance
|
477
|
+
#
|
407
478
|
def execute_controller(controller = nil, completion_callback = nil, &block)
|
408
479
|
raise ArgumentError, "Cannot supply a controller and a block at the same time" if controller && block_given?
|
409
480
|
controller ||= CallController.new current_actor, &block
|