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 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
@@ -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
- :shebang => options[:shebang], :collision => :force
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
@@ -0,0 +1,6 @@
1
+ # For a full description of what this file does, view the online
2
+ # documentation at http://adhearsion.com
3
+
4
+ events.asterisk.before_call.each do |event|
5
+
6
+ end
@@ -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.new path, :daemon => daemon, :pid_file => pid_file
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, &notified_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, &notified_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
- new(ahn_app_path, :loaded_init_files => file)
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
- DEFAULT_RULES = { :pattern => "*.rb",
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 = path
84
- @daemon = options[:daemon]
85
- @pid_file = options[:pid_file].nil? ? ENV['PID_FILE'] : options[:pid_file]
86
- @loaded_init_files = options[: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
- Adhearsion::Logging::AdhearsionLogger.outputters = file_logger
129
+ Logging::AdhearsionLogger.outputters = file_logger
112
130
  else
113
- Adhearsion::Logging::AdhearsionLogger.outputters << file_logger
131
+ Logging::AdhearsionLogger.outputters << file_logger
114
132
  end
115
- Adhearsion::Logging::DefaultAdhearsionLogger.redefine_outputters
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 = Initializer.get_rules_from(AHN_ROOT) || DEFAULT_RULES
199
- paths = rules['paths'] || DEFAULT_RULES
200
- paths.each_pair do |k,v|
201
- if v.kind_of? Hash
202
- directory, pattern = v['directory'] || '.', v['pattern'] || '*'
203
- Paths.manager_for k, :pattern => File.join(directory, pattern)
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 = '.', v
206
- Paths.manager_for k, :pattern => File.join(directory,pattern)
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
@@ -639,7 +639,7 @@ module Adhearsion
639
639
  end
640
640
 
641
641
  def interruptable_play(*files)
642
- files.each do |file|
642
+ files.flatten.each do |file|
643
643
  result = result_digit_from raw_response("EXEC BACKGROUND #{file}")
644
644
  return result if result != 0.chr
645
645
  end
@@ -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