eric-adhearsion 0.7.999
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/LICENSE +456 -0
- data/Manifest.txt +149 -0
- data/README.txt +6 -0
- data/Rakefile +48 -0
- data/ahn_generators/component/USAGE +5 -0
- data/ahn_generators/component/component_generator.rb +57 -0
- data/ahn_generators/component/templates/configuration.rb +0 -0
- data/ahn_generators/component/templates/lib/lib.rb.erb +3 -0
- data/ahn_generators/component/templates/test/test.rb.erb +12 -0
- data/ahn_generators/component/templates/test/test_helper.rb +14 -0
- data/app_generators/ahn/USAGE +5 -0
- data/app_generators/ahn/ahn_generator.rb +76 -0
- data/app_generators/ahn/templates/.ahnrc +12 -0
- data/app_generators/ahn/templates/README +8 -0
- data/app_generators/ahn/templates/Rakefile +3 -0
- data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
- data/app_generators/ahn/templates/components/simon_game/lib/simon_game.rb +61 -0
- data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +14 -0
- data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +31 -0
- data/app_generators/ahn/templates/config/startup.rb +53 -0
- data/app_generators/ahn/templates/dialplan.rb +4 -0
- data/bin/ahn +28 -0
- data/bin/ahnctl +68 -0
- data/bin/jahn +32 -0
- data/lib/adhearsion/blank_slate.rb +5 -0
- data/lib/adhearsion/cli.rb +106 -0
- data/lib/adhearsion/component_manager.rb +277 -0
- data/lib/adhearsion/core_extensions/all.rb +9 -0
- data/lib/adhearsion/core_extensions/array.rb +0 -0
- data/lib/adhearsion/core_extensions/custom_daemonizer.rb +45 -0
- data/lib/adhearsion/core_extensions/global.rb +1 -0
- data/lib/adhearsion/core_extensions/guid.rb +5 -0
- data/lib/adhearsion/core_extensions/hash.rb +0 -0
- data/lib/adhearsion/core_extensions/metaprogramming.rb +17 -0
- data/lib/adhearsion/core_extensions/numeric.rb +4 -0
- data/lib/adhearsion/core_extensions/proc.rb +0 -0
- data/lib/adhearsion/core_extensions/pseudo_uuid.rb +11 -0
- data/lib/adhearsion/core_extensions/publishable.rb +73 -0
- data/lib/adhearsion/core_extensions/relationship_properties.rb +40 -0
- data/lib/adhearsion/core_extensions/string.rb +26 -0
- data/lib/adhearsion/core_extensions/thread.rb +13 -0
- data/lib/adhearsion/core_extensions/thread_safety.rb +7 -0
- data/lib/adhearsion/core_extensions/time.rb +0 -0
- data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/rest_gateway.rb +9 -0
- data/lib/adhearsion/distributed/gateways/soap_gateway.rb +9 -0
- data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +9 -0
- data/lib/adhearsion/distributed/peer_finder.rb +0 -0
- data/lib/adhearsion/distributed/remote_cli.rb +0 -0
- data/lib/adhearsion/hooks.rb +57 -0
- data/lib/adhearsion/host_definitions.rb +63 -0
- data/lib/adhearsion/initializer/asterisk.rb +59 -0
- data/lib/adhearsion/initializer/configuration.rb +202 -0
- data/lib/adhearsion/initializer/database.rb +92 -0
- data/lib/adhearsion/initializer/drb.rb +25 -0
- data/lib/adhearsion/initializer/freeswitch.rb +22 -0
- data/lib/adhearsion/initializer/paths.rb +55 -0
- data/lib/adhearsion/initializer/rails.rb +40 -0
- data/lib/adhearsion/initializer.rb +217 -0
- data/lib/adhearsion/logging.rb +92 -0
- data/lib/adhearsion/services/scheduler.rb +5 -0
- data/lib/adhearsion/tasks/database.rb +5 -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/tasks.rb +15 -0
- data/lib/adhearsion/version.rb +9 -0
- data/lib/adhearsion/voip/asterisk/agi_server.rb +78 -0
- data/lib/adhearsion/voip/asterisk/ami/actions.rb +238 -0
- data/lib/adhearsion/voip/asterisk/ami/machine.rb +871 -0
- data/lib/adhearsion/voip/asterisk/ami/machine.rl +109 -0
- data/lib/adhearsion/voip/asterisk/ami/parser.rb +262 -0
- data/lib/adhearsion/voip/asterisk/ami.rb +147 -0
- data/lib/adhearsion/voip/asterisk/commands.rb +1182 -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/special_dial_plan_managers.rb +80 -0
- data/lib/adhearsion/voip/asterisk.rb +4 -0
- data/lib/adhearsion/voip/call.rb +391 -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 +205 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -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 +75 -0
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
- data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -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.rb +31 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/fixtures/dialplan.rb +3 -0
- data/spec/initializer/test_configuration.rb +267 -0
- data/spec/initializer/test_loading.rb +162 -0
- data/spec/initializer/test_paths.rb +43 -0
- data/spec/silence.rb +10 -0
- data/spec/test_ahn_command.rb +149 -0
- data/spec/test_code_quality.rb +87 -0
- data/spec/test_component_manager.rb +97 -0
- data/spec/test_constants.rb +8 -0
- data/spec/test_drb.rb +104 -0
- data/spec/test_helper.rb +94 -0
- data/spec/test_hooks.rb +37 -0
- data/spec/test_host_definitions.rb +79 -0
- data/spec/test_initialization.rb +105 -0
- data/spec/test_logging.rb +80 -0
- data/spec/test_relationship_properties.rb +54 -0
- data/spec/voip/asterisk/ami_response_definitions.rb +23 -0
- data/spec/voip/asterisk/config_file_generators/test_agents.rb +253 -0
- data/spec/voip/asterisk/config_file_generators/test_queues.rb +325 -0
- data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +306 -0
- data/spec/voip/asterisk/menu_command/test_calculated_match.rb +111 -0
- data/spec/voip/asterisk/menu_command/test_matchers.rb +98 -0
- data/spec/voip/asterisk/mock_ami_server.rb +176 -0
- data/spec/voip/asterisk/test_agi_server.rb +451 -0
- data/spec/voip/asterisk/test_ami.rb +227 -0
- data/spec/voip/asterisk/test_commands.rb +2006 -0
- data/spec/voip/asterisk/test_config_manager.rb +129 -0
- data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
- data/spec/voip/dsl/test_dialing_dsl.rb +268 -0
- data/spec/voip/dsl/test_dispatcher.rb +82 -0
- data/spec/voip/dsl/test_parser.rb +87 -0
- data/spec/voip/freeswitch/test_basic_connection_manager.rb +39 -0
- data/spec/voip/freeswitch/test_inbound_connection_manager.rb +39 -0
- data/spec/voip/freeswitch/test_oes_server.rb +9 -0
- data/spec/voip/test_call_routing.rb +127 -0
- data/spec/voip/test_dialplan_manager.rb +372 -0
- data/spec/voip/test_numerical_string.rb +48 -0
- data/spec/voip/test_phone_number.rb +36 -0
- data/test/test_ahn_generator.rb +59 -0
- data/test/test_component_generator.rb +52 -0
- data/test/test_generator_helper.rb +20 -0
- metadata +254 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Adhearsion
|
4
|
+
class HostDefinition
|
5
|
+
|
6
|
+
SUPPORTED_KEYS = [:host, :username, :password, :key, :name]
|
7
|
+
|
8
|
+
cattr_reader :definitions
|
9
|
+
@@definitions ||= []
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def import_from_data_structure(local_definitions)
|
13
|
+
case local_definitions
|
14
|
+
when Array
|
15
|
+
local_definitions.each do |definition|
|
16
|
+
raise HostDefinitionException, "Unrecognized definition: #{definition}" unless definition.is_a?(Hash)
|
17
|
+
end
|
18
|
+
local_definitions.map { |definition| new definition }
|
19
|
+
when Hash
|
20
|
+
local_definitions.map do |(name,definition)|
|
21
|
+
new definition.merge(:name => name)
|
22
|
+
end
|
23
|
+
else
|
24
|
+
raise HostDefinitionException, "Unrecognized definition #{local_definitions}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def import_from_yaml(yaml_string)
|
29
|
+
import_from_data_structure YAML.load(yaml_string)
|
30
|
+
end
|
31
|
+
|
32
|
+
def import_from_yaml_file(file)
|
33
|
+
import_from_yaml YAML.load_file(file)
|
34
|
+
end
|
35
|
+
|
36
|
+
def clear_definitions!
|
37
|
+
definitions.clear
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :name, :host, :username, :password, :key
|
42
|
+
def initialize(hash)
|
43
|
+
@host, @username, @password, @key, @name = hash.values_at(*SUPPORTED_KEYS)
|
44
|
+
@name ||= uuid
|
45
|
+
|
46
|
+
unrecognized_keys = hash.keys - SUPPORTED_KEYS
|
47
|
+
raise HostDefinitionException, "Unrecognized key(s): #{unrecognized_keys.map(&:inspect).to_sentence}" if unrecognized_keys.any?
|
48
|
+
raise HostDefinitionException, "You must supply a password or key!" if username && !(password || key)
|
49
|
+
raise HostDefinitionException, "You must supply a username!" unless username
|
50
|
+
raise HostDefinitionException, 'You cannot supply both a password and key!' if password && key
|
51
|
+
raise HostDefinitionException, 'You must supply a host!' unless host
|
52
|
+
|
53
|
+
self.class.definitions << self
|
54
|
+
end
|
55
|
+
|
56
|
+
class HostDefinitionException < Exception
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,59 @@
|
|
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 = Adhearsion::AHN_CONFIG.asterisk
|
12
|
+
self.agi_server = initialize_agi
|
13
|
+
self.ami_client = initialize_ami if config.ami_enabled?
|
14
|
+
join_server_thread_after_initialized
|
15
|
+
end
|
16
|
+
|
17
|
+
def stop
|
18
|
+
agi_server.stop
|
19
|
+
ami_client.disconnect! if ami_client
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def initialize_agi
|
25
|
+
Adhearsion::VoIP::Asterisk::AGI::Server.new :host => config.listening_host,
|
26
|
+
:port => config.listening_port
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize_ami
|
30
|
+
options = ami_options
|
31
|
+
start_ami_after_initialized
|
32
|
+
Adhearsion::VoIP::Asterisk::AMI.new options[:username], options[:password],
|
33
|
+
options[:host], :port => options[:port],
|
34
|
+
:events => options[:events]
|
35
|
+
end
|
36
|
+
|
37
|
+
def ami_options
|
38
|
+
%w(host port username password events).inject({}) do |options, property|
|
39
|
+
options[property.to_sym] = config.ami.send property
|
40
|
+
options
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def join_server_thread_after_initialized
|
45
|
+
Adhearsion::Hooks::AfterInitialized.create_hook { agi_server.start }
|
46
|
+
Adhearsion::Hooks::ThreadsJoinedAfterInitialized.create_hook { agi_server.join }
|
47
|
+
end
|
48
|
+
|
49
|
+
def start_ami_after_initialized
|
50
|
+
Adhearsion::Hooks::AfterInitialized.create_hook do
|
51
|
+
ami_client.connect!
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,202 @@
|
|
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
|
+
Adhearsion.module_eval { remove_const(:AHN_CONFIG) } if Adhearsion.const_defined?(:AHN_CONFIG)
|
28
|
+
Adhearsion.const_set(:AHN_CONFIG, new(&block))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :automatically_answer_incoming_calls
|
33
|
+
attr_accessor :end_call_on_hangup
|
34
|
+
attr_accessor :end_call_on_error
|
35
|
+
|
36
|
+
def logging(options)
|
37
|
+
Adhearsion::Logging.logging_level = options[:level]
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@automatically_answer_incoming_calls = true
|
42
|
+
@end_call_on_hangup = true
|
43
|
+
@end_call_on_error = true
|
44
|
+
yield self if block_given?
|
45
|
+
end
|
46
|
+
|
47
|
+
class AbstractConfiguration
|
48
|
+
extend ConfigurationEntryPoint
|
49
|
+
|
50
|
+
class << self
|
51
|
+
private
|
52
|
+
def abstract_method!
|
53
|
+
raise "Must be implemented in subclasses"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(overrides = {})
|
58
|
+
overrides.each_pair do |attribute, value|
|
59
|
+
send("#{attribute}=", value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Abstract superclass for AsteriskConfiguration and FreeSwitchConfiguration.
|
65
|
+
class TelephonyPlatformConfiguration < AbstractConfiguration
|
66
|
+
attr_accessor :listening_port
|
67
|
+
attr_accessor :listening_host
|
68
|
+
|
69
|
+
class << self
|
70
|
+
def default_listening_port
|
71
|
+
abstract_method!
|
72
|
+
end
|
73
|
+
|
74
|
+
def default_listening_host
|
75
|
+
'0.0.0.0'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def initialize(overrides = {})
|
80
|
+
@listening_port = self.class.default_listening_port
|
81
|
+
@listening_host = self.class.default_listening_host
|
82
|
+
super
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class AsteriskConfiguration < TelephonyPlatformConfiguration
|
87
|
+
class << self
|
88
|
+
attr_accessor :speech_engine
|
89
|
+
|
90
|
+
def default_listening_port
|
91
|
+
4573
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class AMIConfiguration < AbstractConfiguration
|
96
|
+
attr_accessor :port, :username, :password, :events, :host
|
97
|
+
|
98
|
+
class << self
|
99
|
+
def default_port
|
100
|
+
5038
|
101
|
+
end
|
102
|
+
|
103
|
+
def default_events
|
104
|
+
false
|
105
|
+
end
|
106
|
+
|
107
|
+
def default_host
|
108
|
+
'localhost'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def initialize(overrides = {})
|
113
|
+
self.host = self.class.default_host
|
114
|
+
self.port = self.class.default_port
|
115
|
+
self.events = self.class.default_events
|
116
|
+
super
|
117
|
+
end
|
118
|
+
end
|
119
|
+
add_configuration_for :AMI
|
120
|
+
end
|
121
|
+
add_configuration_for :Asterisk
|
122
|
+
|
123
|
+
class FreeswitchConfiguration < TelephonyPlatformConfiguration
|
124
|
+
class << self
|
125
|
+
def default_listening_port
|
126
|
+
4572
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
add_configuration_for :Freeswitch
|
131
|
+
|
132
|
+
class DatabaseConfiguration < AbstractConfiguration
|
133
|
+
attr_accessor :connection_options, :orm
|
134
|
+
def initialize(options)
|
135
|
+
@orm = options.delete(:orm) || :active_record # TODO: ORM is a misnomer
|
136
|
+
@connection_options = options
|
137
|
+
end
|
138
|
+
end
|
139
|
+
add_configuration_for :Database
|
140
|
+
|
141
|
+
class DrbConfiguration < AbstractConfiguration
|
142
|
+
attr_accessor :port
|
143
|
+
attr_accessor :host
|
144
|
+
attr_accessor :acl
|
145
|
+
|
146
|
+
# ACL = Access Control List
|
147
|
+
|
148
|
+
class << self
|
149
|
+
def default_port
|
150
|
+
9050
|
151
|
+
end
|
152
|
+
|
153
|
+
def default_host
|
154
|
+
'localhost'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def initialize(overrides = {})
|
159
|
+
self.port = overrides[:port] || self.class.default_port
|
160
|
+
self.host = overrides[:host] || self.class.default_host
|
161
|
+
self.acl = overrides[:raw_acl]
|
162
|
+
|
163
|
+
unless acl
|
164
|
+
self.acl = []
|
165
|
+
overrides[ :deny].to_a.each { |ip| acl << 'deny' << ip }
|
166
|
+
overrides[:allow].to_a.each { |ip| acl << 'allow' << ip }
|
167
|
+
acl.concat %w[allow 127.0.0.1] if acl.empty?
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
add_configuration_for :Drb
|
172
|
+
|
173
|
+
class RailsConfiguration < AbstractConfiguration
|
174
|
+
|
175
|
+
SUPPORTED_RAILS_ENVIRONMENTS = [:development, :test, :production]
|
176
|
+
|
177
|
+
attr_accessor :rails_root, :environment
|
178
|
+
def initialize(options)
|
179
|
+
path_to_rails, environment = check_options options
|
180
|
+
@rails_root = File.expand_path(path_to_rails)
|
181
|
+
@environment = environment.to_sym
|
182
|
+
raise ArgumentError, "Unrecognized environment type #@environment. Supported: " +
|
183
|
+
SUPPORTED_RAILS_ENVIRONMENTS.to_sentence unless SUPPORTED_RAILS_ENVIRONMENTS.include?(@environment)
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
def check_options(options)
|
189
|
+
options = options.clone
|
190
|
+
path = options.delete :path
|
191
|
+
env = options.delete :env
|
192
|
+
raise ArgumentError, "Unrecognied argument(s) #{options.keys.to_sentence} in Rails initializer!" unless options.size.zero?
|
193
|
+
raise ArgumentError, "Must supply an :env argument to the Rails initializer!" unless env
|
194
|
+
raise ArgumentError, "Must supply an :path argument to the Rails initializer!" unless path
|
195
|
+
[path, env]
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
add_configuration_for :Rails
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,92 @@
|
|
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
|
+
ActiveRecord::Base.allow_concurrency = true
|
15
|
+
establish_connection
|
16
|
+
create_call_hook_for_connection_cleanup
|
17
|
+
end
|
18
|
+
|
19
|
+
def stop
|
20
|
+
ActiveRecord::Base.remove_connection
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_call_hook_for_connection_cleanup
|
26
|
+
Hooks::BeforeCall.create_hook do
|
27
|
+
ActiveRecord::Base.verify_active_connections!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def require_dependencies
|
32
|
+
require 'active_record'
|
33
|
+
end
|
34
|
+
|
35
|
+
def require_models
|
36
|
+
all_models.each do |model|
|
37
|
+
load model
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def establish_connection
|
42
|
+
ActiveRecord::Base.establish_connection @@config.connection_options
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
=begin
|
52
|
+
db_config = Adhearsion::Configuration.core.database
|
53
|
+
if db_config
|
54
|
+
unless Adhearsion::Paths.manager_for? "models"
|
55
|
+
raise "No paths specified for the database 'models' in .ahnrc! Aborting."
|
56
|
+
end
|
57
|
+
require 'active_record'
|
58
|
+
|
59
|
+
ActiveRecord::Base.verification_timeout = 14400
|
60
|
+
ActiveRecord::Base.logger = Logger.new("log/database.log")
|
61
|
+
ActiveRecord::Base.establish_connection db_config
|
62
|
+
|
63
|
+
all_models.each { |model| require model }
|
64
|
+
|
65
|
+
# Below is a monkey patch for keeping ActiveRecord connections alive.
|
66
|
+
# http://www.sparecycles.org/2007/7/2/saying-goodbye-to-lost-connections-in-rails
|
67
|
+
|
68
|
+
module ActiveRecord
|
69
|
+
module ConnectionAdapters
|
70
|
+
class MysqlAdapter
|
71
|
+
def execute(sql, name = nil) #:nodoc:
|
72
|
+
reconnect_lost_connections = true
|
73
|
+
begin
|
74
|
+
log(sql, name) { @connection.query(sql) }
|
75
|
+
rescue ActiveRecord::StatementInvalid => exception
|
76
|
+
if reconnect_lost_connections and exception.message =~ /(Lost connection to MySQL server during query|MySQL server has gone away)/
|
77
|
+
reconnect_lost_connections = false
|
78
|
+
reconnect!
|
79
|
+
retry
|
80
|
+
elsif exception.message.split(":").first =~ /Packets out of order/
|
81
|
+
raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
|
82
|
+
else
|
83
|
+
raise
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
=end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'drb'
|
2
|
+
require 'drb/acl'
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
module Adhearsion
|
6
|
+
class Initializer
|
7
|
+
|
8
|
+
class DrbInitializer
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def start
|
13
|
+
config = Adhearsion::AHN_CONFIG.drb
|
14
|
+
DRb.install_acl ACL.new(config.acl) if config.acl
|
15
|
+
DRb.start_service "druby://#{config.host}:#{config.port}", Adhearsion::DrbDoor.instance
|
16
|
+
ahn_log "Starting DRb on #{config.host}:#{config.port}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def stop
|
20
|
+
DRb.stop_service
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# THIS FREESWITCH LIBRARY HASN'T BEEN INTEGRATED INTO THE REFACTORED 0.8.0 YET.
|
2
|
+
# WHAT EXISTS HERE IS OLD, MUST BE CHANGED, AND DOES NOT EVEN GET LOADED AT THE MOMENT.
|
3
|
+
require "adhearsion/voip/freeswitch/oes_server"
|
4
|
+
require "adhearsion/voip/freeswitch/event_handler"
|
5
|
+
require "adhearsion/voip/freeswitch/inbound_connection_manager"
|
6
|
+
require "adhearsion/voip/dsl/dialplan/control_passing_exception"
|
7
|
+
|
8
|
+
oes_enabled = Adhearsion::Configuration.core.voip.freeswitch.oes && Adhearsion::Configuration.core.voip.freeswitch.oes.port
|
9
|
+
|
10
|
+
|
11
|
+
if oes_enabled
|
12
|
+
|
13
|
+
port = Adhearsion::Configuration.core.voip.freeswitch.oes.port
|
14
|
+
host = Adhearsion::Configuration.core.voip.freeswitch.oes.host
|
15
|
+
|
16
|
+
server = Adhearsion::VoIP::FreeSwitch::OesServer.new port, host
|
17
|
+
|
18
|
+
Adhearsion::Hooks::AfterInitialized.create_hook { server.start }
|
19
|
+
Adhearsion::Hooks::ThreadsJoinedAfterInitialized.create_hook { server.join }
|
20
|
+
Adhearsion::Hooks::TearDown.create_hook { server.stop }
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Adhearsion
|
2
|
+
|
3
|
+
# Paths are a way for helpers to have Adhearsion manage dynamic
|
4
|
+
# paths.
|
5
|
+
module Paths
|
6
|
+
|
7
|
+
# May need to build some kind of namespacing?
|
8
|
+
|
9
|
+
@@path_managers = {}
|
10
|
+
|
11
|
+
def self.manager_for(name, hash)
|
12
|
+
globs = Array hash[:pattern] || hash[:patterns]
|
13
|
+
directory = hash[:directory]
|
14
|
+
name = name.to_s.underscore
|
15
|
+
singular, plural = name.singularize, name.pluralize
|
16
|
+
@@path_managers[singular] = globs
|
17
|
+
#TODO: YAGNI. Bad magic
|
18
|
+
Kernel.module_eval do
|
19
|
+
define_method "#{singular}_path" do |query|
|
20
|
+
target = nil
|
21
|
+
globs.each do |mgr|
|
22
|
+
Dir.glob(mgr).each do |f|
|
23
|
+
#return f if File.basename(f) == query
|
24
|
+
target = File.expand_path(f) if File.basename(f) == query
|
25
|
+
end
|
26
|
+
end
|
27
|
+
target
|
28
|
+
end
|
29
|
+
define_method "all_#{plural}" do
|
30
|
+
globs.map { |g| Dir.glob g }.flatten
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.manager_for?(name)
|
36
|
+
@@path_managers[name.to_s.underscore.singularize]
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.remove_manager_for(name)
|
40
|
+
name = name.to_s
|
41
|
+
singular, plural = name.singularize, name.pluralize
|
42
|
+
Kernel.module_eval do
|
43
|
+
undef_method "all_#{plural}", "#{singular}_path"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# When creating with a combined managers, the first
|
48
|
+
# writable directory is returned.
|
49
|
+
def self.combine_managers(name, *managers)
|
50
|
+
# TODO: Searches several managers in sequence.
|
51
|
+
name = name.to_s.underscore
|
52
|
+
singular, plural = name.singularize, name.pluralize
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'adhearsion/voip/asterisk'
|
2
|
+
|
3
|
+
module Adhearsion
|
4
|
+
class Initializer
|
5
|
+
class RailsInitializer
|
6
|
+
|
7
|
+
cattr_accessor :rails_root, :config, :environment
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def start
|
11
|
+
ahn_config = Adhearsion::AHN_CONFIG
|
12
|
+
self.config = ahn_config.rails
|
13
|
+
self.rails_root = config.rails_root
|
14
|
+
self.environment = config.environment
|
15
|
+
raise "You cannot enable the database and Rails at the same time!" if ahn_config.database_enabled?
|
16
|
+
raise "Error loading Rails environment in #{rails_root.inspect}. " +
|
17
|
+
"It's not a directory!" unless File.directory?(rails_root)
|
18
|
+
load_rails
|
19
|
+
if defined? ActiveRecord
|
20
|
+
ActiveRecord::Base.allow_concurrency = true
|
21
|
+
Hooks::BeforeCall.create_hook do
|
22
|
+
ActiveRecord::Base.verify_active_connections!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def load_rails
|
30
|
+
environment_file = File.expand_path(rails_root + "/config/environment.rb")
|
31
|
+
raise "There is no config/environment.rb file!" unless File.exists?(environment_file)
|
32
|
+
ENV['RAILS_ENV'] = environment.to_s
|
33
|
+
require environment_file
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|