adhearsion 2.0.0.beta1 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.travis.yml +2 -4
  2. data/CHANGELOG.md +34 -4
  3. data/README.markdown +2 -1
  4. data/Rakefile +22 -1
  5. data/adhearsion.gemspec +1 -0
  6. data/bin/ahn +0 -2
  7. data/features/cli_daemon.feature +2 -0
  8. data/features/cli_restart.feature +19 -0
  9. data/features/cli_start.feature +4 -6
  10. data/features/cli_stop.feature +3 -0
  11. data/features/step_definitions/app_generator_steps.rb +2 -0
  12. data/features/step_definitions/cli_steps.rb +2 -0
  13. data/features/support/aruba_helper.rb +2 -0
  14. data/features/support/env.rb +8 -46
  15. data/features/support/utils.rb +2 -0
  16. data/lib/adhearsion.rb +4 -6
  17. data/lib/adhearsion/call.rb +71 -17
  18. data/lib/adhearsion/call_controller.rb +25 -14
  19. data/lib/adhearsion/call_controller/dial.rb +34 -15
  20. data/lib/adhearsion/call_controller/input.rb +186 -144
  21. data/lib/adhearsion/call_controller/output.rb +10 -6
  22. data/lib/adhearsion/call_controller/record.rb +11 -13
  23. data/lib/adhearsion/call_controller/utility.rb +2 -0
  24. data/lib/adhearsion/calls.rb +4 -2
  25. data/lib/adhearsion/cli.rb +4 -0
  26. data/lib/adhearsion/cli_commands.rb +8 -2
  27. data/lib/adhearsion/configuration.rb +7 -3
  28. data/lib/adhearsion/console.rb +17 -17
  29. data/lib/adhearsion/events.rb +10 -4
  30. data/lib/adhearsion/foundation.rb +9 -0
  31. data/lib/adhearsion/foundation/custom_daemonizer.rb +3 -1
  32. data/lib/adhearsion/foundation/exception_handler.rb +2 -0
  33. data/lib/adhearsion/foundation/libc.rb +2 -0
  34. data/lib/adhearsion/foundation/object.rb +3 -0
  35. data/lib/adhearsion/foundation/thread_safety.rb +5 -11
  36. data/lib/adhearsion/generators.rb +2 -0
  37. data/lib/adhearsion/generators/app/app_generator.rb +2 -0
  38. data/lib/adhearsion/generators/app/templates/README.md +9 -0
  39. data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +38 -16
  40. data/lib/adhearsion/generators/app/templates/config/environment.rb +2 -0
  41. data/lib/adhearsion/generators/app/templates/lib/simon_game.rb +5 -3
  42. data/lib/adhearsion/generators/controller/controller_generator.rb +2 -0
  43. data/lib/adhearsion/generators/controller/templates/lib/controller.rb +2 -0
  44. data/lib/adhearsion/generators/controller/templates/spec/controller_spec.rb +2 -0
  45. data/lib/adhearsion/generators/generator.rb +3 -1
  46. data/lib/adhearsion/generators/plugin/plugin_generator.rb +2 -0
  47. data/lib/adhearsion/initializer.rb +31 -17
  48. data/lib/adhearsion/linux_proc_name.rb +2 -0
  49. data/lib/adhearsion/logging.rb +5 -3
  50. data/lib/adhearsion/menu_dsl.rb +2 -0
  51. data/lib/adhearsion/menu_dsl/calculated_match.rb +2 -0
  52. data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +2 -0
  53. data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +2 -0
  54. data/lib/adhearsion/menu_dsl/match_calculator.rb +2 -0
  55. data/lib/adhearsion/menu_dsl/menu.rb +58 -4
  56. data/lib/adhearsion/menu_dsl/menu_builder.rb +14 -1
  57. data/lib/adhearsion/menu_dsl/range_match_calculator.rb +4 -1
  58. data/lib/adhearsion/menu_dsl/string_match_calculator.rb +2 -0
  59. data/lib/adhearsion/outbound_call.rb +2 -0
  60. data/lib/adhearsion/plugin.rb +9 -7
  61. data/lib/adhearsion/plugin/collection.rb +3 -1
  62. data/lib/adhearsion/plugin/initializer.rb +3 -1
  63. data/lib/adhearsion/process.rb +8 -2
  64. data/lib/adhearsion/punchblock_plugin.rb +3 -1
  65. data/lib/adhearsion/punchblock_plugin/initializer.rb +34 -11
  66. data/lib/adhearsion/router.rb +4 -2
  67. data/lib/adhearsion/router/route.rb +2 -0
  68. data/lib/adhearsion/script_ahn_loader.rb +2 -0
  69. data/lib/adhearsion/tasks.rb +2 -0
  70. data/lib/adhearsion/tasks/configuration.rb +2 -0
  71. data/lib/adhearsion/tasks/debugging.rb +8 -0
  72. data/lib/adhearsion/tasks/environment.rb +2 -0
  73. data/lib/adhearsion/tasks/plugins.rb +2 -0
  74. data/lib/adhearsion/tasks/testing.rb +2 -0
  75. data/lib/adhearsion/version.rb +3 -1
  76. data/pre-commit +2 -0
  77. data/spec/adhearsion/call_controller/dial_spec.rb +114 -25
  78. data/spec/adhearsion/call_controller/input_spec.rb +192 -169
  79. data/spec/adhearsion/call_controller/output_spec.rb +26 -12
  80. data/spec/adhearsion/call_controller/record_spec.rb +29 -77
  81. data/spec/adhearsion/call_controller/utility_spec.rb +69 -0
  82. data/spec/adhearsion/call_controller_spec.rb +90 -15
  83. data/spec/adhearsion/call_spec.rb +92 -24
  84. data/spec/adhearsion/calls_spec.rb +9 -7
  85. data/spec/adhearsion/configuration_spec.rb +58 -56
  86. data/spec/adhearsion/console_spec.rb +4 -2
  87. data/spec/adhearsion/events_spec.rb +9 -7
  88. data/spec/adhearsion/generators_spec.rb +3 -1
  89. data/spec/adhearsion/initializer_spec.rb +16 -14
  90. data/spec/adhearsion/logging_spec.rb +11 -9
  91. data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +6 -4
  92. data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +6 -4
  93. data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +3 -1
  94. data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +2 -0
  95. data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +42 -11
  96. data/spec/adhearsion/menu_dsl/menu_spec.rb +197 -36
  97. data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +4 -2
  98. data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +5 -3
  99. data/spec/adhearsion/outbound_call_spec.rb +7 -5
  100. data/spec/adhearsion/plugin_spec.rb +19 -15
  101. data/spec/adhearsion/process_spec.rb +12 -7
  102. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +35 -15
  103. data/spec/adhearsion/punchblock_plugin_spec.rb +4 -1
  104. data/spec/adhearsion/router/route_spec.rb +8 -6
  105. data/spec/adhearsion/router_spec.rb +12 -10
  106. data/spec/adhearsion_spec.rb +13 -2
  107. data/spec/capture_warnings.rb +33 -0
  108. data/spec/spec_helper.rb +4 -0
  109. data/spec/support/call_controller_test_helpers.rb +2 -4
  110. data/spec/support/initializer_stubs.rb +8 -5
  111. data/spec/support/logging_helpers.rb +2 -0
  112. data/spec/support/punchblock_mocks.rb +2 -0
  113. metadata +84 -71
  114. data/EVENTS +0 -11
  115. data/lib/adhearsion/call_controller/menu.rb +0 -124
  116. data/lib/adhearsion/foundation/all.rb +0 -8
  117. data/spec/adhearsion/call_controller/menu_spec.rb +0 -120
  118. data/spec/adhearsion/menu_dsl_spec.rb +0 -12
@@ -5,8 +5,6 @@ rvm:
5
5
  - jruby-19mode # JRuby in 1.9 mode
6
6
  - rbx-19mode # currently in active development, may or may not work for your project
7
7
  - ruby-head
8
- env: ARUBA_TIMEOUT=120
8
+ env: ARUBA_TIMEOUT=120 RAILS_ENV=development AHN_ENV=development
9
9
  notifications:
10
- # irc: "irc.freenode.org#adhearsion"
11
- email:
12
- - blangfeld@adhearsion.com
10
+ irc: "irc.freenode.org#adhearsion"
@@ -1,4 +1,34 @@
1
- # 2.0.0.beta1 - 2012-03-07
1
+ # [develop](https://github.com/adhearsion/adhearsion)
2
+
3
+ # [2.0.0.rc1](https://github.com/adhearsion/adhearsion/compare/v2.0.0.beta1...v2.0.0.rc1) - [2012-03-20](https://rubygems.org/gems/adhearsion/versions/2.0.0.rc1)
4
+ * Change: `CallController#join` now blocks until a corresponding unjoined event is received
5
+ * Change: `CallController#speak` is now `CallController#say`
6
+ * Change: `CallController#input` has been removed in favour of `#ask`
7
+
8
+ * Feature: `CallController#menu` may now disallow the caller from interrupting prompts by specifying `:interruptible => false`
9
+ * Feature: `CallController#menu` and `CallController#ask` returns a `Result` object from which the status and response may be established
10
+ * Feature: `CallController#ask` behaves similarly to `#menu`, processing prompts and supporting `:terminator` and `:limit` options
11
+ * Feature: Added `Call#unjoin`
12
+ * Feature: `CallControll#join` now blocks until the corresponding call is unjoined and can be made non-blocking by passing `:async => true`
13
+ * Feature: `CallController#dial` now supports overriding or extra options for each call destinations
14
+ * Feature: Asterisk AMI events may now be handled using the `ami` handler
15
+ * Feature: Added environment debugging info when running at trace level, and by using `rake debugging`
16
+
17
+ * Bugfix: `ahn restart` now does not fail if the PID file is not found
18
+ * Bugfix: AHN_ENV and RAILS_ENV are now respected correctly
19
+ * Bugfix: `ahn` command now elminates all version mis-matches between installed and bundled gems
20
+ * Bugfix: Adhearsion is now ruby warning-free
21
+ * Bugfix: A hangup exception is now raised if call commands fail with a call-not-found
22
+ * Bugfix: `CallController#record` now functions as advertised
23
+ * Bugfix: The punchblock JID resource is not overriden if defined in config
24
+ * Bugfix: `DialStatus` objects returned from `CallController#dial` now include the cases where dials fail
25
+ * Bugfix: Calls are now processed after Punchblock reconnects
26
+ * Bugfix: Better exception logging
27
+ * Bugfix: Strings passed to `CallController#play` which contain `/` but are not file paths are now rendered as text
28
+ * Bugfix: Adhearsion now functions correctly on Heroku
29
+ * Cleaned up log messages
30
+
31
+ # [2.0.0.beta1](https://github.com/adhearsion/adhearsion/compare/v2.0.0.alpha3...v2.0.0.beta1) - [2012-03-07](https://rubygems.org/gems/adhearsion/versions/2.0.0.beta1)
2
32
  * Bugfix: #speak now correctly casts the argument to string if it is not SSML
3
33
  * Bugfix: The console pauses controllers on a call while taking control
4
34
  * Feature: Reopen logfiles on SIGHUP
@@ -9,7 +39,7 @@
9
39
  * Feature: Punchblock plugin can now configure the active media engine (mostly for use on Asterisk)
10
40
  * Bugfix: Fix forcing Adhearsion to stop with enough SIGTERM or CTRL+C
11
41
 
12
- # 2.0.0.alpha3 - 2012-02-21
42
+ # [2.0.0.alpha3](https://github.com/adhearsion/adhearsion/compare/v2.0.0.alpha2...v2.0.0.alpha3) - [2012-02-21](https://rubygems.org/gems/adhearsion/versions/2.0.0.alpha3)
13
43
  * Feature: Add `ahn generate` command to allow invocation of generators
14
44
  * Feature: Add simple generator for call controllers
15
45
  * Feature: Add simple generator for plugins
@@ -28,7 +58,7 @@
28
58
  * Feature: CallController#dial now defaults the outbound caller ID to that of the controller's call
29
59
  * Change: The command to take control of a call is now 'take' rather than 'use'. 'take' called without a call ID present a list of currently running calls
30
60
 
31
- # 2.0.0.alpha2 - 2012-01-30
61
+ # [2.0.0.alpha2](https://github.com/adhearsion/adhearsion/compare/v2.0.0.alpha1...v2.0.0.alpha2) - [2012-01-30](https://rubygems.org/gems/adhearsion/versions/2.0.0.alpha2)
32
62
  * Change: Plugins no longer load dialplan/event/rpc/console methods using corresponding class methods
33
63
  * Feature: CallController and Console can have modules of methods mixed in using `CallController.mixin` and `Console.mixin`
34
64
  * Feature: Added the ability to override configuration using environment variables. The correct names are given when running `rake adhearsion:config:show`, and are automatically added for all plugins. Plugins may define how the string environment variable is transformed to be useful.
@@ -45,7 +75,7 @@
45
75
  * Bugfix: The console should be shut down when shutting down the process
46
76
  * Rake tasks cleaned up and some initialization bugs fixed
47
77
 
48
- # 2.0.0.alpha1 - 2012-01-17
78
+ # [2.0.0.alpha1](https://github.com/adhearsion/adhearsion/compare/v1.2.1...v2.0.0.alpha1) - [2012-01-17](https://rubygems.org/gems/adhearsion/versions/2.0.0.alpha1)
49
79
 
50
80
  ## Major architectural changes
51
81
  * Adhearsion is no longer a framework for creating Asterisk applications, and it does not know anything about the specifics of Asterisk. Adhearsion now makes use of the Punchblock library which abstracts features from common telephony engines. Supported engines are now:
@@ -38,7 +38,7 @@ An Adhearsion application can be as simple as this:
38
38
 
39
39
  ```ruby
40
40
  answer
41
- speak 'Hello, and thank you for your call. We will put you through to the front desk now...'
41
+ say 'Hello, and thank you for your call. We will put you through to the front desk now...'
42
42
  dial 'tel:+18005550199'
43
43
  hangup
44
44
  ```
@@ -69,6 +69,7 @@ Contributions
69
69
  -----------------------------
70
70
 
71
71
  Adhearsion has a set of [contribution guidelines](https://github.com/adhearsion/adhearsion/wiki/Contributing) which help to smooth the contribution process.
72
+ There is a pre-commit hook that runs encoding checks available in pre-commit. To use it, please copy it to .git/hooks/pre-commit and make it executable.
72
73
 
73
74
  Copyright
74
75
  ---------
data/Rakefile CHANGED
@@ -9,7 +9,9 @@ task :default => [:spec, :features]
9
9
  task :gem => :build
10
10
 
11
11
  require 'rspec/core/rake_task'
12
- RSpec::Core::RakeTask.new
12
+ RSpec::Core::RakeTask.new(:spec) do |t|
13
+ t.ruby_opts = "-w -r./spec/capture_warnings"
14
+ end
13
15
 
14
16
  require 'ci/reporter/rake/rspec'
15
17
  require 'ci/reporter/rake/cucumber'
@@ -38,3 +40,22 @@ end
38
40
  task :stats do
39
41
  system 'doc/cloc-1.55.pl . --exclude-dir=.git,vendor,coverage,doc'
40
42
  end
43
+
44
+ task :encodeify do
45
+ Dir['{bin,features,lib,spec}/**/*.rb'].each do |filename|
46
+ File.open filename do |file|
47
+ first_line = file.first
48
+ if first_line == "# encoding: utf-8\n"
49
+ puts "#{filename} is utf-8"
50
+ else
51
+ puts "Making #{filename} utf-8..."
52
+ File.unlink filename
53
+ File.open filename, "w" do |new_file|
54
+ new_file.write "# encoding: utf-8\n\n"
55
+ new_file.write first_line
56
+ new_file.write file.read
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
41
41
  s.add_runtime_dependency 'jruby-openssl' if RUBY_PLATFORM == 'java'
42
42
  s.add_runtime_dependency 'ffi', [">= 1.0.11"]
43
43
  s.add_runtime_dependency 'celluloid', [">= 0.9.0"]
44
+ s.add_runtime_dependency 'deep_merge'
44
45
 
45
46
  # Development dependencies
46
47
  s.add_development_dependency 'rspec', ["~> 2.7.0"]
data/bin/ahn CHANGED
@@ -22,8 +22,6 @@
22
22
  $:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
23
23
 
24
24
  require 'rubygems'
25
- require 'bundler/setup'
26
- require 'adhearsion'
27
25
  require 'adhearsion/cli'
28
26
 
29
27
  Adhearsion::CLI::AhnCommand.start
@@ -3,6 +3,7 @@ Feature: Adhearsion Ahn CLI (daemon)
3
3
  I want the ahn command to provide a 'daemon' command
4
4
  So that I can start my adhearsion app as a daemon
5
5
 
6
+ @reconnect
6
7
  Scenario: Command daemon with path works correctly
7
8
  Given JRuby skip test
8
9
  Given that I create a valid app under "path/somewhere"
@@ -11,6 +12,7 @@ Feature: Adhearsion Ahn CLI (daemon)
11
12
  And I terminate the process using the pid file "adhearsion.pid"
12
13
  Then the exit status should be 0
13
14
 
15
+ @reconnect
14
16
  Scenario: Command daemon with pid option
15
17
  Given JRuby skip test
16
18
  Given that I create a valid app under "path/somewhere"
@@ -0,0 +1,19 @@
1
+ Feature: Adhearsion Ahn CLI (stop)
2
+ As an Adhearsion user
3
+ I want the ahn command to provide a 'restart' command
4
+ So that I can restart a running Adhearsion daemon
5
+
6
+ @reconnect
7
+ Scenario: Command restart with a missing or wrong pid
8
+ Given JRuby skip test
9
+ Given that I create a valid app under "path/somewhere"
10
+ When I run `ahn daemon path/somewhere --pid-file=ahn.pid`
11
+ And I run `ahn restart path/somewhere --pid-file=ahn2.pid`
12
+ Then the output should contain:
13
+ """
14
+ Could not read pid from the file
15
+ """
16
+ And the output should contain:
17
+ """
18
+ Starting Adhearsion
19
+ """
@@ -17,17 +17,15 @@ Feature: Adhearsion Ahn CLI (start)
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"
20
- And I terminate the interactive process
21
- Then the output should contain "Adhearsion::Console: Starting up..."
20
+ Then the output should contain "Adhearsion::Console: Launching Adhearsion Console"
22
21
  And the output should contain "AHN>"
23
- And the output should contain "Transitioning from booting to force_stop"
22
+ And the output should contain "Adhearsion shut down"
24
23
 
25
24
  Scenario: Command start with only path works properly
26
25
  Given JRuby skip test
27
26
  Given that I create a valid app under "path/somewhere"
28
27
  When I run `ahn start path/somewhere` interactively
29
28
  And I wait for output to contain "Starting connection to server"
30
- And I terminate the interactive process
31
- Then the output should contain "Adhearsion::Console: Starting up..."
29
+ Then the output should contain "Adhearsion::Console: Launching Adhearsion Console"
32
30
  And the output should contain "AHN>"
33
- And the output should contain "Transitioning from booting to force_stop"
31
+ And the output should contain "Adhearsion shut down"
@@ -3,6 +3,7 @@ Feature: Adhearsion Ahn CLI (stop)
3
3
  I want the ahn command to provide a 'stop' command
4
4
  So that I can stop a running Adhearsion daemon
5
5
 
6
+ @reconnect
6
7
  Scenario: Command stop with valid path and pid option
7
8
  Given JRuby skip test
8
9
  Given that I create a valid app under "path/somewhere"
@@ -14,6 +15,7 @@ Feature: Adhearsion Ahn CLI (stop)
14
15
  """
15
16
  And the file "ahn.pid" should not exist
16
17
 
18
+ @reconnect
17
19
  Scenario: Command stop with valid path and no pid option
18
20
  Given JRuby skip test
19
21
  Given that I create a valid app under "path/somewhere"
@@ -25,6 +27,7 @@ Feature: Adhearsion Ahn CLI (stop)
25
27
  """
26
28
  And the file "path/somewhere/adhearsion.pid" should not exist
27
29
 
30
+ @reconnect
28
31
  Scenario: Command stop with no options inside the app directory
29
32
  Given JRuby skip test
30
33
  Given that I create a valid app under "path/somewhere"
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  Then /^the file "([^"]*)" should contain each of these content parts:$/ do |file, content_parts|
2
4
  parts = content_parts.split
3
5
  parts.each do |p|
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'timeout'
2
4
 
3
5
  Then /^I should see the usage message$/ do
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Aruba
2
4
  module Api
3
5
  # output() blocks for stderr and stdout it seems
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'simplecov'
2
4
  require 'simplecov-rcov'
3
5
  class SimpleCov::Formatter::MergedFormatter
@@ -18,54 +20,14 @@ require 'cucumber'
18
20
  require 'aruba/cucumber'
19
21
  require 'adhearsion'
20
22
 
21
- module ChildProcess
22
- class << self
23
- def new(*args)
24
- case os
25
- when :unix, :macosx, :linux, :solaris, :bsd, :cygwin
26
- if posix_spawn?
27
- Unix::PosixSpawnProcess.new(args)
28
- elsif jruby?
29
- JRuby::Process.new(args)
30
- else
31
- Unix::ForkExecProcess.new(args)
32
- end
33
- when :windows
34
- Windows::Process.new(args)
35
- else
36
- raise Error, "unsupported OS #{os.inspect}"
37
- end
38
- end
39
- alias_method :build, :new
40
-
41
- def os
42
- @os ||= (
43
- require "rbconfig"
44
- host_os = RbConfig::CONFIG['host_os'].downcase
45
-
46
- case host_os
47
- when /linux/
48
- :linux
49
- when /darwin|mac os/
50
- :macosx
51
- when /mswin|msys|mingw32/
52
- :windows
53
- when /cygwin/
54
- :cygwin
55
- when /solaris|sunos/
56
- :solaris
57
- when /bsd/
58
- :bsd
59
- else
60
- raise Error, "unknown os: #{host_os.inspect}"
61
- end
62
- )
63
- end
64
- end # class << self
65
- end # ChildProcess
66
-
67
23
  Before do
68
24
  @aruba_timeout_seconds = ENV['ARUBA_TIMEOUT'] || RUBY_PLATFORM == 'java' ? 60 : 30
25
+ ENV['AHN_PUNCHBLOCK_RECONNECT_ATTEMPTS'] = '0'
26
+ ENV['AHN_PUNCHBLOCK_PORT'] = '1'
27
+ end
28
+
29
+ Before '@reconnect' do
30
+ ENV['AHN_PUNCHBLOCK_RECONNECT_ATTEMPTS'] = '100'
69
31
  end
70
32
 
71
33
  # TODO: check for name space / run issues
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  Given /^PENDING/ do
2
4
  pending
3
5
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
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.2, JRuby 1.6.5 or Rubinius 2.0." if RUBY_VERSION < "1.9.2"
2
4
 
3
5
  %w{
@@ -16,7 +18,7 @@ abort "ERROR: You are running Adhearsion on an unsupported version of Ruby (Ruby
16
18
  celluloid
17
19
 
18
20
  adhearsion/version
19
- adhearsion/foundation/all
21
+ adhearsion/foundation
20
22
  }.each { |f| require f }
21
23
 
22
24
  module Adhearsion
@@ -54,6 +56,7 @@ module Adhearsion
54
56
  def initialize_config
55
57
  _config = Configuration.new
56
58
  env = ENV['AHN_ENV'] || ENV['RAILS_ENV']
59
+ env = env.to_sym if env.respond_to? :to_sym
57
60
  env = nil unless _config.valid_environment? env
58
61
  _config.platform.environment = env if env
59
62
  _config
@@ -83,11 +86,6 @@ module Adhearsion
83
86
  Adhearsion::Process.state_name
84
87
  end
85
88
  end
86
-
87
- Hangup = Class.new StandardError # At the moment, we'll just use this to end a call-handling Thread
88
- PlaybackError = Class.new StandardError # Represents failure to play audio, such as when the sound file cannot be found
89
- RecordError = Class.new StandardError # Represents failure to record such as when a file cannot be written.
90
- ConfigurationError = Class.new StandardError # Error raised while trying to configure a non existent plugin
91
89
  end
92
90
 
93
91
  Celluloid.exception_handler { |e| Adhearsion::Events.trigger :exception, e }
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'thread'
2
4
 
3
5
  module Adhearsion
@@ -6,7 +8,9 @@ module Adhearsion
6
8
  #
7
9
  class Call
8
10
 
9
- ExpiredError = Class.new Celluloid::DeadActorError
11
+ Hangup = Class.new StandardError
12
+ ExpiredError = Class.new Celluloid::DeadActorError
13
+ CommandTimeout = Class.new StandardError
10
14
 
11
15
  include Celluloid
12
16
  include HasGuardedHandlers
@@ -15,7 +19,7 @@ module Adhearsion
15
19
  super.tap do |proxy|
16
20
  def proxy.method_missing(*args)
17
21
  super
18
- rescue Celluloid::DeadActorError => e
22
+ rescue Celluloid::DeadActorError
19
23
  raise ExpiredError, "This call is expired and is no longer accessible"
20
24
  end
21
25
  end
@@ -33,6 +37,7 @@ module Adhearsion
33
37
  @commands = CommandRegistry.new
34
38
  @variables = {}
35
39
  @controllers = []
40
+ @end_reason = nil
36
41
 
37
42
  self << offer if offer
38
43
  end
@@ -84,7 +89,20 @@ module Adhearsion
84
89
  throw :pass
85
90
  end
86
91
 
92
+ register_event_handler Punchblock::Event::Joined do |event|
93
+ target = event.other_call_id || event.mixer_name
94
+ signal :joined, target
95
+ throw :pass
96
+ end
97
+
98
+ register_event_handler Punchblock::Event::Unjoined do |event|
99
+ target = event.other_call_id || event.mixer_name
100
+ signal :unjoined, target
101
+ throw :pass
102
+ end
103
+
87
104
  on_end do |event|
105
+ logger.info "Call ended"
88
106
  clear_from_active_calls
89
107
  @end_reason = event.reason
90
108
  commands.terminate
@@ -121,6 +139,7 @@ module Adhearsion
121
139
 
122
140
  def hangup(headers = nil)
123
141
  return false unless active?
142
+ logger.info "Hanging up"
124
143
  @end_reason = true
125
144
  write_and_await_response Punchblock::Command::Hangup.new(:headers => headers)
126
145
  end
@@ -138,24 +157,51 @@ module Adhearsion
138
157
  # @param [Hash, Optional] options further options to be joined with
139
158
  #
140
159
  def join(target, options = {})
141
- case target
160
+ command = Punchblock::Command::Join.new join_options_with_target(target, options)
161
+ write_and_await_response command
162
+ end
163
+
164
+ ##
165
+ # Unjoins this call from another call or a mixer
166
+ #
167
+ # @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)
168
+ # @option target [String] call_id The call ID to unjoin from
169
+ # @option target [String] mixer_name The mixer to unjoin from
170
+ #
171
+ def unjoin(target)
172
+ command = Punchblock::Command::Unjoin.new join_options_with_target(target)
173
+ write_and_await_response command
174
+ end
175
+
176
+ def join_options_with_target(target, options = {})
177
+ options.merge(case target
142
178
  when Call
143
- options[:other_call_id] = target.id
179
+ { :other_call_id => target.id }
144
180
  when String
145
- options[:other_call_id] = target
181
+ { :other_call_id => target }
146
182
  when Hash
147
183
  abort ArgumentError.new "You cannot specify both a call ID and mixer name" if target.has_key?(:call_id) && target.has_key?(:mixer_name)
148
184
  target.tap do |t|
149
185
  t[:other_call_id] = t[:call_id]
150
186
  t.delete :call_id
151
187
  end
152
-
153
- options.merge! target
154
188
  else
155
189
  abort ArgumentError.new "Don't know how to join to #{target.inspect}"
190
+ end)
191
+ end
192
+
193
+ def wait_for_joined(expected_target)
194
+ target = nil
195
+ until target == expected_target do
196
+ target = wait :joined
197
+ end
198
+ end
199
+
200
+ def wait_for_unjoined(expected_target)
201
+ target = nil
202
+ until target == expected_target do
203
+ target = wait :unjoined
156
204
  end
157
- command = Punchblock::Command::Join.new options
158
- write_and_await_response command
159
205
  end
160
206
 
161
207
  def mute
@@ -169,20 +215,28 @@ module Adhearsion
169
215
  def write_and_await_response(command, timeout = 60)
170
216
  commands << command
171
217
  write_command command
172
- begin
173
- response = command.response timeout
174
- rescue Timeout::Error => e
175
- abort e
218
+
219
+ case (response = command.response timeout)
220
+ when Punchblock::ProtocolError
221
+ if response.name == :item_not_found
222
+ abort Hangup.new(@end_reason)
223
+ else
224
+ abort response
225
+ end
226
+ when Exception
227
+ abort response
176
228
  end
177
- abort response if response.is_a? Exception
229
+
178
230
  command
231
+ rescue Timeout::Error => e
232
+ abort CommandTimeout.new(command.to_s)
179
233
  end
180
234
 
181
235
  def write_command(command)
182
236
  abort Hangup.new(@end_reason) unless active? || command.is_a?(Punchblock::Command::Hangup)
183
237
  variables.merge! command.headers_hash if command.respond_to? :headers_hash
184
238
  logger.debug "Executing command #{command.inspect}"
185
- client.execute_command command, :call_id => id
239
+ client.execute_command command, :call_id => id, :async => true
186
240
  end
187
241
 
188
242
  def logger_id # :nodoc:
@@ -222,11 +276,11 @@ module Adhearsion
222
276
  end
223
277
 
224
278
  def pause_controllers
225
- controllers.each &:pause!
279
+ controllers.each(&:pause!)
226
280
  end
227
281
 
228
282
  def resume_controllers
229
- controllers.each &:resume!
283
+ controllers.each(&:resume!)
230
284
  end
231
285
 
232
286
  class CommandRegistry < ThreadSafeArray # :nodoc: