adhearsion 1.2.6 → 2.0.0.alpha1
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.
- data/.gitignore +17 -10
- data/CHANGELOG.md +273 -0
- data/Gemfile +1 -1
- data/Guardfile +17 -0
- data/README.markdown +61 -9
- data/Rakefile +16 -48
- data/adhearsion.gemspec +21 -7
- data/bin/ahn +3 -1
- data/cucumber.yml +4 -0
- data/features/app_generator.feature +42 -0
- data/features/cli.feature +108 -0
- data/features/step_definitions/app_generator_steps.rb +6 -0
- data/features/step_definitions/cli_steps.rb +74 -0
- data/features/support/aruba_helper.rb +22 -0
- data/features/support/env.rb +37 -0
- data/features/support/utils.rb +8 -0
- data/lib/adhearsion.rb +85 -41
- data/lib/adhearsion/call.rb +176 -0
- data/lib/adhearsion/call_controller.rb +134 -0
- data/lib/adhearsion/call_controller/dial.rb +70 -0
- data/lib/adhearsion/call_controller/input.rb +173 -0
- data/lib/adhearsion/call_controller/menu.rb +124 -0
- data/lib/adhearsion/call_controller/output.rb +267 -0
- data/lib/adhearsion/call_controller/record.rb +42 -0
- data/lib/adhearsion/call_controller/utility.rb +60 -0
- data/lib/adhearsion/calls.rb +81 -0
- data/lib/adhearsion/cli.rb +1 -3
- data/lib/adhearsion/cli_commands.rb +142 -0
- data/lib/adhearsion/configuration.rb +149 -0
- data/lib/adhearsion/console.rb +19 -8
- data/lib/adhearsion/dialplan_controller.rb +9 -0
- data/lib/adhearsion/events.rb +84 -0
- data/lib/adhearsion/foundation/all.rb +0 -7
- data/lib/adhearsion/foundation/custom_daemonizer.rb +4 -6
- data/lib/adhearsion/foundation/exception_handler.rb +9 -0
- data/lib/adhearsion/foundation/object.rb +26 -8
- data/lib/adhearsion/foundation/synchronized_hash.rb +3 -6
- data/lib/adhearsion/foundation/thread_safety.rb +17 -1
- data/lib/adhearsion/generators/app/app_generator.rb +4 -13
- data/lib/adhearsion/generators/app/templates/Gemfile +10 -5
- data/lib/adhearsion/generators/app/templates/Procfile +1 -0
- data/lib/adhearsion/generators/app/templates/README.md +28 -0
- data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +41 -0
- data/lib/adhearsion/generators/app/templates/{components/simon_game → lib}/simon_game.rb +6 -18
- data/lib/adhearsion/generators/app/templates/script/ahn +2 -2
- data/lib/adhearsion/initializer.rb +151 -293
- data/lib/adhearsion/initializer/logging.rb +33 -0
- data/lib/adhearsion/logging.rb +65 -69
- data/lib/adhearsion/menu_dsl.rb +15 -0
- data/lib/adhearsion/menu_dsl/calculated_match.rb +39 -0
- data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +41 -0
- data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +18 -0
- data/lib/adhearsion/menu_dsl/match_calculator.rb +36 -0
- data/lib/adhearsion/{voip/menu_state_machine/menu_class.rb → menu_dsl/menu.rb} +38 -40
- data/lib/adhearsion/menu_dsl/menu_builder.rb +69 -0
- data/lib/adhearsion/menu_dsl/range_match_calculator.rb +55 -0
- data/lib/adhearsion/menu_dsl/string_match_calculator.rb +21 -0
- data/lib/adhearsion/outbound_call.rb +64 -0
- data/lib/adhearsion/plugin.rb +319 -0
- data/lib/adhearsion/plugin/collection.rb +19 -0
- data/lib/adhearsion/plugin/initializer.rb +37 -0
- data/lib/adhearsion/plugin/methods_container.rb +6 -0
- data/lib/adhearsion/process.rb +94 -0
- data/lib/adhearsion/punchblock_plugin.rb +29 -0
- data/lib/adhearsion/punchblock_plugin/initializer.rb +137 -0
- data/lib/adhearsion/router.rb +30 -0
- data/lib/adhearsion/router/route.rb +42 -0
- data/lib/adhearsion/script_ahn_loader.rb +2 -2
- data/lib/adhearsion/tasks.rb +14 -9
- data/lib/adhearsion/tasks/configuration.rb +26 -0
- data/lib/adhearsion/tasks/plugins.rb +17 -0
- data/lib/adhearsion/version.rb +8 -14
- data/spec/adhearsion/call_controller/dial_spec.rb +138 -0
- data/spec/adhearsion/call_controller/input_spec.rb +278 -0
- data/spec/adhearsion/call_controller/menu_spec.rb +120 -0
- data/spec/adhearsion/call_controller/output_spec.rb +466 -0
- data/spec/adhearsion/call_controller/record_spec.rb +125 -0
- data/spec/adhearsion/call_controller_spec.rb +395 -0
- data/spec/adhearsion/call_spec.rb +438 -0
- data/spec/adhearsion/calls_spec.rb +47 -0
- data/spec/adhearsion/configuration_spec.rb +308 -0
- data/spec/adhearsion/dialplan_controller_spec.rb +26 -0
- data/spec/adhearsion/events_spec.rb +112 -0
- data/spec/adhearsion/initializer/logging_spec.rb +58 -0
- data/spec/adhearsion/initializer_spec.rb +209 -122
- data/spec/adhearsion/logging_spec.rb +58 -47
- data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +56 -0
- data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +57 -0
- data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +33 -0
- data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +13 -0
- data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +118 -0
- data/spec/adhearsion/menu_dsl/menu_spec.rb +210 -0
- data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +28 -0
- data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +36 -0
- data/spec/adhearsion/menu_dsl_spec.rb +12 -0
- data/spec/adhearsion/outbound_call_spec.rb +174 -0
- data/spec/adhearsion/plugin_spec.rb +489 -0
- data/spec/adhearsion/process_spec.rb +34 -0
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +294 -0
- data/spec/adhearsion/router/route_spec.rb +99 -0
- data/spec/adhearsion/router_spec.rb +106 -0
- data/spec/adhearsion_spec.rb +46 -0
- data/spec/spec_helper.rb +14 -14
- data/spec/support/call_controller_test_helpers.rb +48 -0
- data/spec/support/initializer_stubs.rb +8 -13
- data/spec/support/punchblock_mocks.rb +6 -0
- metadata +255 -253
- data/CHANGELOG +0 -174
- data/bin/ahnctl +0 -68
- data/bin/jahn +0 -43
- data/examples/asterisk_manager_interface/standalone.rb +0 -51
- data/lib/adhearsion/commands.rb +0 -302
- data/lib/adhearsion/component_manager.rb +0 -278
- data/lib/adhearsion/component_manager/component_tester.rb +0 -54
- data/lib/adhearsion/component_manager/spec_framework.rb +0 -18
- data/lib/adhearsion/events_support.rb +0 -65
- data/lib/adhearsion/foundation/blank_slate.rb +0 -3
- data/lib/adhearsion/foundation/event_socket.rb +0 -205
- data/lib/adhearsion/foundation/future_resource.rb +0 -36
- data/lib/adhearsion/foundation/metaprogramming.rb +0 -17
- data/lib/adhearsion/foundation/numeric.rb +0 -13
- data/lib/adhearsion/foundation/pseudo_guid.rb +0 -10
- data/lib/adhearsion/foundation/relationship_properties.rb +0 -42
- data/lib/adhearsion/foundation/string.rb +0 -26
- data/lib/adhearsion/generators/app/templates/.ahnrc +0 -34
- data/lib/adhearsion/generators/app/templates/README +0 -8
- data/lib/adhearsion/generators/app/templates/components/ami_remote/ami_remote.rb +0 -15
- data/lib/adhearsion/generators/app/templates/components/disabled/HOW_TO_ENABLE +0 -7
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/README.markdown +0 -47
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.rb +0 -34
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.yml +0 -12
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/README.markdown +0 -3
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +0 -11
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
- data/lib/adhearsion/generators/app/templates/config/startup.rb +0 -81
- data/lib/adhearsion/generators/app/templates/dialplan.rb +0 -3
- data/lib/adhearsion/generators/app/templates/events.rb +0 -33
- data/lib/adhearsion/host_definitions.rb +0 -67
- data/lib/adhearsion/initializer/asterisk.rb +0 -86
- data/lib/adhearsion/initializer/configuration.rb +0 -324
- data/lib/adhearsion/initializer/database.rb +0 -60
- data/lib/adhearsion/initializer/drb.rb +0 -31
- data/lib/adhearsion/initializer/freeswitch.rb +0 -22
- data/lib/adhearsion/initializer/ldap.rb +0 -57
- data/lib/adhearsion/initializer/rails.rb +0 -41
- data/lib/adhearsion/initializer/xmpp.rb +0 -42
- data/lib/adhearsion/tasks/components.rb +0 -32
- data/lib/adhearsion/tasks/database.rb +0 -5
- data/lib/adhearsion/tasks/deprecations.rb +0 -59
- data/lib/adhearsion/tasks/generating.rb +0 -20
- data/lib/adhearsion/tasks/lint.rb +0 -4
- data/lib/adhearsion/voip/asterisk.rb +0 -4
- data/lib/adhearsion/voip/asterisk/agi_server.rb +0 -121
- data/lib/adhearsion/voip/asterisk/commands.rb +0 -1966
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +0 -140
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +0 -102
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +0 -250
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +0 -240
- data/lib/adhearsion/voip/asterisk/config_manager.rb +0 -64
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -697
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +0 -1681
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +0 -341
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +0 -78
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +0 -87
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +0 -80
- data/lib/adhearsion/voip/call.rb +0 -521
- data/lib/adhearsion/voip/call_routing.rb +0 -64
- data/lib/adhearsion/voip/commands.rb +0 -17
- data/lib/adhearsion/voip/constants.rb +0 -39
- data/lib/adhearsion/voip/conveniences.rb +0 -18
- data/lib/adhearsion/voip/dial_plan.rb +0 -252
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +0 -151
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +0 -37
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +0 -27
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +0 -124
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +0 -69
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +0 -16
- data/lib/adhearsion/voip/dsl/numerical_string.rb +0 -128
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +0 -48
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +0 -58
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +0 -129
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +0 -38
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +0 -195
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +0 -80
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +0 -123
- data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +0 -57
- data/lib/adhearsion/xmpp/connection.rb +0 -61
- data/lib/theatre.rb +0 -147
- data/lib/theatre/README.markdown +0 -64
- data/lib/theatre/callback_definition_loader.rb +0 -86
- data/lib/theatre/guid.rb +0 -23
- data/lib/theatre/invocation.rb +0 -131
- data/lib/theatre/namespace_manager.rb +0 -153
- data/lib/theatre/version.rb +0 -2
- data/spec/adhearsion/cli_spec.rb +0 -306
- data/spec/adhearsion/component_manager_spec.rb +0 -292
- data/spec/adhearsion/constants_spec.rb +0 -8
- data/spec/adhearsion/drb_spec.rb +0 -65
- data/spec/adhearsion/fixtures/dialplan.rb +0 -3
- data/spec/adhearsion/foundation/event_socket_spec.rb +0 -168
- data/spec/adhearsion/host_definitions_spec.rb +0 -79
- data/spec/adhearsion/initializer/configuration_spec.rb +0 -291
- data/spec/adhearsion/initializer/loading_spec.rb +0 -154
- data/spec/adhearsion/initializer/paths_spec.rb +0 -74
- data/spec/adhearsion/relationship_properties_spec.rb +0 -54
- data/spec/adhearsion/voip/asterisk/agi_server_spec.rb +0 -473
- data/spec/adhearsion/voip/asterisk/ami/ami_spec.rb +0 -550
- data/spec/adhearsion/voip/asterisk/ami/lexer/ami_fixtures.yml +0 -30
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story +0 -291
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story.rb +0 -241
- data/spec/adhearsion/voip/asterisk/ami/lexer/story_helper.rb +0 -124
- data/spec/adhearsion/voip/asterisk/commands_spec.rb +0 -3241
- data/spec/adhearsion/voip/asterisk/config_file_generators/agents_spec.rb +0 -251
- data/spec/adhearsion/voip/asterisk/config_file_generators/queues_spec.rb +0 -323
- data/spec/adhearsion/voip/asterisk/config_file_generators/voicemail_spec.rb +0 -306
- data/spec/adhearsion/voip/asterisk/config_manager_spec.rb +0 -127
- data/spec/adhearsion/voip/asterisk/menu_command/calculated_match_spec.rb +0 -109
- data/spec/adhearsion/voip/asterisk/menu_command/matchers_spec.rb +0 -97
- data/spec/adhearsion/voip/call_routing_spec.rb +0 -125
- data/spec/adhearsion/voip/dialplan_manager_spec.rb +0 -468
- data/spec/adhearsion/voip/dsl/dialing_dsl_spec.rb +0 -270
- data/spec/adhearsion/voip/dsl/dispatcher_spec.rb +0 -82
- data/spec/adhearsion/voip/dsl/dispatcher_spec_helper.rb +0 -45
- data/spec/adhearsion/voip/dsl/parser_spec.rb +0 -69
- data/spec/adhearsion/voip/freeswitch/basic_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/inbound_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/oes_server_spec.rb +0 -9
- data/spec/adhearsion/voip/numerical_string_spec.rb +0 -61
- data/spec/adhearsion/voip/phone_number_spec.rb +0 -45
- data/spec/support/the_following_code.rb +0 -3
- data/spec/theatre/dsl_examples/simple_before_call.rb +0 -7
- data/spec/theatre/dsl_spec.rb +0 -69
- data/spec/theatre/invocation_spec.rb +0 -182
- data/spec/theatre/namespace_spec.rb +0 -125
- data/spec/theatre/spec_helper_spec.rb +0 -28
- data/spec/theatre/theatre_class_spec.rb +0 -148
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
|
|
3
|
+
module Adhearsion
|
|
4
|
+
##
|
|
5
|
+
# This manages the list of calls the Adhearsion service receives
|
|
6
|
+
class Calls
|
|
7
|
+
attr_reader :semaphore, :calls
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@semaphore = Monitor.new
|
|
11
|
+
@calls = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def from_offer(offer)
|
|
15
|
+
Call.new(offer).tap do |call|
|
|
16
|
+
self << call
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def <<(call)
|
|
21
|
+
atomically { calls[call.id] = call }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def any?
|
|
25
|
+
atomically { !calls.empty? }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def size
|
|
29
|
+
atomically { calls.size }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def remove_inactive_call(call)
|
|
33
|
+
atomically { calls.delete call.id }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Searches all active calls by their id
|
|
37
|
+
def find(id)
|
|
38
|
+
atomically { calls[id] }
|
|
39
|
+
end
|
|
40
|
+
alias :[] :find
|
|
41
|
+
|
|
42
|
+
def clear!
|
|
43
|
+
atomically { calls.clear }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def with_tag(tag)
|
|
47
|
+
atomically do
|
|
48
|
+
calls.inject([]) do |calls_with_tag,(key,call)|
|
|
49
|
+
call.tagged_with?(tag) ? calls_with_tag << call : calls_with_tag
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def each(&block)
|
|
55
|
+
atomically { calls.values.each &block }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def each_pair
|
|
59
|
+
calls.each_pair { |id, call| yield id, call }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_a
|
|
63
|
+
calls.values
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def to_h
|
|
67
|
+
calls
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def method_missing(m, *args)
|
|
71
|
+
atomically { calls.send m.to_sym, *args }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def atomically(&block)
|
|
77
|
+
semaphore.synchronize(&block)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
end
|
data/lib/adhearsion/cli.rb
CHANGED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'adhearsion/script_ahn_loader'
|
|
3
|
+
require 'thor'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module CLI
|
|
7
|
+
class AhnCommand < Thor
|
|
8
|
+
map %w(-h --h -help --help) => :help
|
|
9
|
+
map %w(-v --v -version --version) => :version
|
|
10
|
+
map %w(-) => :start
|
|
11
|
+
|
|
12
|
+
check_unknown_options!
|
|
13
|
+
|
|
14
|
+
def self.exit_on_failure?
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc "create /path/to/directory", "Create a new Adhearsion application under the given path"
|
|
19
|
+
def create(path)
|
|
20
|
+
require 'adhearsion/generators'
|
|
21
|
+
require 'adhearsion/generators/app/app_generator'
|
|
22
|
+
Adhearsion::Generators::AppGenerator.start
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc "version", "Shows Adhearsion version"
|
|
26
|
+
def version
|
|
27
|
+
say "Adhearsion v#{Adhearsion::VERSION}"
|
|
28
|
+
exit 0
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc "start </path/to/directory>", "Start the Adhearsion server in the foreground with a console"
|
|
32
|
+
def start(path = nil)
|
|
33
|
+
start_app path, :console
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
desc "daemon </path/to/directory>", "Start the Adhearsion server in the background"
|
|
37
|
+
method_option :pidfile, :type => :string, :aliases => %w(--pid-file)
|
|
38
|
+
def daemon(path = nil)
|
|
39
|
+
start_app path, :daemon, options[:pidfile]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
desc "stop </path/to/directory>", "Stop a running Adhearsion server"
|
|
43
|
+
method_option :pidfile, :type => :string, :aliases => %w(--pid-file)
|
|
44
|
+
def stop(path = nil)
|
|
45
|
+
execute_from_app_dir! path, ARGV
|
|
46
|
+
|
|
47
|
+
pid_file = if options[:pidfile]
|
|
48
|
+
File.expand_path File.exists?(File.expand_path(options[:pidfile])) ?
|
|
49
|
+
options[:pidfile] :
|
|
50
|
+
File.join(path, options[:pidfile])
|
|
51
|
+
else
|
|
52
|
+
path + '/adhearsion.pid'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
begin
|
|
56
|
+
pid = File.read(pid_file).to_i
|
|
57
|
+
rescue
|
|
58
|
+
raise CLIException, "Could not read pid file #{pid_file}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
raise CLIException, "Could not read pid" if pid.nil?
|
|
62
|
+
|
|
63
|
+
say "Stopping Adhearsion server at #{path} with pid #{pid}"
|
|
64
|
+
waiting_timeout = Time.now + 15
|
|
65
|
+
begin
|
|
66
|
+
::Process.kill "TERM", pid
|
|
67
|
+
sleep 0.25 while process_exists?(pid) && Time.now < waiting_timeout
|
|
68
|
+
::Process.kill "KILL", pid
|
|
69
|
+
rescue Errno::ESRCH
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
desc "restart </path/to/directory>", "Restart the Adhearsion server"
|
|
74
|
+
method_option :pidfile, :type => :string, :aliases => %w(--pid-file)
|
|
75
|
+
def restart(path = nil)
|
|
76
|
+
execute_from_app_dir! path, ARGV
|
|
77
|
+
invoke :stop
|
|
78
|
+
invoke :daemon
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
protected
|
|
82
|
+
|
|
83
|
+
def start_app(path, mode, pid_file = nil)
|
|
84
|
+
execute_from_app_dir! path, ARGV
|
|
85
|
+
say "Starting Adhearsion server at #{path}"
|
|
86
|
+
Adhearsion::Initializer.start :mode => mode, :pid_file => pid_file
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def execute_from_app_dir!(path, *args)
|
|
90
|
+
return if in_app? and running_script_ahn?
|
|
91
|
+
|
|
92
|
+
path ||= '.' if in_app?
|
|
93
|
+
|
|
94
|
+
raise PathRequired, ARGV[0] if path.nil? or path.empty?
|
|
95
|
+
raise PathInvalid, path unless ScriptAhnLoader.in_ahn_application?(path)
|
|
96
|
+
|
|
97
|
+
Dir.chdir path do
|
|
98
|
+
args.flatten!
|
|
99
|
+
args[1] = '.'
|
|
100
|
+
ScriptAhnLoader.exec_script_ahn! args
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def running_script_ahn?
|
|
105
|
+
$0.to_s == "script/ahn"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def in_app?
|
|
109
|
+
ScriptAhnLoader.in_ahn_application? or ScriptAhnLoader.in_ahn_application_subdirectory?
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def process_exists?(pid = nil)
|
|
113
|
+
# FIXME: Raise some error here
|
|
114
|
+
return false if pid.nil?
|
|
115
|
+
`ps -p #{pid} | sed -e '1d'`.strip.empty?
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def method_missing(action, *args)
|
|
119
|
+
help
|
|
120
|
+
raise UnknownCommand, [action, *args] * " "
|
|
121
|
+
end
|
|
122
|
+
end # AhnCommand
|
|
123
|
+
|
|
124
|
+
class UnknownCommand < Thor::Error
|
|
125
|
+
def initialize(cmd)
|
|
126
|
+
super "Unknown command: #{cmd}"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
class PathRequired < Thor::Error
|
|
131
|
+
def initialize(cmd)
|
|
132
|
+
super "A valid path is required for #{cmd}, unless run from an Adhearson app directory"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
class PathInvalid < Thor::Error
|
|
137
|
+
def initialize(path)
|
|
138
|
+
super "Directory #{path} does not belong to an Adhearsion project!"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
module Adhearsion
|
|
2
|
+
|
|
3
|
+
class Configuration
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Initialize the configuration object
|
|
7
|
+
#
|
|
8
|
+
# * &block platform configuration block
|
|
9
|
+
# Adhearsion::Configuration.new do
|
|
10
|
+
# foo "bar", :desc => "My description"
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# @return [Adhearsion::Configuration]
|
|
14
|
+
def initialize(&block)
|
|
15
|
+
initialize_environments
|
|
16
|
+
|
|
17
|
+
Loquacious::Configuration.for :platform do
|
|
18
|
+
root nil, :desc => "Adhearsion application root folder"
|
|
19
|
+
lib "lib", :desc => <<-__
|
|
20
|
+
Folder to include the own libraries to be used. Adhearsion loads any ruby file located into this folder during the bootstrap
|
|
21
|
+
process. Set to nil if you do not want these files to be loaded. This folder is relative to the application root folder.
|
|
22
|
+
__
|
|
23
|
+
automatically_accept_incoming_calls true, :desc => "Adhearsion will accept automatically any inbound call"
|
|
24
|
+
|
|
25
|
+
environment :development, :desc => "Active environment. Supported values: development, production, staging, test"
|
|
26
|
+
|
|
27
|
+
desc "Log configuration"
|
|
28
|
+
logging {
|
|
29
|
+
level :info, :desc => <<-__
|
|
30
|
+
Supported levels (in increasing severity) -- :trace < :debug < :info < :warn < :error < :fatal
|
|
31
|
+
__
|
|
32
|
+
outputters ["log/adhearsion.log"], :desc => <<-__
|
|
33
|
+
An array of log outputters to use. The default is to log to stdout and log/adhearsion.log
|
|
34
|
+
__
|
|
35
|
+
formatter nil, :desc => <<-__
|
|
36
|
+
A log formatter to apply to all active outputters. If nil, the Adhearsion default formatter will be used.
|
|
37
|
+
__
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Loquacious::Configuration.for :platform, &block if block_given?
|
|
42
|
+
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def initialize_environments
|
|
47
|
+
# Create a method per each valid environment that, when invoked, may execute
|
|
48
|
+
# the block received if the environment is active
|
|
49
|
+
valid_environments.each do |enviro|
|
|
50
|
+
add_environment enviro
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def valid_environment?(env)
|
|
55
|
+
env && self.valid_environments.include?(env.to_sym)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def valid_environments
|
|
59
|
+
@valid_environments ||= [:production, :development, :staging, :test]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def add_environment(env)
|
|
63
|
+
self.class.send(:define_method, env.to_sym) do |*args, &block|
|
|
64
|
+
unless block.nil? || env != self.platform.environment.to_sym
|
|
65
|
+
self.instance_eval &block
|
|
66
|
+
end
|
|
67
|
+
self
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
# Direct access to a specific configuration object
|
|
73
|
+
#
|
|
74
|
+
# Adhearsion.config[:platform] => returns the configuration object associated to the Adhearsion platform
|
|
75
|
+
#
|
|
76
|
+
# @return [Loquacious::Configuration] configuration object or nil if the plugin does not exist
|
|
77
|
+
def [](value)
|
|
78
|
+
self.send value.to_sym
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# Wrapper to access to a specific configuration object
|
|
83
|
+
#
|
|
84
|
+
# Adhearsion.config.foo => returns the configuration object associated to the foo plugin
|
|
85
|
+
def method_missing(method_name, *args, &block)
|
|
86
|
+
config = Loquacious::Configuration.for method_name, &block
|
|
87
|
+
raise Adhearsion::ConfigurationError.new "Invalid plugin #{method_name}" if config.nil?
|
|
88
|
+
config
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# root accessor
|
|
92
|
+
def root
|
|
93
|
+
platform.root
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# Handle the Adhearsion platform configuration
|
|
98
|
+
#
|
|
99
|
+
# It accepts a block that will be executed in the Adhearsion config var environment
|
|
100
|
+
# to update the desired values
|
|
101
|
+
#
|
|
102
|
+
# Adhearsion.config.platform do
|
|
103
|
+
# foo "bar", :desc => "My new description"
|
|
104
|
+
# end
|
|
105
|
+
#
|
|
106
|
+
# values = Adhearsion.config.platform
|
|
107
|
+
# values.foo => "bar"
|
|
108
|
+
#
|
|
109
|
+
# @return [Loquacious::Configuration] configuration object or nil if the plugin does not exist
|
|
110
|
+
def platform(&block)
|
|
111
|
+
Loquacious::Configuration.for :platform, &block
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
##
|
|
115
|
+
# Fetchs the configuration info for the Adhearsion platform or a specific plugin
|
|
116
|
+
# @param name [Symbol]
|
|
117
|
+
# - :all => Adhearsion platform and all the loaded plugins
|
|
118
|
+
# - nil => Adhearsion platform configuration
|
|
119
|
+
# - :platform => Adhearsion platform configuration
|
|
120
|
+
# - :<plugin-config-name> => Adhearsion plugin configuration
|
|
121
|
+
#
|
|
122
|
+
# @param args [Hash]
|
|
123
|
+
# - @option :show_values [Boolean] true | false to return the current values or just the description
|
|
124
|
+
#
|
|
125
|
+
# @return string with the configuration description/values
|
|
126
|
+
def description(name, args = {:show_values => true})
|
|
127
|
+
desc = StringIO.new
|
|
128
|
+
|
|
129
|
+
name.nil? and name = :platform
|
|
130
|
+
if name.eql? :all
|
|
131
|
+
value = ""
|
|
132
|
+
Loquacious::Configuration.instance_variable_get("@table").keys.map do |config|
|
|
133
|
+
value.concat description config, args
|
|
134
|
+
end
|
|
135
|
+
return value
|
|
136
|
+
else
|
|
137
|
+
return "" if Loquacious::Configuration.for(name).nil?
|
|
138
|
+
|
|
139
|
+
config = Loquacious::Configuration.help_for name,
|
|
140
|
+
:name_leader => "",
|
|
141
|
+
:desc_leader => "# ",
|
|
142
|
+
:colorize => true,
|
|
143
|
+
:io => desc
|
|
144
|
+
config.show :values => args[:show_values]
|
|
145
|
+
"\n# ******* Configuration for #{name} **************\n\n#{desc.string}"
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
data/lib/adhearsion/console.rb
CHANGED
|
@@ -20,11 +20,12 @@ module Adhearsion
|
|
|
20
20
|
end
|
|
21
21
|
]
|
|
22
22
|
Pry.config.command_prefix = "%"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
if libedit?
|
|
24
|
+
logger.error "Cannot start. You are running Adhearsion on Ruby with libedit. You must use readline for the console to work."
|
|
25
|
+
else
|
|
26
|
+
logger.info "Starting up..."
|
|
27
|
+
pry
|
|
28
|
+
end
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def calls
|
|
@@ -36,14 +37,24 @@ module Adhearsion
|
|
|
36
37
|
raise ArgumentError unless Adhearsion.active_calls[call]
|
|
37
38
|
call = Adhearsion.active_calls[call]
|
|
38
39
|
end
|
|
39
|
-
Pry.prompt = [ proc { "AHN<#{call.channel}> "},
|
|
40
|
-
proc { "AHN<#{call.channel}? "} ]
|
|
40
|
+
Pry.prompt = [ proc { "AHN<#{call.channel}> " },
|
|
41
|
+
proc { "AHN<#{call.channel}? " } ]
|
|
41
42
|
|
|
42
43
|
# Pause execution of the thread currently controlling the call
|
|
43
44
|
call.with_command_lock do
|
|
44
45
|
CallWrapper.new(call).pry
|
|
45
46
|
end
|
|
46
47
|
end
|
|
48
|
+
|
|
49
|
+
def libedit?
|
|
50
|
+
begin
|
|
51
|
+
# If NotImplemented then this might be libedit
|
|
52
|
+
Readline.emacs_editing_mode
|
|
53
|
+
false
|
|
54
|
+
rescue NotImplementedError
|
|
55
|
+
true
|
|
56
|
+
end
|
|
57
|
+
end
|
|
47
58
|
end
|
|
48
59
|
|
|
49
60
|
class CallWrapper
|
|
@@ -51,7 +62,7 @@ module Adhearsion
|
|
|
51
62
|
|
|
52
63
|
def initialize(call)
|
|
53
64
|
@call = call
|
|
54
|
-
extend Adhearsion::
|
|
65
|
+
extend Adhearsion::Commands.for('asterisk')
|
|
55
66
|
end
|
|
56
67
|
end
|
|
57
68
|
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Adhearsion
|
|
2
|
+
class Events
|
|
3
|
+
|
|
4
|
+
include HasGuardedHandlers
|
|
5
|
+
|
|
6
|
+
Message = Struct.new :type, :object
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def method_missing(method_name, *args, &block)
|
|
10
|
+
instance.send method_name, *args, &block
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def respond_to?(method_name)
|
|
14
|
+
instance.respond_to?(method_name) || super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def instance
|
|
18
|
+
@@instance || refresh!
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def refresh!
|
|
22
|
+
@@instance = new
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
refresh!
|
|
27
|
+
|
|
28
|
+
def queue
|
|
29
|
+
@queue || reinitialize_queue!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def trigger(type, object = nil)
|
|
33
|
+
queue.push_async Message.new(type, object)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def trigger_immediately(type, object = nil)
|
|
37
|
+
queue.push_immediately Message.new(type, object)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def reinitialize_queue!
|
|
41
|
+
GirlFriday.shutdown! if @queue
|
|
42
|
+
# TODO: Extract number of threads to use from Adhearsion.config
|
|
43
|
+
@queue = GirlFriday::WorkQueue.new 'main_queue', :error_handler => ErrorHandler do |message|
|
|
44
|
+
begin
|
|
45
|
+
handle_message message
|
|
46
|
+
rescue Exception => e
|
|
47
|
+
ErrorHandler.new.handle e
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def handle_message(message)
|
|
53
|
+
trigger_handler message.type, message.object
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def draw(&block)
|
|
57
|
+
instance_exec &block
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def method_missing(method_name, *args, &block)
|
|
61
|
+
register_handler method_name, *args, &block
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def respond_to?(method_name)
|
|
65
|
+
return true if @handlers && @handlers.has_key?(method_name)
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
alias :register_callback :register_handler
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def call_handler(handler, guards, event)
|
|
74
|
+
super && throw(:pass)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class ErrorHandler
|
|
78
|
+
def handle(exception)
|
|
79
|
+
Events.trigger :exception, exception
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|