sevenscale-adhearsion 0.7.1000 → 0.7.1003
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/Manifest.txt +5 -3
- data/README.txt +1 -2
- data/Rakefile +7 -1
- data/adhearsion.gemspec +40 -0
- data/app_generators/ahn/ahn_generator.rb +3 -2
- data/app_generators/ahn/templates/.ahnrc +16 -0
- data/app_generators/ahn/templates/Rakefile +15 -0
- data/app_generators/ahn/templates/events.rb +6 -0
- data/lib/adhearsion/cli.rb +1 -1
- data/lib/adhearsion/events_support.rb +262 -0
- data/lib/adhearsion/initializer.rb +52 -22
- data/lib/adhearsion/voip/asterisk/agi_server.rb +3 -0
- data/lib/adhearsion/voip/asterisk/commands.rb +1 -1
- data/lib/adhearsion/voip/asterisk.rb +8 -1
- data/lib/adhearsion/voip/call.rb +35 -1
- data/lib/adhearsion.rb +1 -0
- data/spec/sample.rb +9 -0
- data/spec/test_events.rb +136 -0
- data/spec/test_helper.rb +30 -18
- data/spec/test_hooks.rb +0 -22
- data/spec/test_initialization.rb +67 -48
- data/spec/voip/asterisk/test_agi_server.rb +4 -4
- data/spec/voip/test_dialplan_manager.rb +70 -0
- metadata +17 -5
- data/lib/adhearsion/services/scheduler.rb +0 -5
- data/script/destroy +0 -14
- data/script/generate +0 -14
data/Manifest.txt
CHANGED
@@ -3,6 +3,7 @@ LICENSE
|
|
3
3
|
Manifest.txt
|
4
4
|
README.txt
|
5
5
|
Rakefile
|
6
|
+
adhearsion.gemspec
|
6
7
|
ahn_generators/component/USAGE
|
7
8
|
ahn_generators/component/component_generator.rb
|
8
9
|
ahn_generators/component/templates/configuration.rb
|
@@ -20,6 +21,7 @@ app_generators/ahn/templates/components/simon_game/test/test_helper.rb
|
|
20
21
|
app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb
|
21
22
|
app_generators/ahn/templates/config/startup.rb
|
22
23
|
app_generators/ahn/templates/dialplan.rb
|
24
|
+
app_generators/ahn/templates/events.rb
|
23
25
|
bin/ahn
|
24
26
|
bin/ahnctl
|
25
27
|
bin/jahn
|
@@ -50,6 +52,7 @@ lib/adhearsion/distributed/gateways/soap_gateway.rb
|
|
50
52
|
lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb
|
51
53
|
lib/adhearsion/distributed/peer_finder.rb
|
52
54
|
lib/adhearsion/distributed/remote_cli.rb
|
55
|
+
lib/adhearsion/events_support.rb
|
53
56
|
lib/adhearsion/hooks.rb
|
54
57
|
lib/adhearsion/host_definitions.rb
|
55
58
|
lib/adhearsion/initializer.rb
|
@@ -61,7 +64,6 @@ lib/adhearsion/initializer/freeswitch.rb
|
|
61
64
|
lib/adhearsion/initializer/paths.rb
|
62
65
|
lib/adhearsion/initializer/rails.rb
|
63
66
|
lib/adhearsion/logging.rb
|
64
|
-
lib/adhearsion/services/scheduler.rb
|
65
67
|
lib/adhearsion/tasks.rb
|
66
68
|
lib/adhearsion/tasks/database.rb
|
67
69
|
lib/adhearsion/tasks/generating.rb
|
@@ -104,18 +106,18 @@ lib/adhearsion/voip/menu_state_machine/calculated_match.rb
|
|
104
106
|
lib/adhearsion/voip/menu_state_machine/matchers.rb
|
105
107
|
lib/adhearsion/voip/menu_state_machine/menu_builder.rb
|
106
108
|
lib/adhearsion/voip/menu_state_machine/menu_class.rb
|
107
|
-
script/destroy
|
108
|
-
script/generate
|
109
109
|
spec/fixtures/dialplan.rb
|
110
110
|
spec/initializer/test_configuration.rb
|
111
111
|
spec/initializer/test_loading.rb
|
112
112
|
spec/initializer/test_paths.rb
|
113
|
+
spec/sample.rb
|
113
114
|
spec/silence.rb
|
114
115
|
spec/test_ahn_command.rb
|
115
116
|
spec/test_code_quality.rb
|
116
117
|
spec/test_component_manager.rb
|
117
118
|
spec/test_constants.rb
|
118
119
|
spec/test_drb.rb
|
120
|
+
spec/test_events.rb
|
119
121
|
spec/test_helper.rb
|
120
122
|
spec/test_hooks.rb
|
121
123
|
spec/test_host_definitions.rb
|
data/README.txt
CHANGED
@@ -2,5 +2,4 @@ Adhearsion
|
|
2
2
|
by Jay Phillips, et. al
|
3
3
|
http://adhearsion.com
|
4
4
|
|
5
|
-
Adhearsion is an open-source framework written in Ruby designed to vastly improve Voice over IP development. It rests atop established telephony platforms (such as Asterisk and Freeswitch) and abstracts their complexity with the beauty of a well-designed, high-level suite of solutions.
|
6
|
-
|
5
|
+
Adhearsion is an open-source framework written in Ruby designed to vastly improve Voice over IP development. It rests atop established telephony platforms (such as Asterisk and Freeswitch) and abstracts their complexity with the beauty of a well-designed, high-level suite of solutions.
|
data/Rakefile
CHANGED
@@ -4,6 +4,7 @@ ENV['RUBY_FLAGS'] = "-I#{%w(lib ext bin test).join(File::PATH_SEPARATOR)}"
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'hoe'
|
6
6
|
require 'lib/adhearsion/version'
|
7
|
+
# require File.dirname(__FILE__) + "/support/yard/lib/yard"
|
7
8
|
|
8
9
|
begin
|
9
10
|
require 'rcov/rcovtask'
|
@@ -24,6 +25,11 @@ task :test do
|
|
24
25
|
# The other :test task is created by Hoe below.
|
25
26
|
end
|
26
27
|
|
28
|
+
# YARD::Rake::YardocTask.new do |t|
|
29
|
+
# t.files = ['lib/**/*.rb'] # optional
|
30
|
+
# # t.options = ['--any', '--extra', '--opts'] # optional
|
31
|
+
# end
|
32
|
+
|
27
33
|
# Need to migrate away from Hoe...
|
28
34
|
Hoe.new('adhearsion', Adhearsion::VERSION::STRING) do |p|
|
29
35
|
p.rubyforge_name = 'adhearsion'
|
@@ -45,4 +51,4 @@ end
|
|
45
51
|
|
46
52
|
task :ragel do
|
47
53
|
`ragel -n -R lib/adhearsion/voip/asterisk/ami/machine.rl | rlgen-ruby -o lib/adhearsion/voip/asterisk/ami/machine.rb`
|
48
|
-
end
|
54
|
+
end
|
data/adhearsion.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{adhearsion}
|
3
|
+
s.version = "0.7.1003"
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["Jay Phillips"]
|
7
|
+
s.date = %q{2008-09-16}
|
8
|
+
s.description = %q{Adhearsion is an open-source VoIP development framework written in Ruby}
|
9
|
+
s.email = %q{Jay -at- Codemecca.com}
|
10
|
+
s.executables = ["ahn", "ahnctl", "jahn"]
|
11
|
+
s.extra_rdoc_files = ["Manifest.txt", "README.txt"]
|
12
|
+
s.files = ["CHANGELOG", "LICENSE", "Manifest.txt", "README.txt", "Rakefile", "adhearsion.gemspec", "ahn_generators/component/USAGE", "ahn_generators/component/component_generator.rb", "ahn_generators/component/templates/configuration.rb", "ahn_generators/component/templates/lib/lib.rb.erb", "ahn_generators/component/templates/test/test.rb.erb", "ahn_generators/component/templates/test/test_helper.rb", "app_generators/ahn/USAGE", "app_generators/ahn/ahn_generator.rb", "app_generators/ahn/templates/.ahnrc", "app_generators/ahn/templates/README", "app_generators/ahn/templates/Rakefile", "app_generators/ahn/templates/components/simon_game/configuration.rb", "app_generators/ahn/templates/components/simon_game/lib/simon_game.rb", "app_generators/ahn/templates/components/simon_game/test/test_helper.rb", "app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb", "app_generators/ahn/templates/config/startup.rb", "app_generators/ahn/templates/dialplan.rb", "app_generators/ahn/templates/events.rb", "bin/ahn", "bin/ahnctl", "bin/jahn", "lib/adhearsion.rb", "lib/adhearsion/blank_slate.rb", "lib/adhearsion/cli.rb", "lib/adhearsion/component_manager.rb", "lib/adhearsion/core_extensions/all.rb", "lib/adhearsion/core_extensions/array.rb", "lib/adhearsion/core_extensions/custom_daemonizer.rb", "lib/adhearsion/core_extensions/global.rb", "lib/adhearsion/core_extensions/guid.rb", "lib/adhearsion/core_extensions/hash.rb", "lib/adhearsion/core_extensions/metaprogramming.rb", "lib/adhearsion/core_extensions/numeric.rb", "lib/adhearsion/core_extensions/proc.rb", "lib/adhearsion/core_extensions/pseudo_uuid.rb", "lib/adhearsion/core_extensions/publishable.rb", "lib/adhearsion/core_extensions/relationship_properties.rb", "lib/adhearsion/core_extensions/string.rb", "lib/adhearsion/core_extensions/thread.rb", "lib/adhearsion/core_extensions/thread_safety.rb", "lib/adhearsion/core_extensions/time.rb", "lib/adhearsion/distributed/gateways/dbus_gateway.rb", "lib/adhearsion/distributed/gateways/osa_gateway.rb", "lib/adhearsion/distributed/gateways/rest_gateway.rb", "lib/adhearsion/distributed/gateways/soap_gateway.rb", "lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb", "lib/adhearsion/distributed/peer_finder.rb", "lib/adhearsion/distributed/remote_cli.rb", "lib/adhearsion/events_support.rb", "lib/adhearsion/hooks.rb", "lib/adhearsion/host_definitions.rb", "lib/adhearsion/initializer.rb", "lib/adhearsion/initializer/asterisk.rb", "lib/adhearsion/initializer/configuration.rb", "lib/adhearsion/initializer/database.rb", "lib/adhearsion/initializer/drb.rb", "lib/adhearsion/initializer/freeswitch.rb", "lib/adhearsion/initializer/paths.rb", "lib/adhearsion/initializer/rails.rb", "lib/adhearsion/logging.rb", "lib/adhearsion/tasks.rb", "lib/adhearsion/tasks/database.rb", "lib/adhearsion/tasks/generating.rb", "lib/adhearsion/tasks/lint.rb", "lib/adhearsion/tasks/testing.rb", "lib/adhearsion/version.rb", "lib/adhearsion/voip/asterisk.rb", "lib/adhearsion/voip/asterisk/agi_server.rb", "lib/adhearsion/voip/asterisk/ami.rb", "lib/adhearsion/voip/asterisk/ami/actions.rb", "lib/adhearsion/voip/asterisk/ami/machine.rb", "lib/adhearsion/voip/asterisk/ami/machine.rl", "lib/adhearsion/voip/asterisk/ami/parser.rb", "lib/adhearsion/voip/asterisk/commands.rb", "lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb", "lib/adhearsion/voip/asterisk/config_generators/config_generator.rb", "lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb", "lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb", "lib/adhearsion/voip/asterisk/config_manager.rb", "lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb", "lib/adhearsion/voip/call.rb", "lib/adhearsion/voip/call_routing.rb", "lib/adhearsion/voip/commands.rb", "lib/adhearsion/voip/constants.rb", "lib/adhearsion/voip/conveniences.rb", "lib/adhearsion/voip/dial_plan.rb", "lib/adhearsion/voip/dsl/dialing_dsl.rb", "lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb", "lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb", "lib/adhearsion/voip/dsl/dialplan/dispatcher.rb", "lib/adhearsion/voip/dsl/dialplan/parser.rb", "lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb", "lib/adhearsion/voip/dsl/numerical_string.rb", "lib/adhearsion/voip/freeswitch/basic_connection_manager.rb", "lib/adhearsion/voip/freeswitch/event_handler.rb", "lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb", "lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb", "lib/adhearsion/voip/freeswitch/oes_server.rb", "lib/adhearsion/voip/menu_state_machine/calculated_match.rb", "lib/adhearsion/voip/menu_state_machine/matchers.rb", "lib/adhearsion/voip/menu_state_machine/menu_builder.rb", "lib/adhearsion/voip/menu_state_machine/menu_class.rb", "spec/fixtures/dialplan.rb", "spec/initializer/test_configuration.rb", "spec/initializer/test_loading.rb", "spec/initializer/test_paths.rb", "spec/sample.rb", "spec/silence.rb", "spec/test_ahn_command.rb", "spec/test_code_quality.rb", "spec/test_component_manager.rb", "spec/test_constants.rb", "spec/test_drb.rb", "spec/test_events.rb", "spec/test_helper.rb", "spec/test_hooks.rb", "spec/test_host_definitions.rb", "spec/test_initialization.rb", "spec/test_logging.rb", "spec/test_relationship_properties.rb", "spec/voip/asterisk/ami_response_definitions.rb", "spec/voip/asterisk/config_file_generators/test_agents.rb", "spec/voip/asterisk/config_file_generators/test_queues.rb", "spec/voip/asterisk/config_file_generators/test_voicemail.rb", "spec/voip/asterisk/menu_command/test_calculated_match.rb", "spec/voip/asterisk/menu_command/test_matchers.rb", "spec/voip/asterisk/mock_ami_server.rb", "spec/voip/asterisk/test_agi_server.rb", "spec/voip/asterisk/test_ami.rb", "spec/voip/asterisk/test_commands.rb", "spec/voip/asterisk/test_config_manager.rb", "spec/voip/dsl/dispatcher_spec_helper.rb", "spec/voip/dsl/test_dialing_dsl.rb", "spec/voip/dsl/test_dispatcher.rb", "spec/voip/dsl/test_parser.rb", "spec/voip/freeswitch/test_basic_connection_manager.rb", "spec/voip/freeswitch/test_inbound_connection_manager.rb", "spec/voip/freeswitch/test_oes_server.rb", "spec/voip/test_call_routing.rb", "spec/voip/test_dialplan_manager.rb", "spec/voip/test_numerical_string.rb", "spec/voip/test_phone_number.rb", "test/test_ahn_generator.rb", "test/test_component_generator.rb", "test/test_generator_helper.rb"]
|
13
|
+
s.has_rdoc = true
|
14
|
+
s.homepage = %q{http://adhearsion.com}
|
15
|
+
s.rdoc_options = ["--main", "README.txt"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{adhearsion}
|
18
|
+
s.rubygems_version = %q{1.2.0}
|
19
|
+
s.summary = %q{Adhearsion, open-source telephony integrator.}
|
20
|
+
s.test_files = ["spec/initializer/test_configuration.rb", "spec/initializer/test_loading.rb", "spec/initializer/test_paths.rb", "spec/test_ahn_command.rb", "spec/test_code_quality.rb", "spec/test_component_manager.rb", "spec/test_constants.rb", "spec/test_drb.rb", "spec/test_events.rb", "spec/test_helper.rb", "spec/test_hooks.rb", "spec/test_host_definitions.rb", "spec/test_initialization.rb", "spec/test_logging.rb", "spec/test_relationship_properties.rb", "spec/voip/asterisk/config_file_generators/test_agents.rb", "spec/voip/asterisk/config_file_generators/test_queues.rb", "spec/voip/asterisk/config_file_generators/test_voicemail.rb", "spec/voip/asterisk/menu_command/test_calculated_match.rb", "spec/voip/asterisk/menu_command/test_matchers.rb", "spec/voip/asterisk/test_agi_server.rb", "spec/voip/asterisk/test_ami.rb", "spec/voip/asterisk/test_commands.rb", "spec/voip/asterisk/test_config_manager.rb", "spec/voip/dsl/test_dialing_dsl.rb", "spec/voip/dsl/test_dispatcher.rb", "spec/voip/dsl/test_parser.rb", "spec/voip/freeswitch/test_basic_connection_manager.rb", "spec/voip/freeswitch/test_inbound_connection_manager.rb", "spec/voip/freeswitch/test_oes_server.rb", "spec/voip/test_call_routing.rb", "spec/voip/test_dialplan_manager.rb", "spec/voip/test_numerical_string.rb", "spec/voip/test_phone_number.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 2
|
25
|
+
|
26
|
+
if current_version >= 3 then
|
27
|
+
s.add_runtime_dependency(%q<rubigen>, [">= 1.0.6"])
|
28
|
+
s.add_runtime_dependency(%q<log4r>, [">= 1.0.5"])
|
29
|
+
s.add_development_dependency(%q<hoe>, [">= 1.7.0"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<rubigen>, [">= 1.0.6"])
|
32
|
+
s.add_dependency(%q<log4r>, [">= 1.0.5"])
|
33
|
+
s.add_dependency(%q<hoe>, [">= 1.7.0"])
|
34
|
+
end
|
35
|
+
else
|
36
|
+
s.add_dependency(%q<rubigen>, [">= 1.0.6"])
|
37
|
+
s.add_dependency(%q<log4r>, [">= 1.0.5"])
|
38
|
+
s.add_dependency(%q<hoe>, [">= 1.7.0"])
|
39
|
+
end
|
40
|
+
end
|
@@ -31,11 +31,12 @@ class AhnGenerator < RubiGen::Base
|
|
31
31
|
|
32
32
|
m.file *["config/startup.rb"]*2
|
33
33
|
m.file *["dialplan.rb"]*2
|
34
|
+
m.file *["events.rb"]*2
|
34
35
|
m.file *["README"]*2
|
35
36
|
m.file *["Rakefile"]*2
|
36
37
|
|
37
|
-
m.dependency "install_rubigen_scripts", [destination_root, 'ahn', 'adhearsion', 'test_spec'],
|
38
|
-
|
38
|
+
# m.dependency "install_rubigen_scripts", [destination_root, 'ahn', 'adhearsion', 'test_spec'],
|
39
|
+
# :shebang => options[:shebang], :collision => :force
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# Adhearsion Runtime Configuration.
|
2
2
|
|
3
|
+
# You can use the "gems" section to force Adhearsion to load a particular version of a gem.
|
4
|
+
# This is useful when a component require()s a gem, but you don't want it to use the latest one installed on the system.
|
5
|
+
# For example, if a component require()s activerecord, sucking in the latest on the system, and then you enable a Rails app
|
6
|
+
# which wants a particular version of activerecord, RubyGems will raise an error saying "you cannot activate two versions of
|
7
|
+
# the same gem". Note: specifying the version and/or the source is optional, but you must include a : after the gem name.
|
8
|
+
gems:
|
9
|
+
# twitter:
|
10
|
+
# hpricot:
|
11
|
+
# rack:
|
12
|
+
# activerecord:
|
13
|
+
# version: >= 2.1.0
|
14
|
+
# aasm:
|
15
|
+
# source: http://gems.github.com
|
16
|
+
|
3
17
|
paths:
|
4
18
|
|
5
19
|
# All paths are relative to this file's directory
|
@@ -7,6 +21,8 @@ paths:
|
|
7
21
|
|
8
22
|
dialplan: dialplan.rb
|
9
23
|
|
24
|
+
events: events.rb
|
25
|
+
|
10
26
|
models:
|
11
27
|
directory: models
|
12
28
|
pattern: "*.rb"
|
@@ -1,3 +1,18 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'adhearsion'
|
3
3
|
require 'adhearsion/tasks'
|
4
|
+
|
5
|
+
desc "Writes a .gitignore file that ignores certain SCM annoyances such as log files"
|
6
|
+
task :gitignore do
|
7
|
+
ignore_file = "#{Dir.pwd}/.gitignore"
|
8
|
+
if File.exists? ignore_file
|
9
|
+
STDERR.puts "File #{ignore_file} already exists!"
|
10
|
+
else
|
11
|
+
File.open ignore_file, 'w' do |file|
|
12
|
+
# Add other files to the Array below
|
13
|
+
%w[ log ].each do |pattern|
|
14
|
+
file.puts pattern
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/adhearsion/cli.rb
CHANGED
@@ -67,7 +67,7 @@ USAGE
|
|
67
67
|
|
68
68
|
def start(path, daemon=false, pid_file=nil)
|
69
69
|
raise PathInvalid, path unless File.exists? path + "/.ahnrc"
|
70
|
-
Adhearsion::Initializer.
|
70
|
+
Adhearsion::Initializer.start path, :daemon => daemon, :pid_file => pid_file
|
71
71
|
end
|
72
72
|
|
73
73
|
def version
|
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'thread'
|
2
|
+
module Adhearsion
|
3
|
+
module Events
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def framework_events_container
|
8
|
+
defined?(@@framework_events_container) ? @@framework_events_container : reinitialize_framework_events_container!
|
9
|
+
end
|
10
|
+
|
11
|
+
def load_definitions_from_files(*files)
|
12
|
+
files.each do |file|
|
13
|
+
framework_events_container.instance_eval File.read(file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
alias load_definitions_from_file load_definitions_from_files
|
17
|
+
|
18
|
+
def namespace_registered?(*paths)
|
19
|
+
framework_events_container.namespace_registered?(*paths)
|
20
|
+
end
|
21
|
+
|
22
|
+
def reinitialize_framework_events_container!
|
23
|
+
@@framework_events_container = EventsDefinitionContainer.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def register_namespace_path(*paths)
|
27
|
+
framework_events_container.register_namespace_path(*paths)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
class EventsDefinitionContainer
|
33
|
+
|
34
|
+
attr_reader :root
|
35
|
+
def initialize
|
36
|
+
@root = RootEventNamespace.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def register_namespace_path(*paths)
|
40
|
+
inject_across_path(*paths) do |namespace, path|
|
41
|
+
namespace.namespace_registered?(path) ? namespace[path] : namespace.register_namespace(path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def events
|
46
|
+
root.capturer
|
47
|
+
end
|
48
|
+
|
49
|
+
def namespace_registered?(*paths)
|
50
|
+
!! inject_across_path(*paths) { |namespace,path| namespace[path] }
|
51
|
+
rescue UndefinedEventNamespace
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
def callbacks_at_path(*paths)
|
56
|
+
inject_across_path(*paths) { |namespace,path| namespace[path] }.callbacks
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def inject_across_path(*paths, &block)
|
62
|
+
paths.map(&:to_sym).inject(root, &block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class NamespaceDefinitionCapturer
|
67
|
+
|
68
|
+
attr_reader :namespace
|
69
|
+
def initialize(namespace)
|
70
|
+
@namespace = namespace
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_missing(name, *args)
|
74
|
+
super if name == :each # Added to prevent confusion
|
75
|
+
nested_namespace_or_registrar = namespace[name.to_sym]
|
76
|
+
raise UndefinedEventNamespace.new(name) unless nested_namespace_or_registrar
|
77
|
+
case nested_namespace_or_registrar
|
78
|
+
when EventCallbackRegistrar
|
79
|
+
nested_namespace_or_registrar
|
80
|
+
when RegisteredEventNamespace
|
81
|
+
nested_namespace_or_registrar.capturer
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class UndefinedEventNamespace < Exception
|
87
|
+
def initialize(name)
|
88
|
+
super "Undefined namespace '#{name}'"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class AbstractEventNamespace
|
93
|
+
|
94
|
+
attr_reader :children
|
95
|
+
def initialize
|
96
|
+
@children = {}
|
97
|
+
end
|
98
|
+
|
99
|
+
def [](namespace_name)
|
100
|
+
raise UndefinedEventNamespace.new(namespace_name) unless namespace_registered? namespace_name
|
101
|
+
children[namespace_name]
|
102
|
+
end
|
103
|
+
|
104
|
+
def namespace_registered?(namespace_name)
|
105
|
+
children.has_key?(namespace_name)
|
106
|
+
end
|
107
|
+
|
108
|
+
def register_namespace(namespace)
|
109
|
+
children[namespace] = RegisteredEventNamespace.new(self)
|
110
|
+
end
|
111
|
+
|
112
|
+
def root?
|
113
|
+
false
|
114
|
+
end
|
115
|
+
|
116
|
+
def capturer
|
117
|
+
@capturer ||= NamespaceDefinitionCapturer.new(self)
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
class RootEventNamespace < AbstractEventNamespace
|
123
|
+
|
124
|
+
def parent
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
128
|
+
def root?
|
129
|
+
true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class RegisteredEventNamespace < AbstractEventNamespace
|
134
|
+
attr_reader :parent
|
135
|
+
def initialize(parent)
|
136
|
+
super()
|
137
|
+
@parent = parent
|
138
|
+
end
|
139
|
+
|
140
|
+
def register_callback_name(name, mode=:sync, &block)
|
141
|
+
children[name] = case mode
|
142
|
+
when :sync then SynchronousEventCallbackRegistrar
|
143
|
+
when :async then AsynchronousEventCallbackRegistrar
|
144
|
+
else
|
145
|
+
raise ArgumentError, "Unsupported mode #{mode.inspect} !"
|
146
|
+
end.new(self, &block)
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
class EventCallbackRegistrar
|
152
|
+
|
153
|
+
attr_reader :namespace, :callbacks
|
154
|
+
attr_accessor :notified_on_new_callback
|
155
|
+
|
156
|
+
|
157
|
+
def initialize(namespace, ¬ified_on_new_callback)
|
158
|
+
@namespace = namespace
|
159
|
+
@callbacks = []
|
160
|
+
@mutex = Mutex.new
|
161
|
+
@notified_on_new_callback = notified_on_new_callback
|
162
|
+
end
|
163
|
+
|
164
|
+
# This is effectively called when you define a new callback with each()
|
165
|
+
def register_callback(&block)
|
166
|
+
returning RegisteredEventCallback.new(self, &block) do |callback|
|
167
|
+
with_lock { callbacks << callback }
|
168
|
+
notified_on_new_callback.call callback if notified_on_new_callback
|
169
|
+
end
|
170
|
+
end
|
171
|
+
alias each register_callback
|
172
|
+
|
173
|
+
def <<(message)
|
174
|
+
raise NotImplementedError
|
175
|
+
end
|
176
|
+
|
177
|
+
def remove_callback(callback)
|
178
|
+
with_lock { callbacks.delete callback }
|
179
|
+
end
|
180
|
+
|
181
|
+
protected
|
182
|
+
|
183
|
+
def with_lock(&block)
|
184
|
+
@mutex.synchronize(&block)
|
185
|
+
end
|
186
|
+
|
187
|
+
def threadsafe_callback_collection
|
188
|
+
with_lock { callbacks.clone }
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
class SynchronousEventCallbackRegistrar < EventCallbackRegistrar
|
194
|
+
def <<(event)
|
195
|
+
threadsafe_callback_collection.each do |callback|
|
196
|
+
callback.run_with_event event
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class AsynchronousEventCallbackRegistrar < EventCallbackRegistrar
|
202
|
+
|
203
|
+
attr_reader :thread
|
204
|
+
def initialize(namespace, ¬ified_on_new_callback)
|
205
|
+
super
|
206
|
+
@thread = AsynchronousEventCallbackRegistrar.new
|
207
|
+
end
|
208
|
+
|
209
|
+
def <<(event)
|
210
|
+
threadsafe_callback_collection.each do |callback|
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
protected
|
216
|
+
|
217
|
+
attr_reader :queue
|
218
|
+
|
219
|
+
class AsynchronousEventHandlerThread < Thread
|
220
|
+
|
221
|
+
def initialize(&block)
|
222
|
+
@queue = Queue.new
|
223
|
+
super do
|
224
|
+
loop { block.call @queue.pop }
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def <<(event)
|
229
|
+
@queue << event
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
# A RegisteredEventCallback is stored away each time you call each() on an event namespace.
|
237
|
+
# It keeps a copy of the namespace
|
238
|
+
class RegisteredEventCallback
|
239
|
+
|
240
|
+
attr_reader :registrar, :args, :block
|
241
|
+
def initialize(registrar, *args, &block)
|
242
|
+
raise ArgumentError, "Must supply a callback in the form of a block!" unless block_given?
|
243
|
+
@registrar, @args, @block = registrar, args, block
|
244
|
+
end
|
245
|
+
|
246
|
+
def run_with_event(event)
|
247
|
+
begin
|
248
|
+
block.call event
|
249
|
+
rescue => e
|
250
|
+
indenter = "\n" + (" " * 5)
|
251
|
+
ahn_log.events.error e.message + indenter + e.backtrace.join(indenter)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def namespace
|
256
|
+
registrar.namespace
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
262
|
+
end
|
@@ -41,9 +41,7 @@ module Adhearsion
|
|
41
41
|
|
42
42
|
class << self
|
43
43
|
def get_rules_from(location)
|
44
|
-
if File.directory? location
|
45
|
-
location = File.join location, ".ahnrc"
|
46
|
-
end
|
44
|
+
location = File.join location, ".ahnrc" if File.directory? location
|
47
45
|
File.exists?(location) ? YAML.load_file(location) : nil
|
48
46
|
end
|
49
47
|
|
@@ -55,17 +53,20 @@ module Adhearsion
|
|
55
53
|
end
|
56
54
|
end
|
57
55
|
|
56
|
+
def start(*args, &block)
|
57
|
+
new(*args, &block).start
|
58
|
+
end
|
59
|
+
|
58
60
|
def start_from_init_file(file, ahn_app_path)
|
59
61
|
return if defined?(@@started) && @@started
|
60
|
-
|
62
|
+
start ahn_app_path, :loaded_init_files => file
|
61
63
|
end
|
62
64
|
|
63
65
|
end
|
64
66
|
|
65
67
|
attr_reader :path, :daemon, :pid_file, :log_file, :ahn_app_log_directory
|
66
68
|
|
67
|
-
|
68
|
-
:directory => "helpers"}
|
69
|
+
DEFAULT_FRAMEWORK_EVENT_CALLBACK_NAMES = [:after_initialized, :shutdown]
|
69
70
|
|
70
71
|
# Creation of pid_files
|
71
72
|
#
|
@@ -80,10 +81,13 @@ module Adhearsion
|
|
80
81
|
# even in daemon mode by supplying "false".
|
81
82
|
def initialize(path=nil, options={})
|
82
83
|
@@started = true
|
83
|
-
@path
|
84
|
-
@daemon
|
85
|
-
@pid_file
|
86
|
-
@loaded_init_files
|
84
|
+
@path = path
|
85
|
+
@daemon = options[:daemon]
|
86
|
+
@pid_file = options[:pid_file].nil? ? ENV['PID_FILE'] : options[:pid_file]
|
87
|
+
@loaded_init_files = options[:loaded_init_files]
|
88
|
+
end
|
89
|
+
|
90
|
+
def start
|
87
91
|
self.class.ahn_root = path
|
88
92
|
resolve_pid_file_path
|
89
93
|
resolve_log_file_path
|
@@ -96,11 +100,25 @@ module Adhearsion
|
|
96
100
|
initialize_log_file
|
97
101
|
create_pid_file if pid_file
|
98
102
|
load_components
|
99
|
-
|
103
|
+
init_events
|
100
104
|
ahn_log "Adhearsion initialized!"
|
101
105
|
|
102
106
|
trigger_after_initialized_hooks
|
103
107
|
join_framework_threads
|
108
|
+
|
109
|
+
self
|
110
|
+
end
|
111
|
+
|
112
|
+
def init_events
|
113
|
+
if Paths.manager_for? "events"
|
114
|
+
framework = Events.register_namespace_path(:framework)
|
115
|
+
DEFAULT_FRAMEWORK_EVENT_CALLBACK_NAMES.each do |framework_event_callback_name|
|
116
|
+
framework.register_callback_name framework_event_callback_name
|
117
|
+
end
|
118
|
+
Events.load_definitions_from_files *all_events
|
119
|
+
else
|
120
|
+
ahn_log.events.warn 'No "events" section in .ahnrc. Skipping its initialization.'
|
121
|
+
end
|
104
122
|
end
|
105
123
|
|
106
124
|
def initialize_log_file
|
@@ -108,11 +126,11 @@ module Adhearsion
|
|
108
126
|
file_logger = Log4r::FileOutputter.new("Main Adhearsion log file", :filename => log_file, :trunc => false)
|
109
127
|
|
110
128
|
if should_daemonize?
|
111
|
-
|
129
|
+
Logging::AdhearsionLogger.outputters = file_logger
|
112
130
|
else
|
113
|
-
|
131
|
+
Logging::AdhearsionLogger.outputters << file_logger
|
114
132
|
end
|
115
|
-
|
133
|
+
Logging::DefaultAdhearsionLogger.redefine_outputters
|
116
134
|
end
|
117
135
|
|
118
136
|
def resolve_log_file_path
|
@@ -195,15 +213,27 @@ module Adhearsion
|
|
195
213
|
end
|
196
214
|
|
197
215
|
def bootstrap_rc
|
198
|
-
rules =
|
199
|
-
|
200
|
-
paths
|
201
|
-
|
202
|
-
|
203
|
-
|
216
|
+
rules = self.class.get_rules_from AHN_ROOT
|
217
|
+
|
218
|
+
paths = rules['paths']
|
219
|
+
paths.each_pair do |path_name, pattern_or_ruleset|
|
220
|
+
if pattern_or_ruleset.kind_of? Hash
|
221
|
+
directory, pattern = pattern_or_ruleset['directory'] || '.', pattern_or_ruleset['pattern'] || '*'
|
222
|
+
Paths.manager_for path_name, :pattern => File.join(directory, pattern)
|
204
223
|
else
|
205
|
-
directory, pattern = '.',
|
206
|
-
Paths.manager_for
|
224
|
+
directory, pattern = '.', pattern_or_ruleset
|
225
|
+
Paths.manager_for path_name, :pattern => File.join(directory,pattern)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
gems = rules['gems']
|
230
|
+
if gems.kind_of?(Hash) && gems.any? && respond_to?(:gem)
|
231
|
+
gems.each_pair do |gem_name,properties_hash|
|
232
|
+
if properties_hash && properties_hash["version"]
|
233
|
+
gem gem_name, properties_hash["version"]
|
234
|
+
else
|
235
|
+
gem gem_name
|
236
|
+
end
|
207
237
|
end
|
208
238
|
end
|
209
239
|
end
|
@@ -47,7 +47,10 @@ module Adhearsion
|
|
47
47
|
rescue => e
|
48
48
|
ahn_log.agi.error e.inspect
|
49
49
|
ahn_log.agi.error e.backtrace.map { |s| " " * 5 + s }.join("\n")
|
50
|
+
ensure
|
51
|
+
Adhearsion.remove_inactive_call call rescue nil
|
50
52
|
end
|
53
|
+
|
51
54
|
end
|
52
55
|
|
53
56
|
DEFAULT_OPTIONS = { :server_class => RubyServer, :port => 4573, :host => "0.0.0.0" } unless defined? DEFAULT_OPTIONS
|
@@ -1,4 +1,11 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/dsl/numerical_string"
|
2
2
|
require File.dirname(__FILE__) + "/asterisk/agi_server"
|
3
3
|
require File.dirname(__FILE__) + "/asterisk/ami"
|
4
|
-
require File.dirname(__FILE__) + "/asterisk/commands"
|
4
|
+
require File.dirname(__FILE__) + "/asterisk/commands"
|
5
|
+
|
6
|
+
unless Adhearsion::Events.namespace_registered? :asterisk
|
7
|
+
asterisk_namespace = Adhearsion::Events.register_namespace_path :asterisk
|
8
|
+
[:before_call, :after_call, :hungup_call, :failed_call].each do |callback_name|
|
9
|
+
asterisk_namespace.register_callback_name callback_name
|
10
|
+
end
|
11
|
+
end
|