sevenscale-adhearsion 0.7.1000

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.
Files changed (150) hide show
  1. data/CHANGELOG +3 -0
  2. data/LICENSE +456 -0
  3. data/Manifest.txt +149 -0
  4. data/README.txt +6 -0
  5. data/Rakefile +48 -0
  6. data/ahn_generators/component/USAGE +5 -0
  7. data/ahn_generators/component/component_generator.rb +57 -0
  8. data/ahn_generators/component/templates/configuration.rb +0 -0
  9. data/ahn_generators/component/templates/lib/lib.rb.erb +3 -0
  10. data/ahn_generators/component/templates/test/test.rb.erb +12 -0
  11. data/ahn_generators/component/templates/test/test_helper.rb +14 -0
  12. data/app_generators/ahn/USAGE +5 -0
  13. data/app_generators/ahn/ahn_generator.rb +76 -0
  14. data/app_generators/ahn/templates/.ahnrc +12 -0
  15. data/app_generators/ahn/templates/README +8 -0
  16. data/app_generators/ahn/templates/Rakefile +3 -0
  17. data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
  18. data/app_generators/ahn/templates/components/simon_game/lib/simon_game.rb +61 -0
  19. data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +14 -0
  20. data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +31 -0
  21. data/app_generators/ahn/templates/config/startup.rb +53 -0
  22. data/app_generators/ahn/templates/dialplan.rb +4 -0
  23. data/bin/ahn +28 -0
  24. data/bin/ahnctl +68 -0
  25. data/bin/jahn +32 -0
  26. data/lib/adhearsion/blank_slate.rb +5 -0
  27. data/lib/adhearsion/cli.rb +106 -0
  28. data/lib/adhearsion/component_manager.rb +277 -0
  29. data/lib/adhearsion/core_extensions/all.rb +9 -0
  30. data/lib/adhearsion/core_extensions/array.rb +0 -0
  31. data/lib/adhearsion/core_extensions/custom_daemonizer.rb +45 -0
  32. data/lib/adhearsion/core_extensions/global.rb +1 -0
  33. data/lib/adhearsion/core_extensions/guid.rb +5 -0
  34. data/lib/adhearsion/core_extensions/hash.rb +0 -0
  35. data/lib/adhearsion/core_extensions/metaprogramming.rb +17 -0
  36. data/lib/adhearsion/core_extensions/numeric.rb +4 -0
  37. data/lib/adhearsion/core_extensions/proc.rb +0 -0
  38. data/lib/adhearsion/core_extensions/pseudo_uuid.rb +11 -0
  39. data/lib/adhearsion/core_extensions/publishable.rb +73 -0
  40. data/lib/adhearsion/core_extensions/relationship_properties.rb +40 -0
  41. data/lib/adhearsion/core_extensions/string.rb +26 -0
  42. data/lib/adhearsion/core_extensions/thread.rb +13 -0
  43. data/lib/adhearsion/core_extensions/thread_safety.rb +7 -0
  44. data/lib/adhearsion/core_extensions/time.rb +0 -0
  45. data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
  46. data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
  47. data/lib/adhearsion/distributed/gateways/rest_gateway.rb +9 -0
  48. data/lib/adhearsion/distributed/gateways/soap_gateway.rb +9 -0
  49. data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +9 -0
  50. data/lib/adhearsion/distributed/peer_finder.rb +0 -0
  51. data/lib/adhearsion/distributed/remote_cli.rb +0 -0
  52. data/lib/adhearsion/hooks.rb +57 -0
  53. data/lib/adhearsion/host_definitions.rb +63 -0
  54. data/lib/adhearsion/initializer/asterisk.rb +59 -0
  55. data/lib/adhearsion/initializer/configuration.rb +202 -0
  56. data/lib/adhearsion/initializer/database.rb +92 -0
  57. data/lib/adhearsion/initializer/drb.rb +25 -0
  58. data/lib/adhearsion/initializer/freeswitch.rb +22 -0
  59. data/lib/adhearsion/initializer/paths.rb +55 -0
  60. data/lib/adhearsion/initializer/rails.rb +40 -0
  61. data/lib/adhearsion/initializer.rb +217 -0
  62. data/lib/adhearsion/logging.rb +92 -0
  63. data/lib/adhearsion/services/scheduler.rb +5 -0
  64. data/lib/adhearsion/tasks/database.rb +5 -0
  65. data/lib/adhearsion/tasks/generating.rb +20 -0
  66. data/lib/adhearsion/tasks/lint.rb +4 -0
  67. data/lib/adhearsion/tasks/testing.rb +37 -0
  68. data/lib/adhearsion/tasks.rb +15 -0
  69. data/lib/adhearsion/version.rb +9 -0
  70. data/lib/adhearsion/voip/asterisk/agi_server.rb +78 -0
  71. data/lib/adhearsion/voip/asterisk/ami/actions.rb +238 -0
  72. data/lib/adhearsion/voip/asterisk/ami/machine.rb +871 -0
  73. data/lib/adhearsion/voip/asterisk/ami/machine.rl +109 -0
  74. data/lib/adhearsion/voip/asterisk/ami/parser.rb +262 -0
  75. data/lib/adhearsion/voip/asterisk/ami.rb +147 -0
  76. data/lib/adhearsion/voip/asterisk/commands.rb +1186 -0
  77. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
  78. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
  79. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
  80. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
  81. data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
  82. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
  83. data/lib/adhearsion/voip/asterisk.rb +4 -0
  84. data/lib/adhearsion/voip/call.rb +402 -0
  85. data/lib/adhearsion/voip/call_routing.rb +64 -0
  86. data/lib/adhearsion/voip/commands.rb +9 -0
  87. data/lib/adhearsion/voip/constants.rb +39 -0
  88. data/lib/adhearsion/voip/conveniences.rb +18 -0
  89. data/lib/adhearsion/voip/dial_plan.rb +205 -0
  90. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
  91. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
  92. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
  93. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
  94. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +75 -0
  95. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
  96. data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -0
  97. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
  98. data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
  99. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
  100. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
  101. data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
  102. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
  103. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
  104. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
  105. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
  106. data/lib/adhearsion.rb +31 -0
  107. data/script/destroy +14 -0
  108. data/script/generate +14 -0
  109. data/spec/fixtures/dialplan.rb +3 -0
  110. data/spec/initializer/test_configuration.rb +267 -0
  111. data/spec/initializer/test_loading.rb +162 -0
  112. data/spec/initializer/test_paths.rb +43 -0
  113. data/spec/silence.rb +10 -0
  114. data/spec/test_ahn_command.rb +149 -0
  115. data/spec/test_code_quality.rb +87 -0
  116. data/spec/test_component_manager.rb +97 -0
  117. data/spec/test_constants.rb +8 -0
  118. data/spec/test_drb.rb +104 -0
  119. data/spec/test_helper.rb +94 -0
  120. data/spec/test_hooks.rb +37 -0
  121. data/spec/test_host_definitions.rb +79 -0
  122. data/spec/test_initialization.rb +105 -0
  123. data/spec/test_logging.rb +80 -0
  124. data/spec/test_relationship_properties.rb +54 -0
  125. data/spec/voip/asterisk/ami_response_definitions.rb +23 -0
  126. data/spec/voip/asterisk/config_file_generators/test_agents.rb +253 -0
  127. data/spec/voip/asterisk/config_file_generators/test_queues.rb +325 -0
  128. data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +306 -0
  129. data/spec/voip/asterisk/menu_command/test_calculated_match.rb +111 -0
  130. data/spec/voip/asterisk/menu_command/test_matchers.rb +98 -0
  131. data/spec/voip/asterisk/mock_ami_server.rb +176 -0
  132. data/spec/voip/asterisk/test_agi_server.rb +453 -0
  133. data/spec/voip/asterisk/test_ami.rb +227 -0
  134. data/spec/voip/asterisk/test_commands.rb +2006 -0
  135. data/spec/voip/asterisk/test_config_manager.rb +129 -0
  136. data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
  137. data/spec/voip/dsl/test_dialing_dsl.rb +268 -0
  138. data/spec/voip/dsl/test_dispatcher.rb +82 -0
  139. data/spec/voip/dsl/test_parser.rb +87 -0
  140. data/spec/voip/freeswitch/test_basic_connection_manager.rb +39 -0
  141. data/spec/voip/freeswitch/test_inbound_connection_manager.rb +39 -0
  142. data/spec/voip/freeswitch/test_oes_server.rb +9 -0
  143. data/spec/voip/test_call_routing.rb +127 -0
  144. data/spec/voip/test_dialplan_manager.rb +372 -0
  145. data/spec/voip/test_numerical_string.rb +48 -0
  146. data/spec/voip/test_phone_number.rb +36 -0
  147. data/test/test_ahn_generator.rb +59 -0
  148. data/test/test_component_generator.rb +52 -0
  149. data/test/test_generator_helper.rb +20 -0
  150. metadata +254 -0
@@ -0,0 +1,217 @@
1
+ module Adhearsion
2
+
3
+ class PathString < String
4
+ attr_accessor :component_path, :dialplan_path, :log_path
5
+
6
+ def initialize(path)
7
+ super
8
+ defaults
9
+ end
10
+
11
+ def defaults
12
+ @component_path = build_path_for "components"
13
+ @dialplan_path = dup
14
+ @log_path = build_path_for "logs"
15
+ end
16
+
17
+ def base_path=(value)
18
+ replace(value)
19
+ defaults
20
+ end
21
+
22
+ def using_base_path(temporary_base_path, &block)
23
+ original_path = dup
24
+ self.base_path = temporary_base_path
25
+ block.call
26
+ ensure
27
+ self.base_path = original_path
28
+ end
29
+
30
+ def dial_plan_named(name)
31
+ File.join(dialplan_path, name)
32
+ end
33
+
34
+ private
35
+ def build_path_for(path)
36
+ File.join(to_s, path)
37
+ end
38
+ end
39
+
40
+ class Initializer
41
+
42
+ class << self
43
+ def get_rules_from(location)
44
+ if File.directory? location
45
+ location = File.join location, ".ahnrc"
46
+ end
47
+ File.exists?(location) ? YAML.load_file(location) : nil
48
+ end
49
+
50
+ def ahn_root=(path)
51
+ if Object.constants.include?("AHN_ROOT")
52
+ Object.const_get(:AHN_ROOT).base_path = File.expand_path(path)
53
+ else
54
+ Object.const_set(:AHN_ROOT, PathString.new(File.expand_path(path)))
55
+ end
56
+ end
57
+
58
+ def start_from_init_file(file, ahn_app_path)
59
+ return if defined?(@@started) && @@started
60
+ new(ahn_app_path, :loaded_init_files => file)
61
+ end
62
+
63
+ end
64
+
65
+ attr_reader :path, :daemon, :pid_file, :log_file, :ahn_app_log_directory
66
+
67
+ DEFAULT_RULES = { :pattern => "*.rb",
68
+ :directory => "helpers"}
69
+
70
+ # Creation of pid_files
71
+ #
72
+ # - You may want to have Adhearsion create a process identification
73
+ # file when it boots so that a crash monitoring program such as
74
+ # Monit can reboot if necessary or so the init script can kill it
75
+ # for system shutdowns.
76
+ # - To have Adhearsion create a pid file in the default location (i.e.
77
+ # AHN_INSTALL_DIR/adhearsion.pid), supply :pid_file with 'true'. Otherwise
78
+ # one is not created UNLESS it is running in daemon mode, in which
79
+ # case one is created. You can force Adhearsion to not create one
80
+ # even in daemon mode by supplying "false".
81
+ def initialize(path=nil, options={})
82
+ @@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]
87
+ self.class.ahn_root = path
88
+ resolve_pid_file_path
89
+ resolve_log_file_path
90
+ switch_to_root_directory
91
+ catch_termination_signal
92
+ bootstrap_rc
93
+ load_all_init_files
94
+ init_modules
95
+ daemonize! if should_daemonize?
96
+ initialize_log_file
97
+ create_pid_file if pid_file
98
+ load_components
99
+
100
+ ahn_log "Adhearsion initialized!"
101
+
102
+ trigger_after_initialized_hooks
103
+ join_framework_threads
104
+ end
105
+
106
+ def initialize_log_file
107
+ Dir.mkdir(ahn_app_log_directory) unless File.directory? ahn_app_log_directory
108
+ file_logger = Log4r::FileOutputter.new("Main Adhearsion log file", :filename => log_file, :trunc => false)
109
+
110
+ if should_daemonize?
111
+ Adhearsion::Logging::AdhearsionLogger.outputters = file_logger
112
+ else
113
+ Adhearsion::Logging::AdhearsionLogger.outputters << file_logger
114
+ end
115
+ Adhearsion::Logging::DefaultAdhearsionLogger.redefine_outputters
116
+ end
117
+
118
+ def resolve_log_file_path
119
+ @ahn_app_log_directory = AHN_ROOT + '/log'
120
+ @log_file = File.expand_path(ahn_app_log_directory + "/adhearsion.log")
121
+ end
122
+
123
+ def create_pid_file(file = pid_file)
124
+ if file
125
+ File.open pid_file, 'w' do |file|
126
+ file.puts Process.pid
127
+ end
128
+
129
+ Hooks::TearDown.create_hook do
130
+ File.delete(pid_file) if File.exists?(pid_file)
131
+ end
132
+ end
133
+ end
134
+
135
+ def init_modules
136
+ require 'adhearsion/initializer/database.rb'
137
+ require 'adhearsion/initializer/asterisk.rb'
138
+ require 'adhearsion/initializer/drb.rb'
139
+ require 'adhearsion/initializer/rails.rb'
140
+ # require 'adhearsion/initializer/freeswitch.rb'
141
+
142
+ DatabaseInitializer.start if AHN_CONFIG.database_enabled?
143
+ AsteriskInitializer.start if AHN_CONFIG.asterisk_enabled?
144
+ DrbInitializer.start if AHN_CONFIG.drb_enabled?
145
+ RailsInitializer.start if AHN_CONFIG.rails_enabled?
146
+ # FreeswitchInitializer.start if AHN_CONFIG.freeswitch_enabled?
147
+ end
148
+
149
+ def resolve_pid_file_path
150
+ @pid_file = if pid_file.equal?(true) then default_pid_path
151
+ elsif pid_file then pid_file
152
+ elsif pid_file.equal?(false) then nil
153
+ # FIXME @pid_file = @daemon? Assignment or equality? I'm assuming equality.
154
+ else @pid_file = @daemon ? default_pid_path : nil
155
+ end
156
+ end
157
+
158
+ def switch_to_root_directory
159
+ Dir.chdir AHN_ROOT
160
+ end
161
+
162
+ def catch_termination_signal
163
+ Hooks::TearDown.catch_termination_signals
164
+ end
165
+
166
+ def load_all_init_files
167
+ if Paths.manager_for? "init"
168
+ init_files_from_rc = all_inits.map { |file| File.expand_path(file) }
169
+ already_loaded_init_files = Array(@loaded_init_files).map { |file| File.expand_path(file) }
170
+ (init_files_from_rc - already_loaded_init_files).each { |init| load init }
171
+ end
172
+ end
173
+
174
+ def should_daemonize?
175
+ @daemon || ENV['DAEMON']
176
+ end
177
+
178
+ def daemonize!
179
+ ahn_log "Daemonizing now! Creating #{pid_file}."
180
+ extend Adhearsion::CustomDaemonizer
181
+ daemonize log_file
182
+ end
183
+
184
+ def load_components
185
+ ComponentManager.load
186
+ ComponentManager.start
187
+ end
188
+
189
+ def trigger_after_initialized_hooks
190
+ Hooks::AfterInitialized.trigger_hooks
191
+ end
192
+
193
+ def join_framework_threads
194
+ Hooks::ThreadsJoinedAfterInitialized.trigger_hooks
195
+ end
196
+
197
+ 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)
204
+ else
205
+ directory, pattern = '.', v
206
+ Paths.manager_for k, :pattern => File.join(directory,pattern)
207
+ end
208
+ end
209
+ end
210
+
211
+ def default_pid_path
212
+ File.join AHN_ROOT, 'adhearsion.pid'
213
+ end
214
+
215
+ class InitializationFailedError < Exception; end
216
+ end
217
+ end
@@ -0,0 +1,92 @@
1
+ require 'log4r'
2
+
3
+ module Adhearsion
4
+ module Logging
5
+
6
+ @@logging_level_lock = Mutex.new
7
+
8
+ class << self
9
+
10
+ def silence!
11
+ self.logging_level = :fatal
12
+ end
13
+
14
+ def unsilence!
15
+ self.logging_level = :info
16
+ end
17
+
18
+ def logging_level=(new_logging_level)
19
+ new_logging_level = Log4r.const_get(new_logging_level.to_s.upcase)
20
+ @@logging_level_lock.synchronize do
21
+ @@logging_level = new_logging_level
22
+ Log4r::Logger.each_logger do |logger|
23
+ logger.level = new_logging_level
24
+ end
25
+ end
26
+ end
27
+
28
+ def logging_level
29
+ @@logging_level_lock.synchronize do
30
+ return @@logging_level ||= Log4r::INFO
31
+ end
32
+ end
33
+ end
34
+
35
+ class AdhearsionLogger < Log4r::Logger
36
+
37
+ @@outputters = [Log4r::Outputter.stdout]
38
+
39
+ class << self
40
+ def outputters
41
+ @@outputters
42
+ end
43
+
44
+ def outputters=(other)
45
+ @@outputters = other
46
+ end
47
+ end
48
+
49
+ def initialize(*args)
50
+ super
51
+ redefine_outputters
52
+ end
53
+
54
+ def redefine_outputters
55
+ self.outputters = @@outputters
56
+ end
57
+
58
+ def method_missing(logger_name, *args, &block)
59
+ define_logging_method(logger_name, self.class.new(logger_name.to_s))
60
+ send(logger_name, *args, &block)
61
+ end
62
+
63
+ private
64
+
65
+ def define_logging_method(name, logger)
66
+ # Can't use Module#define_method() because blocks in Ruby 1.8.x can't
67
+ # have their own block arguments.
68
+ self.class.class_eval(<<-CODE, __FILE__, __LINE__)
69
+ def #{name}(*args, &block)
70
+ logger = Log4r::Logger['#{name}']
71
+ if args.any? || block_given?
72
+ logger.info(*args, &block)
73
+ else
74
+ logger
75
+ end
76
+ end
77
+ CODE
78
+ end
79
+ end
80
+
81
+ DefaultAdhearsionLogger = AdhearsionLogger.new 'ahn'
82
+
83
+ end
84
+ end
85
+
86
+ def ahn_log(*args)
87
+ if args.any?
88
+ Adhearsion::Logging::DefaultAdhearsionLogger.info(*args)
89
+ else
90
+ Adhearsion::Logging::DefaultAdhearsionLogger
91
+ end
92
+ end
@@ -0,0 +1,5 @@
1
+ module Adhearsion
2
+ module Scheduler
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ task:migrate do
2
+ require 'active_record'
3
+ %w.db/migrate db/ahn..each
4
+ ActiveRecord::Migrator.migrate 'db/migrate', ENV['VERSION'] ? ENV['VERSION'].to_i : nil
5
+ end
@@ -0,0 +1,20 @@
1
+ namespace:create do
2
+
3
+ task:war do
4
+ # Hmm, this will is a tough one
5
+ end
6
+
7
+ task:rails_plugin do
8
+
9
+ end
10
+
11
+ task:migration do
12
+ name = ARGV.shift
13
+ end
14
+ end
15
+
16
+ namespace:delete do
17
+ task:migration do
18
+ # Take arg.underscore and remove it
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ task :sanity do
2
+ puts "Performing many checks on your Adhearsion application!"
3
+ # TODO: Anything that should be brought to the user's attention should be placed here!
4
+ end
@@ -0,0 +1,37 @@
1
+ namespace:test do
2
+ desc "Run tests for a component specified by COMPONENT=<component_name>. If no component is specified, tests will be executed for all components"
3
+ task :component do
4
+ component = ENV['COMPONENT']
5
+ components_to_test = component.nil? ? all_component_directories : [full_path_for(component)]
6
+ components_to_test.each do |component_name|
7
+ setup_and_execute(component_name)
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def setup_and_execute(component_path)
14
+ task = create_test_task_for(component_path)
15
+ Rake::Task[task.name].execute
16
+ end
17
+
18
+ def create_test_task_for(component_path)
19
+ Rake::TestTask.new(task_name_for(component_path)) do |t|
20
+ t.libs = ["lib", "test"].map{|subdir| File.join(component_path, subdir)}
21
+ t.test_files = FileList["#{component_path}/test/test_*.rb"]
22
+ t.verbose = true
23
+ end
24
+ end
25
+
26
+ def task_name_for(component_path)
27
+ "test_#{component_path.split(/\//).last}"
28
+ end
29
+
30
+ def all_component_directories
31
+ Dir['components/*']
32
+ end
33
+
34
+ def full_path_for(component)
35
+ component =~ /^components\// ? component : File.join("components", component)
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ require 'rake/testtask'
2
+ require 'adhearsion'
3
+ require 'adhearsion/tasks/database'
4
+ require 'adhearsion/tasks/testing'
5
+ require 'adhearsion/tasks/generating'
6
+ require 'adhearsion/tasks/lint'
7
+
8
+ namespace :adhearsion do
9
+ desc "Dump useful information about this application's adhearsion environment"
10
+ task :about do
11
+ puts "Adhearsion version: #{Adhearsion::VERSION::STRING}"
12
+ end
13
+ end
14
+
15
+ task :default => "adhearsion:about"
@@ -0,0 +1,9 @@
1
+ module Adhearsion #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0 unless defined? MAJOR
4
+ MINOR = 7 unless defined? MINOR
5
+ TINY = 999 unless defined? TINY
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.') unless defined? STRING
8
+ end
9
+ end
@@ -0,0 +1,78 @@
1
+ require 'gserver'
2
+ module Adhearsion
3
+ module VoIP
4
+ module Asterisk
5
+ module AGI
6
+ class Server
7
+
8
+ class RubyServer < GServer
9
+
10
+ def initialize(port, host)
11
+ super(port, host, (1.0/0.0)) # (1.0/0.0) == Infinity
12
+ end
13
+
14
+ def serve(io)
15
+ Hooks::BeforeCall.trigger_hooks
16
+ call = Adhearsion.receive_call_from(io)
17
+ ahn_log.agi "Handling call with variables #{call.variables.inspect}"
18
+
19
+ return DialPlan::ConfirmationManager.handle(call) if DialPlan::ConfirmationManager.confirmation_call?(call)
20
+
21
+ # This is what happens 99.9% of the time.
22
+
23
+ DialPlan::Manager.handle call
24
+ rescue DialPlan::Manager::NoContextError => e
25
+ ahn_log.agi e.message
26
+ call.hangup!
27
+ rescue FailedExtensionCallException => failed_call
28
+ begin
29
+ ahn_log.agi "Received \"failed\" meta-call with :failed_reason => #{failed_call.call.failed_reason.inspect}. Executing OnFailedCall hooks."
30
+ Hooks::OnFailedCall.trigger_hooks(failed_call.call)
31
+ call.hangup!
32
+ rescue => e
33
+ ahn_log.agi.error e
34
+ end
35
+ rescue HungupExtensionCallException => hungup_call
36
+ begin
37
+ ahn_log.agi "Received \"h\" meta-call. Executing OnHungupCall hooks."
38
+ Hooks::OnHungupCall.trigger_hooks(hungup_call.call)
39
+ call.hangup!
40
+ rescue => e
41
+ ahn_log.agi.error e
42
+ end
43
+ rescue UselessCallException
44
+ ahn_log.agi "Ignoring meta-AGI request"
45
+ call.hangup!
46
+ # TBD: (may have more hooks than what Jay has defined in hooks.rb)
47
+ rescue => e
48
+ ahn_log.agi.error e.inspect
49
+ ahn_log.agi.error e.backtrace.map { |s| " " * 5 + s }.join("\n")
50
+ end
51
+ end
52
+
53
+ DEFAULT_OPTIONS = { :server_class => RubyServer, :port => 4573, :host => "0.0.0.0" } unless defined? DEFAULT_OPTIONS
54
+ attr_reader :host, :port, :server_class, :server
55
+
56
+ def initialize(options = {})
57
+ options = DEFAULT_OPTIONS.merge options
58
+ @host, @port, @server_class = options.values_at(:host, :port, :server_class)
59
+ @server = server_class.new(port, host)
60
+ end
61
+
62
+ def start
63
+ server.start
64
+ end
65
+
66
+ def shutdown
67
+ server.stop
68
+ end
69
+
70
+ def join
71
+ server.join
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end