rene-adhearsion 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +73 -0
- data/EVENTS +11 -0
- data/LICENSE +456 -0
- data/Rakefile +130 -0
- data/adhearsion.gemspec +173 -0
- data/app_generators/ahn/USAGE +5 -0
- data/app_generators/ahn/ahn_generator.rb +96 -0
- data/app_generators/ahn/templates/.ahnrc +34 -0
- data/app_generators/ahn/templates/README +8 -0
- data/app_generators/ahn/templates/Rakefile +25 -0
- data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +15 -0
- data/app_generators/ahn/templates/components/disabled/HOW_TO_ENABLE +7 -0
- data/app_generators/ahn/templates/components/disabled/restful_rpc/README.markdown +11 -0
- data/app_generators/ahn/templates/components/disabled/restful_rpc/example-client.rb +48 -0
- data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb +91 -0
- data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.yml +34 -0
- data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +263 -0
- data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.rb +104 -0
- data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.yml +2 -0
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +47 -0
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +34 -0
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.yml +12 -0
- data/app_generators/ahn/templates/components/disabled/xmpp_gateway/README.markdown +3 -0
- data/app_generators/ahn/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +11 -0
- data/app_generators/ahn/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
- data/app_generators/ahn/templates/components/simon_game/simon_game.rb +56 -0
- data/app_generators/ahn/templates/config/startup.rb +83 -0
- data/app_generators/ahn/templates/dialplan.rb +3 -0
- data/app_generators/ahn/templates/events.rb +32 -0
- data/bin/ahn +28 -0
- data/bin/ahnctl +68 -0
- data/bin/jahn +42 -0
- data/examples/asterisk_manager_interface/standalone.rb +51 -0
- data/lib/adhearsion.rb +45 -0
- data/lib/adhearsion/cli.rb +228 -0
- data/lib/adhearsion/component_manager.rb +272 -0
- data/lib/adhearsion/component_manager/component_tester.rb +55 -0
- data/lib/adhearsion/component_manager/spec_framework.rb +24 -0
- data/lib/adhearsion/events_support.rb +84 -0
- data/lib/adhearsion/foundation/all.rb +15 -0
- data/lib/adhearsion/foundation/blank_slate.rb +3 -0
- data/lib/adhearsion/foundation/custom_daemonizer.rb +45 -0
- data/lib/adhearsion/foundation/event_socket.rb +204 -0
- data/lib/adhearsion/foundation/future_resource.rb +36 -0
- data/lib/adhearsion/foundation/metaprogramming.rb +17 -0
- data/lib/adhearsion/foundation/numeric.rb +13 -0
- data/lib/adhearsion/foundation/pseudo_guid.rb +10 -0
- data/lib/adhearsion/foundation/relationship_properties.rb +42 -0
- data/lib/adhearsion/foundation/string.rb +26 -0
- data/lib/adhearsion/foundation/synchronized_hash.rb +96 -0
- data/lib/adhearsion/foundation/thread_safety.rb +7 -0
- data/lib/adhearsion/host_definitions.rb +67 -0
- data/lib/adhearsion/initializer.rb +395 -0
- data/lib/adhearsion/initializer/asterisk.rb +87 -0
- data/lib/adhearsion/initializer/configuration.rb +321 -0
- data/lib/adhearsion/initializer/database.rb +60 -0
- data/lib/adhearsion/initializer/drb.rb +31 -0
- data/lib/adhearsion/initializer/freeswitch.rb +22 -0
- data/lib/adhearsion/initializer/ldap.rb +57 -0
- data/lib/adhearsion/initializer/rails.rb +41 -0
- data/lib/adhearsion/initializer/xmpp.rb +42 -0
- data/lib/adhearsion/logging.rb +92 -0
- data/lib/adhearsion/tasks.rb +16 -0
- data/lib/adhearsion/tasks/database.rb +5 -0
- data/lib/adhearsion/tasks/deprecations.rb +59 -0
- data/lib/adhearsion/tasks/generating.rb +20 -0
- data/lib/adhearsion/tasks/lint.rb +4 -0
- data/lib/adhearsion/tasks/testing.rb +37 -0
- data/lib/adhearsion/version.rb +33 -0
- data/lib/adhearsion/voip/asterisk.rb +4 -0
- data/lib/adhearsion/voip/asterisk/agi_server.rb +115 -0
- data/lib/adhearsion/voip/asterisk/commands.rb +1510 -0
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
- data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +705 -0
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +1680 -0
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +340 -0
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +78 -0
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +87 -0
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
- data/lib/adhearsion/voip/asterisk/super_manager.rb +19 -0
- data/lib/adhearsion/voip/call.rb +497 -0
- data/lib/adhearsion/voip/call_routing.rb +64 -0
- data/lib/adhearsion/voip/commands.rb +9 -0
- data/lib/adhearsion/voip/constants.rb +39 -0
- data/lib/adhearsion/voip/conveniences.rb +18 -0
- data/lib/adhearsion/voip/dial_plan.rb +246 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +69 -0
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
- data/lib/adhearsion/voip/dsl/numerical_string.rb +115 -0
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
- data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
- data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
- data/lib/adhearsion/xmpp/connection.rb +61 -0
- data/lib/theatre.rb +151 -0
- data/lib/theatre/README.markdown +64 -0
- data/lib/theatre/callback_definition_loader.rb +84 -0
- data/lib/theatre/guid.rb +23 -0
- data/lib/theatre/invocation.rb +121 -0
- data/lib/theatre/namespace_manager.rb +153 -0
- data/lib/theatre/version.rb +2 -0
- metadata +241 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'adhearsion/voip/asterisk'
|
2
|
+
module Adhearsion
|
3
|
+
class Initializer
|
4
|
+
|
5
|
+
class AsteriskInitializer
|
6
|
+
|
7
|
+
cattr_accessor :config, :agi_server, :ami_client
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def start
|
11
|
+
self.config = AHN_CONFIG.asterisk
|
12
|
+
self.agi_server = initialize_agi
|
13
|
+
self.ami_client = VoIP::Asterisk.manager_interface = initialize_ami if config.ami_enabled?
|
14
|
+
join_server_thread_after_initialized
|
15
|
+
|
16
|
+
# Make sure we stop everything when we shutdown
|
17
|
+
Events.register_callback(:shutdown) do
|
18
|
+
ahn_log.info "Shutting down with #{Adhearsion.active_calls.size} active calls"
|
19
|
+
self.stop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def stop
|
24
|
+
agi_server.graceful_shutdown
|
25
|
+
ami_client.disconnect! if ami_client
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def initialize_agi
|
31
|
+
VoIP::Asterisk::AGI::Server.new :host => config.listening_host,
|
32
|
+
:port => config.listening_port
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize_ami
|
36
|
+
options = ami_options
|
37
|
+
start_ami_after_initialized
|
38
|
+
VoIP::Asterisk::Manager::ManagerInterface.new(options).tap do
|
39
|
+
class << VoIP::Asterisk
|
40
|
+
if respond_to?(:manager_interface)
|
41
|
+
ahn_log.warn "Asterisk.manager_interface already initialized?"
|
42
|
+
else
|
43
|
+
def manager_interface
|
44
|
+
# ahn_log.ami.warn "Warning! This Asterisk.manager_interface() notation is for Adhearsion version 0.8.0 only. Subsequent versions of Adhearsion will use a feature called SuperManager. Migrating to use SuperManager will be very simple. See http://docs.adhearsion.com/AMI for more information."
|
45
|
+
Adhearsion::Initializer::AsteriskInitializer.ami_client
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def ami_options
|
53
|
+
%w(host port username password events auto_reconnect).inject({}) do |options, property|
|
54
|
+
options[property.to_sym] = config.ami.send property
|
55
|
+
options
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def join_server_thread_after_initialized
|
60
|
+
Events.register_callback(:after_initialized) do
|
61
|
+
begin
|
62
|
+
agi_server.start
|
63
|
+
rescue => e
|
64
|
+
ahn_log.fatal "Failed to start AGI server! #{e.inspect}"
|
65
|
+
abort
|
66
|
+
end
|
67
|
+
end
|
68
|
+
IMPORTANT_THREADS << agi_server
|
69
|
+
end
|
70
|
+
|
71
|
+
def start_ami_after_initialized
|
72
|
+
Events.register_callback(:after_initialized) do
|
73
|
+
begin
|
74
|
+
self.ami_client.connect!
|
75
|
+
rescue Errno::ECONNREFUSED
|
76
|
+
ahn_log.ami.error "Connection refused when connecting to AMI! Please check your configuration."
|
77
|
+
rescue => e
|
78
|
+
ahn_log.ami.error "Error connecting to AMI! #{e.inspect}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
module Adhearsion
|
2
|
+
class Configuration
|
3
|
+
module ConfigurationEntryPoint
|
4
|
+
def add_configuration_for(name)
|
5
|
+
configuration_class_name = "#{name}Configuration"
|
6
|
+
lowercased_name = name.to_s.underscore
|
7
|
+
|
8
|
+
class_eval(<<-EVAL, __FILE__, __LINE__)
|
9
|
+
def enable_#{lowercased_name}(configuration_options = {})
|
10
|
+
@#{lowercased_name}_configuration = #{configuration_class_name}.new(configuration_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def #{lowercased_name}
|
14
|
+
@#{lowercased_name}_configuration
|
15
|
+
end
|
16
|
+
|
17
|
+
def #{lowercased_name}_enabled?
|
18
|
+
!#{lowercased_name}.nil?
|
19
|
+
end
|
20
|
+
EVAL
|
21
|
+
end
|
22
|
+
end
|
23
|
+
extend ConfigurationEntryPoint
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def configure(&block)
|
27
|
+
if Adhearsion.const_defined?(:AHN_CONFIG)
|
28
|
+
yield AHN_CONFIG if block_given?
|
29
|
+
else
|
30
|
+
Adhearsion.const_set(:AHN_CONFIG, new(&block))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :automatically_answer_incoming_calls
|
36
|
+
attr_accessor :end_call_on_hangup
|
37
|
+
attr_accessor :end_call_on_error
|
38
|
+
attr_accessor :components_to_load
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@automatically_answer_incoming_calls = true
|
42
|
+
@end_call_on_hangup = true
|
43
|
+
@end_call_on_error = true
|
44
|
+
@components_to_load = []
|
45
|
+
yield self if block_given?
|
46
|
+
end
|
47
|
+
|
48
|
+
def ahnrc
|
49
|
+
@ahnrc
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Load the contents of an .ahnrc file into this Configuration.
|
54
|
+
#
|
55
|
+
# @param [String, Hash] ahnrc String of YAML .ahnrc data or a Hash of the pre-loaded YAML data structure
|
56
|
+
#
|
57
|
+
def ahnrc=(new_ahnrc)
|
58
|
+
case new_ahnrc
|
59
|
+
when Hash
|
60
|
+
@raw_ahnrc = new_ahnrc.to_yaml.freeze
|
61
|
+
@ahnrc = new_ahnrc.clone.freeze
|
62
|
+
when String
|
63
|
+
@raw_ahnrc = new_ahnrc.clone.freeze
|
64
|
+
@ahnrc = YAML.load(new_ahnrc).freeze
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def logging(options)
|
69
|
+
Adhearsion::Logging.logging_level = options[:level]
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_component(*list)
|
73
|
+
AHN_CONFIG.components_to_load |= list
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Adhearsion's .ahnrc file is used to define paths to certain parts of the framework. For example, the name dialplan.rb
|
78
|
+
# is actually specified in .ahnrc. This file can actually be just a filename, a filename with a glob (.e.g "*.rb"), an
|
79
|
+
# Array of filenames or even an Array of globs.
|
80
|
+
#
|
81
|
+
# @param [String,Array] String segments which convey the nesting of Hash keys through .ahnrc
|
82
|
+
# @raise [RuntimeError] If ahnrc has not been set yet with #ahnrc=()
|
83
|
+
# @raise [NameError] If the path through the ahnrc is invalid
|
84
|
+
#
|
85
|
+
def files_from_setting(*path_through_config)
|
86
|
+
raise RuntimeError, "No ahnrc has been set yet!" unless @ahnrc
|
87
|
+
queried_nested_setting = path_through_config.flatten.inject(@ahnrc) do |hash,key_name|
|
88
|
+
if hash.kind_of?(Hash) && hash.has_key?(key_name)
|
89
|
+
hash[key_name]
|
90
|
+
else
|
91
|
+
raise NameError, "Paths #{path_through_config.inspect} not found in .ahnrc!"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
raise NameError, "Paths #{path_through_config.inspect} not found in .ahnrc!" unless queried_nested_setting
|
95
|
+
queried_nested_setting = Array queried_nested_setting
|
96
|
+
queried_nested_setting.map { |filename| files_from_glob(filename) }.flatten.uniq
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def files_from_glob(glob)
|
102
|
+
Dir.glob "#{AHN_ROOT}/#{glob}"
|
103
|
+
end
|
104
|
+
|
105
|
+
class AbstractConfiguration
|
106
|
+
extend ConfigurationEntryPoint
|
107
|
+
|
108
|
+
class << self
|
109
|
+
private
|
110
|
+
def abstract_method!
|
111
|
+
raise "Must be implemented in subclasses"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def initialize(overrides = {})
|
116
|
+
overrides.each_pair do |attribute, value|
|
117
|
+
send("#{attribute}=", value)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Abstract superclass for AsteriskConfiguration and FreeSwitchConfiguration.
|
123
|
+
class TelephonyPlatformConfiguration < AbstractConfiguration
|
124
|
+
attr_accessor :listening_port
|
125
|
+
attr_accessor :listening_host
|
126
|
+
|
127
|
+
class << self
|
128
|
+
def default_listening_port
|
129
|
+
abstract_method!
|
130
|
+
end
|
131
|
+
|
132
|
+
def default_listening_host
|
133
|
+
'0.0.0.0'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def initialize(overrides = {})
|
138
|
+
@listening_host = overrides.has_key?(:host) ? overrides.delete(:host) : self.class.default_listening_host
|
139
|
+
@listening_port = overrides.has_key?(:port) ? overrides.delete(:port) : self.class.default_listening_port
|
140
|
+
super
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class AsteriskConfiguration < TelephonyPlatformConfiguration
|
145
|
+
attr_accessor :speech_engine
|
146
|
+
attr_accessor :argument_delimiter
|
147
|
+
|
148
|
+
class << self
|
149
|
+
def default_listening_port
|
150
|
+
4573
|
151
|
+
end
|
152
|
+
|
153
|
+
# Keep Asterisk 1.4 (and prior) as the default to protect upgraders
|
154
|
+
# This setting only applies to AGI. AMI delimiters are always
|
155
|
+
# auto-detected.
|
156
|
+
def default_argument_delimiter
|
157
|
+
'|'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def initialize(overrides = {})
|
162
|
+
@argument_delimiter = self.class.default_argument_delimiter
|
163
|
+
super
|
164
|
+
end
|
165
|
+
|
166
|
+
class AMIConfiguration < AbstractConfiguration
|
167
|
+
attr_accessor :port, :username, :password, :events, :host, :auto_reconnect
|
168
|
+
|
169
|
+
class << self
|
170
|
+
def default_port
|
171
|
+
5038
|
172
|
+
end
|
173
|
+
|
174
|
+
def default_events
|
175
|
+
false
|
176
|
+
end
|
177
|
+
|
178
|
+
def default_host
|
179
|
+
'localhost'
|
180
|
+
end
|
181
|
+
|
182
|
+
def default_auto_reconnect
|
183
|
+
true
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def initialize(overrides = {})
|
188
|
+
self.host = self.class.default_host
|
189
|
+
self.port = self.class.default_port
|
190
|
+
self.events = self.class.default_events
|
191
|
+
self.auto_reconnect = self.class.default_auto_reconnect
|
192
|
+
super
|
193
|
+
end
|
194
|
+
end
|
195
|
+
add_configuration_for :AMI
|
196
|
+
end
|
197
|
+
add_configuration_for :Asterisk
|
198
|
+
|
199
|
+
class FreeswitchConfiguration < TelephonyPlatformConfiguration
|
200
|
+
class << self
|
201
|
+
def default_listening_port
|
202
|
+
4572
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
add_configuration_for :Freeswitch
|
207
|
+
|
208
|
+
class DatabaseConfiguration < AbstractConfiguration
|
209
|
+
attr_accessor :connection_options, :orm
|
210
|
+
def initialize(options)
|
211
|
+
@orm = options.delete(:orm) || :active_record # TODO: ORM is a misnomer
|
212
|
+
@connection_options = options
|
213
|
+
end
|
214
|
+
end
|
215
|
+
add_configuration_for :Database
|
216
|
+
|
217
|
+
class LdapConfiguration < AbstractConfiguration
|
218
|
+
attr_accessor :connection_options
|
219
|
+
def initialize(options)
|
220
|
+
@connection_options = options
|
221
|
+
end
|
222
|
+
end
|
223
|
+
add_configuration_for :Ldap
|
224
|
+
|
225
|
+
class DrbConfiguration < AbstractConfiguration
|
226
|
+
attr_accessor :port
|
227
|
+
attr_accessor :host
|
228
|
+
attr_accessor :acl
|
229
|
+
|
230
|
+
# ACL = Access Control List
|
231
|
+
|
232
|
+
class << self
|
233
|
+
def default_port
|
234
|
+
9050
|
235
|
+
end
|
236
|
+
|
237
|
+
def default_host
|
238
|
+
'localhost'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def initialize(overrides = {})
|
243
|
+
self.port = overrides[:port] || self.class.default_port
|
244
|
+
self.host = overrides[:host] || self.class.default_host
|
245
|
+
self.acl = overrides[:raw_acl]
|
246
|
+
|
247
|
+
unless acl
|
248
|
+
self.acl = []
|
249
|
+
overrides[ :deny].to_a.each { |ip| acl << 'deny' << ip }
|
250
|
+
overrides[:allow].to_a.each { |ip| acl << 'allow' << ip }
|
251
|
+
acl.concat %w[allow 127.0.0.1] if acl.empty?
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
add_configuration_for :Drb
|
256
|
+
|
257
|
+
class RailsConfiguration < AbstractConfiguration
|
258
|
+
|
259
|
+
attr_accessor :rails_root, :environment
|
260
|
+
def initialize(options)
|
261
|
+
path_to_rails, environment = check_options options
|
262
|
+
@rails_root = File.expand_path(path_to_rails)
|
263
|
+
@environment = environment.to_sym
|
264
|
+
end
|
265
|
+
|
266
|
+
private
|
267
|
+
|
268
|
+
def check_options(options)
|
269
|
+
options = options.clone
|
270
|
+
path = options.delete :path
|
271
|
+
env = options.delete :env
|
272
|
+
raise ArgumentError, "Unrecognied argument(s) #{options.keys.to_sentence} in Rails initializer!" unless options.size.zero?
|
273
|
+
raise ArgumentError, "Must supply an :env argument to the Rails initializer!" unless env
|
274
|
+
raise ArgumentError, "Must supply an :path argument to the Rails initializer!" unless path
|
275
|
+
[path, env]
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
279
|
+
add_configuration_for :Rails
|
280
|
+
|
281
|
+
class XMPPConfiguration < AbstractConfiguration
|
282
|
+
|
283
|
+
attr_accessor :jid, :password, :server, :port
|
284
|
+
def initialize(options)
|
285
|
+
jid, password, server, port = check_options options
|
286
|
+
@jid = jid
|
287
|
+
@password = password
|
288
|
+
@server = server
|
289
|
+
@port = port
|
290
|
+
end
|
291
|
+
|
292
|
+
class << self
|
293
|
+
def default_port
|
294
|
+
5222
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
private
|
299
|
+
|
300
|
+
def check_options(options)
|
301
|
+
options = options.clone
|
302
|
+
jid = options.delete :jid
|
303
|
+
password = options.delete :password
|
304
|
+
server = options.delete :server
|
305
|
+
port = options.delete :port
|
306
|
+
raise ArgumentError, "Unrecognied argument(s) #{options.keys.to_sentence} in XMPP initializer!" unless options.size.zero?
|
307
|
+
raise ArgumentError, "Must supply a :jid argument to the XMPP initializer!" unless jid
|
308
|
+
raise ArgumentError, "Must supply a :password argument to the XMPP initializer!" unless password
|
309
|
+
if server
|
310
|
+
port ||= self.class.default_port
|
311
|
+
else
|
312
|
+
raise ArgumentError, "Must supply a :server argument as well as :port to the XMPP initializer!" if port
|
313
|
+
end
|
314
|
+
[jid, password, server, port]
|
315
|
+
end
|
316
|
+
|
317
|
+
end
|
318
|
+
add_configuration_for :XMPP
|
319
|
+
|
320
|
+
end
|
321
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# TODO: Have all of the initializer modules required and then traverse the subclasses, asking them if they're enabled. If they are enabled, then they should do their initialization stuff. Is this really necessary to develop this entirely new system when the components system exists?
|
2
|
+
|
3
|
+
module Adhearsion
|
4
|
+
class Initializer
|
5
|
+
|
6
|
+
class DatabaseInitializer
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def start
|
11
|
+
require_dependencies
|
12
|
+
require_models
|
13
|
+
@@config = Adhearsion::AHN_CONFIG.database
|
14
|
+
# You may need to uncomment the following line for older versions of ActiveRecord
|
15
|
+
# ActiveRecord::Base.allow_concurrency = true
|
16
|
+
establish_connection
|
17
|
+
ActiveRecord::Base.logger =
|
18
|
+
@@config.connection_options.has_key?(:logger) ?
|
19
|
+
@@config.connection_options[:logger] :
|
20
|
+
ahn_log.db
|
21
|
+
create_call_hook_for_connection_cleanup
|
22
|
+
end
|
23
|
+
|
24
|
+
def stop
|
25
|
+
ActiveRecord::Base.remove_connection
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def create_call_hook_for_connection_cleanup
|
31
|
+
Events.register_callback([:asterisk, :before_call]) do
|
32
|
+
ActiveRecord::Base.verify_active_connections!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def require_dependencies
|
37
|
+
begin
|
38
|
+
require 'active_record'
|
39
|
+
rescue LoadError
|
40
|
+
ahn_log.fatal "Database support requires the \"activerecord\" gem."
|
41
|
+
# Silence the abort so we don't get an ugly backtrace
|
42
|
+
abort ""
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def require_models
|
47
|
+
AHN_CONFIG.files_from_setting("paths", "models").each do |model|
|
48
|
+
load model
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def establish_connection
|
53
|
+
ActiveRecord::Base.establish_connection @@config.connection_options
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|