adhearsion 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/CHANGELOG.md +29 -0
  4. data/Gemfile +0 -2
  5. data/Guardfile +2 -2
  6. data/README.markdown +3 -6
  7. data/Rakefile +1 -1
  8. data/adhearsion.gemspec +7 -2
  9. data/features/cli_create.feature +85 -7
  10. data/features/plugin_generator.feature +4 -0
  11. data/features/step_definitions/app_generator_steps.rb +8 -1
  12. data/lib/adhearsion.rb +6 -3
  13. data/lib/adhearsion/call.rb +101 -30
  14. data/lib/adhearsion/call_controller.rb +40 -12
  15. data/lib/adhearsion/call_controller/dial.rb +119 -36
  16. data/lib/adhearsion/call_controller/input.rb +11 -5
  17. data/lib/adhearsion/call_controller/output.rb +47 -33
  18. data/lib/adhearsion/call_controller/output/async_player.rb +3 -2
  19. data/lib/adhearsion/call_controller/output/formatter.rb +7 -2
  20. data/lib/adhearsion/call_controller/output/player.rb +2 -2
  21. data/lib/adhearsion/call_controller/record.rb +16 -13
  22. data/lib/adhearsion/call_controller/utility.rb +3 -3
  23. data/lib/adhearsion/calls.rb +21 -8
  24. data/lib/adhearsion/cli_commands/ahn_command.rb +1 -0
  25. data/lib/adhearsion/configuration.rb +2 -2
  26. data/lib/adhearsion/console.rb +3 -2
  27. data/lib/adhearsion/generators.rb +7 -9
  28. data/lib/adhearsion/generators/app/app_generator.rb +12 -2
  29. data/lib/adhearsion/generators/app/templates/Gemfile.erb +7 -9
  30. data/lib/adhearsion/generators/app/templates/README.md +0 -19
  31. data/lib/adhearsion/generators/app/templates/adhearsion.erb +37 -0
  32. data/lib/adhearsion/generators/app/templates/config/environment.rb +6 -1
  33. data/lib/adhearsion/generators/app/templates/events.erb +18 -0
  34. data/lib/adhearsion/generators/app/templates/routes.erb +19 -0
  35. data/lib/adhearsion/generators/app/templates/{lib/simon_game.rb → simon_game.rb} +0 -0
  36. data/lib/adhearsion/generators/app/templates/{spec/call_controllers/simon_game_spec.rb → simon_game_spec.rb} +0 -0
  37. data/lib/adhearsion/generators/controller/controller_generator.rb +2 -2
  38. data/lib/adhearsion/generators/controller/templates/lib/{controller.rb → controller.rb.erb} +0 -0
  39. data/lib/adhearsion/generators/controller/templates/spec/{controller_spec.rb → controller_spec.rb.erb} +0 -0
  40. data/lib/adhearsion/generators/plugin/plugin_generator.rb +16 -15
  41. data/lib/adhearsion/generators/plugin/templates/gitignore +17 -0
  42. data/lib/adhearsion/generators/plugin/templates/spec/plugin-template/controller_methods_spec.rb.tt +1 -1
  43. data/lib/adhearsion/initializer.rb +14 -2
  44. data/lib/adhearsion/logging.rb +1 -0
  45. data/lib/adhearsion/outbound_call.rb +3 -7
  46. data/lib/adhearsion/punchblock_plugin/initializer.rb +3 -2
  47. data/lib/adhearsion/router/openended_route.rb +1 -1
  48. data/lib/adhearsion/router/route.rb +4 -3
  49. data/lib/adhearsion/version.rb +1 -1
  50. data/spec/adhearsion/call_controller/dial_spec.rb +811 -79
  51. data/spec/adhearsion/call_controller/output/formatter_spec.rb +13 -1
  52. data/spec/adhearsion/call_controller/output_spec.rb +35 -1
  53. data/spec/adhearsion/call_controller_spec.rb +174 -18
  54. data/spec/adhearsion/call_spec.rb +423 -39
  55. data/spec/adhearsion/calls_spec.rb +19 -3
  56. data/spec/adhearsion/outbound_call_spec.rb +88 -45
  57. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +3 -3
  58. data/spec/adhearsion/router/route_spec.rb +2 -2
  59. data/spec/spec_helper.rb +2 -0
  60. metadata +92 -77
  61. data/features/app_generator.feature +0 -49
  62. data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +0 -71
  63. data/lib/adhearsion/generators/plugin/templates/.gitignore +0 -9
@@ -28,7 +28,7 @@ module Adhearsion
28
28
  klass.start args
29
29
  end
30
30
 
31
- ##
31
+ #
32
32
  # Return a ordered list of task with their class
33
33
  #
34
34
  def mappings
@@ -38,20 +38,18 @@ module Adhearsion
38
38
  ##
39
39
  # Globally add a new generator class to +ahn generate+
40
40
  #
41
- # @param [Symbol] name
42
- # key name for generator mapping
43
- # @param [Class] klass
44
- # class of generator
41
+ # @param [Symbol] name key name for generator mapping
42
+ # @param [Class] klass class of generator
45
43
  #
46
44
  # @return [Hash] generator mappings
47
45
  #
48
46
  # @example
49
- # Adhearsion::Generators.add_generator :myplugin, MyPluginGenerator
47
+ # Adhearsion::Generators.add_generator :myplugin, MyPluginGenerator
50
48
  #
51
49
  def add_generator(name, klass)
52
50
  mappings[name] = klass
53
51
  end
54
52
 
55
- end#class << self
56
- end#module
57
- end#module
53
+ end
54
+ end
55
+ end
@@ -4,19 +4,29 @@ module Adhearsion
4
4
  module Generators
5
5
  class AppGenerator < Generator
6
6
 
7
- BASEDIRS = %w( config lib script spec )
8
- EMPTYDIRS = %w( spec/support )
7
+ BASEDIRS = %w( config script spec )
8
+ EMPTYDIRS = %w( app/call_controllers lib spec/support spec/call_controllers )
9
+
10
+ class_option :empty, type: :boolean
9
11
 
10
12
  def setup_project
11
13
  self.destination_root = @generator_name
12
14
  BASEDIRS.each { |dir| directory dir }
13
15
  EMPTYDIRS.each { |dir| empty_directory dir }
16
+
14
17
  template "Gemfile.erb", "Gemfile"
18
+ template "adhearsion.erb", "config/adhearsion.rb"
19
+ template "events.erb", "config/events.rb"
20
+ template "routes.erb", "config/routes.rb"
15
21
  copy_file "gitignore", ".gitignore"
16
22
  copy_file "rspec", ".rspec"
17
23
  copy_file "Procfile"
18
24
  copy_file "Rakefile"
19
25
  copy_file "README.md"
26
+ unless options[:empty]
27
+ copy_file "simon_game.rb", "app/call_controllers/simon_game.rb"
28
+ copy_file "simon_game_spec.rb", "spec/call_controllers/simon_game_spec.rb"
29
+ end
20
30
  chmod "script/ahn", 0755
21
31
  end
22
32
  end
@@ -2,22 +2,20 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'adhearsion', '~> <%= Adhearsion::VERSION.split('.')[0,2].join('.') %>'
4
4
 
5
+ # Adhearsion depends on the Punchblock library, but here you can specify the major version your application depends on.
6
+ # Exercise care when updating the major version, since you might encounter API compatability in parts of your Adhearsion application that rely on the Punchblock API.
7
+ # On occasion, an update of Adhearsion might necessitate an update to Punchblock. You will have to manually allow that here, and take care in the upgrade.
8
+ gem 'punchblock', '~> <%= require "punchblock/version"; Punchblock::VERSION.split('.')[0,2].join('.') %>'
9
+
5
10
  # This is here by default due to deprecation of #ask and #menu.
6
11
  # See http://adhearsion.com/docs/common_problems#toc_3 for details
7
12
  gem 'adhearsion-asr'
8
13
 
9
14
  #
10
- # Here are some example plugins you might like to use. Simply
11
- # uncomment them and run `bundle install`.
15
+ # Check http://ahnhub.com for a list of plugins you can use in your app.
16
+ # To use them, simply add them here and run `bundle install`.
12
17
  #
13
18
 
14
- # gem 'adhearsion-asterisk'
15
- # gem 'adhearsion-rails'
16
- # gem 'adhearsion-activerecord'
17
- # gem 'adhearsion-ldap'
18
- # gem 'adhearsion-xmpp'
19
- # gem 'adhearsion-drb'
20
-
21
19
  group :development, :test do
22
20
  gem 'rspec'
23
21
  end
@@ -17,8 +17,6 @@ If you are using Asterisk 1.8, you will need to add an additional context with t
17
17
 
18
18
  ## FreeSWITCH
19
19
 
20
- ### With mod_rayo (recommended)
21
-
22
20
  * Ensure that mod_rayo is installed and configured according to its' documentation.
23
21
  * Add an extension to your dialplan like so:
24
22
 
@@ -32,23 +30,6 @@ If you are using Asterisk 1.8, you will need to add an additional context with t
32
30
 
33
31
  * Connect Adhearsion via XMPP using the Rayo protocol, as per the sample config.
34
32
 
35
- ### With Punchblock's FreeSWITCH mode (deprecated)
36
-
37
- * Ensure that mod_event_socket is installed, and configure it in autoload_configs/event_socket.conf.xml to taste
38
- * Add an extension to your dialplan like so:
39
-
40
- ```xml
41
- <extension name='Adhearsion'>
42
- <condition field="destination_number" expression="^10$">
43
- <action application="set" data="hangup_after_bridge=false"/>
44
- <action application="set" data="park_after_bridge=true"/>
45
- <action application='rayo'/>
46
- </condition>
47
- </extension>
48
- ```
49
-
50
- * Connect Adhearsion via EventSocket, as per the sample config.
51
-
52
33
  ## Voxeo PRISM
53
34
 
54
35
  Install the [rayo-server](https://github.com/rayo/rayo-server) app into PRISM 11 and follow the [configuration guide](https://github.com/rayo/rayo-server/wiki/Single-node-and-cluster-configuration-reference).
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ Adhearsion.config do |config|
4
+ <% unless options[:empty] %>
5
+ # Centralized way to specify any Adhearsion platform or plugin configuration
6
+ # - Execute rake config:show to view the active configuration values
7
+ #
8
+ # To update a plugin configuration you can write either:
9
+ #
10
+ # * Option 1
11
+ # Adhearsion.config.<plugin-name> do |config|
12
+ # config.<key> = <value>
13
+ # end
14
+ #
15
+ # * Option 2
16
+ # Adhearsion.config do |config|
17
+ # config.<plugin-name>.<key> = <value>
18
+ # end
19
+ <% end %>
20
+ config.development do |dev|
21
+ dev.platform.logging.level = :debug
22
+ end
23
+
24
+ ##
25
+ # Use with Rayo (eg Voxeo PRISM or FreeSWITCH mod_rayo)
26
+ #
27
+ # config.punchblock.username = "usera@freeswitch.local-dev.mojolingo.com" # Your XMPP JID for use with Rayo
28
+ # config.punchblock.password = "1" # Your XMPP password
29
+
30
+ ##
31
+ # Use with Asterisk
32
+ #
33
+ # config.punchblock.platform = :asterisk # Use Asterisk
34
+ # config.punchblock.username = "manager" # Your AMI username
35
+ # config.punchblock.password = "password" # Your AMI password
36
+ # config.punchblock.host = "asterisk.local-dev.mojolingo.com" # Your AMI host
37
+ end
@@ -2,4 +2,9 @@
2
2
 
3
3
  require 'bundler'
4
4
  Bundler.setup
5
- Bundler.require
5
+
6
+ require 'adhearsion'
7
+
8
+ Bundler.require(:default, Adhearsion.environment)
9
+
10
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '../app/')))
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ Adhearsion::Events.draw do
4
+ <% unless options[:empty] %>
5
+ # Register global handlers for events
6
+ #
7
+ # eg. Handling Punchblock events
8
+ # punchblock do |event|
9
+ # ...
10
+ # end
11
+ #
12
+ # eg Handling PeerStatus AMI events
13
+ # ami :name => 'PeerStatus' do |event|
14
+ # ...
15
+ # end
16
+ #
17
+ <% end %>
18
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ <% unless options[:empty] %>
4
+ require 'call_controllers/simon_game'
5
+ <% end %>
6
+
7
+ Adhearsion.router do
8
+ <% if options[:empty] %>
9
+ route 'default' do
10
+
11
+ end
12
+ <% else %>
13
+ #
14
+ # Specify your call routes, directing calls with particular attributes to a controller
15
+ #
16
+
17
+ route 'default', SimonGame
18
+ <% end %>
19
+ end
@@ -15,8 +15,8 @@ module Adhearsion
15
15
  self.destination_root = '.'
16
16
  empty_directory 'lib'
17
17
  empty_directory 'spec'
18
- template 'lib/controller.rb', "lib/#{@controller_name.underscore}.rb"
19
- template 'spec/controller_spec.rb', "spec/#{@controller_name.underscore}_spec.rb"
18
+ template 'lib/controller.rb.erb', "lib/#{@controller_name.underscore}.rb"
19
+ template 'spec/controller_spec.rb.erb', "spec/#{@controller_name.underscore}_spec.rb"
20
20
  end
21
21
 
22
22
  end
@@ -13,25 +13,26 @@ module Adhearsion
13
13
  def create_plugin
14
14
  @plugin_file = @plugin_name.underscore
15
15
  @plugin_name = @plugin_name.camelize
16
- self.destination_root = '.'
16
+ self.destination_root = @plugin_file
17
17
 
18
- empty_directory @plugin_file
19
- empty_directory "#{@plugin_file}/lib"
20
- empty_directory "#{@plugin_file}/lib/#{@plugin_file}"
21
- empty_directory "#{@plugin_file}/spec"
18
+ empty_directory "lib"
19
+ empty_directory "lib/#{@plugin_file}"
20
+ empty_directory "spec"
22
21
 
23
- template 'plugin-template.gemspec.tt', "#{@plugin_file}/#{@plugin_file}.gemspec"
24
- template 'Rakefile.tt', "#{@plugin_file}/Rakefile"
25
- template 'README.md.tt', "#{@plugin_file}/README.md"
26
- template 'Gemfile.tt', "#{@plugin_file}/Gemfile"
22
+ copy_file "gitignore", ".gitignore"
27
23
 
28
- template 'lib/plugin-template.rb.tt', "#{@plugin_file}/lib/#{@plugin_file}.rb"
29
- template 'lib/plugin-template/version.rb.tt', "#{@plugin_file}/lib/#{@plugin_file}/version.rb"
30
- template 'lib/plugin-template/plugin.rb.tt', "#{@plugin_file}/lib/#{@plugin_file}/plugin.rb"
31
- template 'lib/plugin-template/controller_methods.rb.tt', "#{@plugin_file}/lib/#{@plugin_file}/controller_methods.rb"
24
+ template 'plugin-template.gemspec.tt', "#{@plugin_file}.gemspec"
25
+ template 'Rakefile.tt', "Rakefile"
26
+ template 'README.md.tt', "README.md"
27
+ template 'Gemfile.tt', "Gemfile"
32
28
 
33
- template 'spec/spec_helper.rb.tt', "#{@plugin_file}/spec/spec_helper.rb"
34
- template 'spec/plugin-template/controller_methods_spec.rb.tt', "#{@plugin_file}/spec/#{@plugin_file}/controller_methods_spec.rb"
29
+ template 'lib/plugin-template.rb.tt', "lib/#{@plugin_file}.rb"
30
+ template 'lib/plugin-template/version.rb.tt', "lib/#{@plugin_file}/version.rb"
31
+ template 'lib/plugin-template/plugin.rb.tt', "lib/#{@plugin_file}/plugin.rb"
32
+ template 'lib/plugin-template/controller_methods.rb.tt', "lib/#{@plugin_file}/controller_methods.rb"
33
+
34
+ template 'spec/spec_helper.rb.tt', "spec/spec_helper.rb"
35
+ template 'spec/plugin-template/controller_methods_spec.rb.tt', "spec/#{@plugin_file}/controller_methods_spec.rb"
35
36
  end
36
37
 
37
38
  end
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -16,7 +16,7 @@ module <%= @plugin_name %>
16
16
 
17
17
  describe "#greet" do
18
18
  it "greets with the correct parameter" do
19
- subject.expects(:play).once.with("Hello, Luca")
19
+ subject.should_receive(:play).once.with("Hello, Luca")
20
20
  subject.greet "Luca"
21
21
  end
22
22
  end
@@ -34,7 +34,7 @@ module Adhearsion
34
34
  @mode = options[:mode]
35
35
  @pid_file = options[:pid_file].nil? ? ENV['PID_FILE'] : options[:pid_file]
36
36
  @loaded_init_files = options[:loaded_init_files]
37
- Adhearsion.ahn_root = '.'
37
+ Adhearsion.root = '.'
38
38
  end
39
39
 
40
40
  def start
@@ -42,6 +42,8 @@ module Adhearsion
42
42
  resolve_pid_file_path
43
43
  load_lib_folder
44
44
  load_config_file
45
+ load_events_file
46
+ load_routes_file
45
47
  initialize_log_paths
46
48
 
47
49
  if should_daemonize?
@@ -195,6 +197,16 @@ module Adhearsion
195
197
  require "#{Adhearsion.config.root}/config/adhearsion.rb"
196
198
  end
197
199
 
200
+ def load_events_file
201
+ path = "#{Adhearsion.config.root}/config/events.rb"
202
+ require path if File.exists?(path)
203
+ end
204
+
205
+ def load_routes_file
206
+ path = "#{Adhearsion.config.root}/config/routes.rb"
207
+ require path if File.exists?(path)
208
+ end
209
+
198
210
  def init_get_logging_appenders
199
211
  @file_loggers ||= memoize_logging_appenders
200
212
  end
@@ -249,7 +261,7 @@ module Adhearsion
249
261
  end
250
262
 
251
263
  def launch_console
252
- Adhearsion::Process.important_threads << Thread.new do
264
+ Thread.new do
253
265
  catching_standard_errors do
254
266
  Adhearsion::Console.run
255
267
  end
@@ -88,6 +88,7 @@ module Adhearsion
88
88
  'stdout',
89
89
  :layout => ::Logging.layouts.pattern(
90
90
  :pattern => adhearsion_pattern,
91
+ :date_pattern => "%Y-%m-%d %H:%M:%S.%L",
91
92
  :color_scheme => 'bright'
92
93
  ),
93
94
  :auto_flushing => 2,
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Adhearsion
4
4
  class OutboundCall < Call
5
- execute_block_on_receiver :register_handler, :register_tmp_handler, :register_handler_with_priority, :register_event_handler, :on_joined, :on_unjoined, :on_end, :execute_controller, :on_answer, :execute_controller_or_router_on_answer
5
+ execute_block_on_receiver :on_answer, :execute_controller_or_router_on_answer, *execute_block_on_receiver
6
6
 
7
7
  attr_reader :dial_command
8
8
 
@@ -73,7 +73,7 @@ module Adhearsion
73
73
  wait_timeout = 60
74
74
  end
75
75
 
76
- write_and_await_response(Punchblock::Command::Dial.new(options), wait_timeout).tap do |dial_command|
76
+ write_and_await_response(Punchblock::Command::Dial.new(options), wait_timeout, true).tap do |dial_command|
77
77
  @dial_command = dial_command
78
78
  Adhearsion.active_calls << current_actor
79
79
  Adhearsion::Events.trigger_immediately :call_dialed, current_actor
@@ -95,15 +95,11 @@ module Adhearsion
95
95
  def run_router_on_answer
96
96
  register_event_handler Punchblock::Event::Answered do |event|
97
97
  run_router
98
- throw :pass
99
98
  end
100
99
  end
101
100
 
102
101
  def on_answer(&block)
103
- register_event_handler Punchblock::Event::Answered do |event|
104
- block.call event
105
- throw :pass
106
- end
102
+ register_event_handler Punchblock::Event::Answered, &block
107
103
  end
108
104
 
109
105
  def execute_controller_or_router_on_answer(controller, metadata = {}, &controller_block)
@@ -127,7 +127,8 @@ module Adhearsion
127
127
 
128
128
  def dispatch_offer(offer)
129
129
  catching_standard_errors do
130
- call = Adhearsion.active_calls.from_offer offer
130
+ call = Call.new(offer)
131
+ Adhearsion.active_calls << call
131
132
  case Adhearsion::Process.state_name
132
133
  when :booting, :rejecting
133
134
  logger.info "Declining call because the process is not yet running."
@@ -144,7 +145,7 @@ module Adhearsion
144
145
  if call = Adhearsion.active_calls[event.target_call_id]
145
146
  call.async.deliver_message event
146
147
  else
147
- logger.error "Event received for inactive call #{event.target_call_id}: #{event.inspect}"
148
+ logger.warn "Event received for inactive call #{event.target_call_id}: #{event.inspect}"
148
149
  end
149
150
  end
150
151
 
@@ -8,7 +8,7 @@ module Adhearsion
8
8
  end
9
9
 
10
10
  def dispatch(call, callback = nil)
11
- call[:ahn_prevent_hangup] = true
11
+ call.auto_hangup = false
12
12
  super
13
13
  end
14
14
  end
@@ -38,10 +38,11 @@ module Adhearsion
38
38
 
39
39
  call.execute_controller controller, lambda { |call_actor|
40
40
  begin
41
- if call_actor[:ahn_prevent_hangup]
42
- logger.info "Call routing completed, keeping the call alive at controller/router request."
43
- else
41
+ if call_actor.auto_hangup
42
+ logger.info "Call routing completed. Hanging up now..."
44
43
  call_actor.hangup
44
+ else
45
+ logger.info "Call routing completed, keeping the call alive at controller/router request."
45
46
  end
46
47
  rescue Call::Hangup, Call::ExpiredError
47
48
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Adhearsion
4
- VERSION = '2.4.0'
4
+ VERSION = '2.5.0'
5
5
  end