adhearsion 1.2.6 → 2.0.0.alpha1

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 (236) hide show
  1. data/.gitignore +17 -10
  2. data/CHANGELOG.md +273 -0
  3. data/Gemfile +1 -1
  4. data/Guardfile +17 -0
  5. data/README.markdown +61 -9
  6. data/Rakefile +16 -48
  7. data/adhearsion.gemspec +21 -7
  8. data/bin/ahn +3 -1
  9. data/cucumber.yml +4 -0
  10. data/features/app_generator.feature +42 -0
  11. data/features/cli.feature +108 -0
  12. data/features/step_definitions/app_generator_steps.rb +6 -0
  13. data/features/step_definitions/cli_steps.rb +74 -0
  14. data/features/support/aruba_helper.rb +22 -0
  15. data/features/support/env.rb +37 -0
  16. data/features/support/utils.rb +8 -0
  17. data/lib/adhearsion.rb +85 -41
  18. data/lib/adhearsion/call.rb +176 -0
  19. data/lib/adhearsion/call_controller.rb +134 -0
  20. data/lib/adhearsion/call_controller/dial.rb +70 -0
  21. data/lib/adhearsion/call_controller/input.rb +173 -0
  22. data/lib/adhearsion/call_controller/menu.rb +124 -0
  23. data/lib/adhearsion/call_controller/output.rb +267 -0
  24. data/lib/adhearsion/call_controller/record.rb +42 -0
  25. data/lib/adhearsion/call_controller/utility.rb +60 -0
  26. data/lib/adhearsion/calls.rb +81 -0
  27. data/lib/adhearsion/cli.rb +1 -3
  28. data/lib/adhearsion/cli_commands.rb +142 -0
  29. data/lib/adhearsion/configuration.rb +149 -0
  30. data/lib/adhearsion/console.rb +19 -8
  31. data/lib/adhearsion/dialplan_controller.rb +9 -0
  32. data/lib/adhearsion/events.rb +84 -0
  33. data/lib/adhearsion/foundation/all.rb +0 -7
  34. data/lib/adhearsion/foundation/custom_daemonizer.rb +4 -6
  35. data/lib/adhearsion/foundation/exception_handler.rb +9 -0
  36. data/lib/adhearsion/foundation/object.rb +26 -8
  37. data/lib/adhearsion/foundation/synchronized_hash.rb +3 -6
  38. data/lib/adhearsion/foundation/thread_safety.rb +17 -1
  39. data/lib/adhearsion/generators/app/app_generator.rb +4 -13
  40. data/lib/adhearsion/generators/app/templates/Gemfile +10 -5
  41. data/lib/adhearsion/generators/app/templates/Procfile +1 -0
  42. data/lib/adhearsion/generators/app/templates/README.md +28 -0
  43. data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +41 -0
  44. data/lib/adhearsion/generators/app/templates/{components/simon_game → lib}/simon_game.rb +6 -18
  45. data/lib/adhearsion/generators/app/templates/script/ahn +2 -2
  46. data/lib/adhearsion/initializer.rb +151 -293
  47. data/lib/adhearsion/initializer/logging.rb +33 -0
  48. data/lib/adhearsion/logging.rb +65 -69
  49. data/lib/adhearsion/menu_dsl.rb +15 -0
  50. data/lib/adhearsion/menu_dsl/calculated_match.rb +39 -0
  51. data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +41 -0
  52. data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +18 -0
  53. data/lib/adhearsion/menu_dsl/match_calculator.rb +36 -0
  54. data/lib/adhearsion/{voip/menu_state_machine/menu_class.rb → menu_dsl/menu.rb} +38 -40
  55. data/lib/adhearsion/menu_dsl/menu_builder.rb +69 -0
  56. data/lib/adhearsion/menu_dsl/range_match_calculator.rb +55 -0
  57. data/lib/adhearsion/menu_dsl/string_match_calculator.rb +21 -0
  58. data/lib/adhearsion/outbound_call.rb +64 -0
  59. data/lib/adhearsion/plugin.rb +319 -0
  60. data/lib/adhearsion/plugin/collection.rb +19 -0
  61. data/lib/adhearsion/plugin/initializer.rb +37 -0
  62. data/lib/adhearsion/plugin/methods_container.rb +6 -0
  63. data/lib/adhearsion/process.rb +94 -0
  64. data/lib/adhearsion/punchblock_plugin.rb +29 -0
  65. data/lib/adhearsion/punchblock_plugin/initializer.rb +137 -0
  66. data/lib/adhearsion/router.rb +30 -0
  67. data/lib/adhearsion/router/route.rb +42 -0
  68. data/lib/adhearsion/script_ahn_loader.rb +2 -2
  69. data/lib/adhearsion/tasks.rb +14 -9
  70. data/lib/adhearsion/tasks/configuration.rb +26 -0
  71. data/lib/adhearsion/tasks/plugins.rb +17 -0
  72. data/lib/adhearsion/version.rb +8 -14
  73. data/spec/adhearsion/call_controller/dial_spec.rb +138 -0
  74. data/spec/adhearsion/call_controller/input_spec.rb +278 -0
  75. data/spec/adhearsion/call_controller/menu_spec.rb +120 -0
  76. data/spec/adhearsion/call_controller/output_spec.rb +466 -0
  77. data/spec/adhearsion/call_controller/record_spec.rb +125 -0
  78. data/spec/adhearsion/call_controller_spec.rb +395 -0
  79. data/spec/adhearsion/call_spec.rb +438 -0
  80. data/spec/adhearsion/calls_spec.rb +47 -0
  81. data/spec/adhearsion/configuration_spec.rb +308 -0
  82. data/spec/adhearsion/dialplan_controller_spec.rb +26 -0
  83. data/spec/adhearsion/events_spec.rb +112 -0
  84. data/spec/adhearsion/initializer/logging_spec.rb +58 -0
  85. data/spec/adhearsion/initializer_spec.rb +209 -122
  86. data/spec/adhearsion/logging_spec.rb +58 -47
  87. data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +56 -0
  88. data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +57 -0
  89. data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +33 -0
  90. data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +13 -0
  91. data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +118 -0
  92. data/spec/adhearsion/menu_dsl/menu_spec.rb +210 -0
  93. data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +28 -0
  94. data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +36 -0
  95. data/spec/adhearsion/menu_dsl_spec.rb +12 -0
  96. data/spec/adhearsion/outbound_call_spec.rb +174 -0
  97. data/spec/adhearsion/plugin_spec.rb +489 -0
  98. data/spec/adhearsion/process_spec.rb +34 -0
  99. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +294 -0
  100. data/spec/adhearsion/router/route_spec.rb +99 -0
  101. data/spec/adhearsion/router_spec.rb +106 -0
  102. data/spec/adhearsion_spec.rb +46 -0
  103. data/spec/spec_helper.rb +14 -14
  104. data/spec/support/call_controller_test_helpers.rb +48 -0
  105. data/spec/support/initializer_stubs.rb +8 -13
  106. data/spec/support/punchblock_mocks.rb +6 -0
  107. metadata +255 -253
  108. data/CHANGELOG +0 -174
  109. data/bin/ahnctl +0 -68
  110. data/bin/jahn +0 -43
  111. data/examples/asterisk_manager_interface/standalone.rb +0 -51
  112. data/lib/adhearsion/commands.rb +0 -302
  113. data/lib/adhearsion/component_manager.rb +0 -278
  114. data/lib/adhearsion/component_manager/component_tester.rb +0 -54
  115. data/lib/adhearsion/component_manager/spec_framework.rb +0 -18
  116. data/lib/adhearsion/events_support.rb +0 -65
  117. data/lib/adhearsion/foundation/blank_slate.rb +0 -3
  118. data/lib/adhearsion/foundation/event_socket.rb +0 -205
  119. data/lib/adhearsion/foundation/future_resource.rb +0 -36
  120. data/lib/adhearsion/foundation/metaprogramming.rb +0 -17
  121. data/lib/adhearsion/foundation/numeric.rb +0 -13
  122. data/lib/adhearsion/foundation/pseudo_guid.rb +0 -10
  123. data/lib/adhearsion/foundation/relationship_properties.rb +0 -42
  124. data/lib/adhearsion/foundation/string.rb +0 -26
  125. data/lib/adhearsion/generators/app/templates/.ahnrc +0 -34
  126. data/lib/adhearsion/generators/app/templates/README +0 -8
  127. data/lib/adhearsion/generators/app/templates/components/ami_remote/ami_remote.rb +0 -15
  128. data/lib/adhearsion/generators/app/templates/components/disabled/HOW_TO_ENABLE +0 -7
  129. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/README.markdown +0 -47
  130. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.rb +0 -34
  131. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.yml +0 -12
  132. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/README.markdown +0 -3
  133. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +0 -11
  134. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
  135. data/lib/adhearsion/generators/app/templates/config/startup.rb +0 -81
  136. data/lib/adhearsion/generators/app/templates/dialplan.rb +0 -3
  137. data/lib/adhearsion/generators/app/templates/events.rb +0 -33
  138. data/lib/adhearsion/host_definitions.rb +0 -67
  139. data/lib/adhearsion/initializer/asterisk.rb +0 -86
  140. data/lib/adhearsion/initializer/configuration.rb +0 -324
  141. data/lib/adhearsion/initializer/database.rb +0 -60
  142. data/lib/adhearsion/initializer/drb.rb +0 -31
  143. data/lib/adhearsion/initializer/freeswitch.rb +0 -22
  144. data/lib/adhearsion/initializer/ldap.rb +0 -57
  145. data/lib/adhearsion/initializer/rails.rb +0 -41
  146. data/lib/adhearsion/initializer/xmpp.rb +0 -42
  147. data/lib/adhearsion/tasks/components.rb +0 -32
  148. data/lib/adhearsion/tasks/database.rb +0 -5
  149. data/lib/adhearsion/tasks/deprecations.rb +0 -59
  150. data/lib/adhearsion/tasks/generating.rb +0 -20
  151. data/lib/adhearsion/tasks/lint.rb +0 -4
  152. data/lib/adhearsion/voip/asterisk.rb +0 -4
  153. data/lib/adhearsion/voip/asterisk/agi_server.rb +0 -121
  154. data/lib/adhearsion/voip/asterisk/commands.rb +0 -1966
  155. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +0 -140
  156. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +0 -102
  157. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +0 -250
  158. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +0 -240
  159. data/lib/adhearsion/voip/asterisk/config_manager.rb +0 -64
  160. data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -697
  161. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +0 -1681
  162. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +0 -341
  163. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +0 -78
  164. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +0 -87
  165. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +0 -80
  166. data/lib/adhearsion/voip/call.rb +0 -521
  167. data/lib/adhearsion/voip/call_routing.rb +0 -64
  168. data/lib/adhearsion/voip/commands.rb +0 -17
  169. data/lib/adhearsion/voip/constants.rb +0 -39
  170. data/lib/adhearsion/voip/conveniences.rb +0 -18
  171. data/lib/adhearsion/voip/dial_plan.rb +0 -252
  172. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +0 -151
  173. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +0 -37
  174. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +0 -27
  175. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +0 -124
  176. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +0 -69
  177. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +0 -16
  178. data/lib/adhearsion/voip/dsl/numerical_string.rb +0 -128
  179. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +0 -48
  180. data/lib/adhearsion/voip/freeswitch/event_handler.rb +0 -58
  181. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +0 -129
  182. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +0 -38
  183. data/lib/adhearsion/voip/freeswitch/oes_server.rb +0 -195
  184. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +0 -80
  185. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +0 -123
  186. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +0 -57
  187. data/lib/adhearsion/xmpp/connection.rb +0 -61
  188. data/lib/theatre.rb +0 -147
  189. data/lib/theatre/README.markdown +0 -64
  190. data/lib/theatre/callback_definition_loader.rb +0 -86
  191. data/lib/theatre/guid.rb +0 -23
  192. data/lib/theatre/invocation.rb +0 -131
  193. data/lib/theatre/namespace_manager.rb +0 -153
  194. data/lib/theatre/version.rb +0 -2
  195. data/spec/adhearsion/cli_spec.rb +0 -306
  196. data/spec/adhearsion/component_manager_spec.rb +0 -292
  197. data/spec/adhearsion/constants_spec.rb +0 -8
  198. data/spec/adhearsion/drb_spec.rb +0 -65
  199. data/spec/adhearsion/fixtures/dialplan.rb +0 -3
  200. data/spec/adhearsion/foundation/event_socket_spec.rb +0 -168
  201. data/spec/adhearsion/host_definitions_spec.rb +0 -79
  202. data/spec/adhearsion/initializer/configuration_spec.rb +0 -291
  203. data/spec/adhearsion/initializer/loading_spec.rb +0 -154
  204. data/spec/adhearsion/initializer/paths_spec.rb +0 -74
  205. data/spec/adhearsion/relationship_properties_spec.rb +0 -54
  206. data/spec/adhearsion/voip/asterisk/agi_server_spec.rb +0 -473
  207. data/spec/adhearsion/voip/asterisk/ami/ami_spec.rb +0 -550
  208. data/spec/adhearsion/voip/asterisk/ami/lexer/ami_fixtures.yml +0 -30
  209. data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story +0 -291
  210. data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story.rb +0 -241
  211. data/spec/adhearsion/voip/asterisk/ami/lexer/story_helper.rb +0 -124
  212. data/spec/adhearsion/voip/asterisk/commands_spec.rb +0 -3241
  213. data/spec/adhearsion/voip/asterisk/config_file_generators/agents_spec.rb +0 -251
  214. data/spec/adhearsion/voip/asterisk/config_file_generators/queues_spec.rb +0 -323
  215. data/spec/adhearsion/voip/asterisk/config_file_generators/voicemail_spec.rb +0 -306
  216. data/spec/adhearsion/voip/asterisk/config_manager_spec.rb +0 -127
  217. data/spec/adhearsion/voip/asterisk/menu_command/calculated_match_spec.rb +0 -109
  218. data/spec/adhearsion/voip/asterisk/menu_command/matchers_spec.rb +0 -97
  219. data/spec/adhearsion/voip/call_routing_spec.rb +0 -125
  220. data/spec/adhearsion/voip/dialplan_manager_spec.rb +0 -468
  221. data/spec/adhearsion/voip/dsl/dialing_dsl_spec.rb +0 -270
  222. data/spec/adhearsion/voip/dsl/dispatcher_spec.rb +0 -82
  223. data/spec/adhearsion/voip/dsl/dispatcher_spec_helper.rb +0 -45
  224. data/spec/adhearsion/voip/dsl/parser_spec.rb +0 -69
  225. data/spec/adhearsion/voip/freeswitch/basic_connection_manager_spec.rb +0 -39
  226. data/spec/adhearsion/voip/freeswitch/inbound_connection_manager_spec.rb +0 -39
  227. data/spec/adhearsion/voip/freeswitch/oes_server_spec.rb +0 -9
  228. data/spec/adhearsion/voip/numerical_string_spec.rb +0 -61
  229. data/spec/adhearsion/voip/phone_number_spec.rb +0 -45
  230. data/spec/support/the_following_code.rb +0 -3
  231. data/spec/theatre/dsl_examples/simple_before_call.rb +0 -7
  232. data/spec/theatre/dsl_spec.rb +0 -69
  233. data/spec/theatre/invocation_spec.rb +0 -182
  234. data/spec/theatre/namespace_spec.rb +0 -125
  235. data/spec/theatre/spec_helper_spec.rb +0 -28
  236. data/spec/theatre/theatre_class_spec.rb +0 -148
@@ -0,0 +1,81 @@
1
+ require 'thread'
2
+
3
+ module Adhearsion
4
+ ##
5
+ # This manages the list of calls the Adhearsion service receives
6
+ class Calls
7
+ attr_reader :semaphore, :calls
8
+
9
+ def initialize
10
+ @semaphore = Monitor.new
11
+ @calls = {}
12
+ end
13
+
14
+ def from_offer(offer)
15
+ Call.new(offer).tap do |call|
16
+ self << call
17
+ end
18
+ end
19
+
20
+ def <<(call)
21
+ atomically { calls[call.id] = call }
22
+ end
23
+
24
+ def any?
25
+ atomically { !calls.empty? }
26
+ end
27
+
28
+ def size
29
+ atomically { calls.size }
30
+ end
31
+
32
+ def remove_inactive_call(call)
33
+ atomically { calls.delete call.id }
34
+ end
35
+
36
+ # Searches all active calls by their id
37
+ def find(id)
38
+ atomically { calls[id] }
39
+ end
40
+ alias :[] :find
41
+
42
+ def clear!
43
+ atomically { calls.clear }
44
+ end
45
+
46
+ def with_tag(tag)
47
+ atomically do
48
+ calls.inject([]) do |calls_with_tag,(key,call)|
49
+ call.tagged_with?(tag) ? calls_with_tag << call : calls_with_tag
50
+ end
51
+ end
52
+ end
53
+
54
+ def each(&block)
55
+ atomically { calls.values.each &block }
56
+ end
57
+
58
+ def each_pair
59
+ calls.each_pair { |id, call| yield id, call }
60
+ end
61
+
62
+ def to_a
63
+ calls.values
64
+ end
65
+
66
+ def to_h
67
+ calls
68
+ end
69
+
70
+ def method_missing(m, *args)
71
+ atomically { calls.send m.to_sym, *args }
72
+ end
73
+
74
+ private
75
+
76
+ def atomically(&block)
77
+ semaphore.synchronize(&block)
78
+ end
79
+
80
+ end
81
+ end
@@ -4,6 +4,4 @@ require 'adhearsion/script_ahn_loader'
4
4
  # the rest of this script is not run.
5
5
  Adhearsion::ScriptAhnLoader.exec_script_ahn!
6
6
 
7
- require 'bundler/setup'
8
- require 'adhearsion'
9
- require 'adhearsion/commands'
7
+ require 'adhearsion/cli_commands'
@@ -0,0 +1,142 @@
1
+ require 'fileutils'
2
+ require 'adhearsion/script_ahn_loader'
3
+ require 'thor'
4
+
5
+ module Adhearsion
6
+ module CLI
7
+ class AhnCommand < Thor
8
+ map %w(-h --h -help --help) => :help
9
+ map %w(-v --v -version --version) => :version
10
+ map %w(-) => :start
11
+
12
+ check_unknown_options!
13
+
14
+ def self.exit_on_failure?
15
+ true
16
+ end
17
+
18
+ desc "create /path/to/directory", "Create a new Adhearsion application under the given path"
19
+ def create(path)
20
+ require 'adhearsion/generators'
21
+ require 'adhearsion/generators/app/app_generator'
22
+ Adhearsion::Generators::AppGenerator.start
23
+ end
24
+
25
+ desc "version", "Shows Adhearsion version"
26
+ def version
27
+ say "Adhearsion v#{Adhearsion::VERSION}"
28
+ exit 0
29
+ end
30
+
31
+ desc "start </path/to/directory>", "Start the Adhearsion server in the foreground with a console"
32
+ def start(path = nil)
33
+ start_app path, :console
34
+ end
35
+
36
+ desc "daemon </path/to/directory>", "Start the Adhearsion server in the background"
37
+ method_option :pidfile, :type => :string, :aliases => %w(--pid-file)
38
+ def daemon(path = nil)
39
+ start_app path, :daemon, options[:pidfile]
40
+ end
41
+
42
+ desc "stop </path/to/directory>", "Stop a running Adhearsion server"
43
+ method_option :pidfile, :type => :string, :aliases => %w(--pid-file)
44
+ def stop(path = nil)
45
+ execute_from_app_dir! path, ARGV
46
+
47
+ pid_file = if options[:pidfile]
48
+ File.expand_path File.exists?(File.expand_path(options[:pidfile])) ?
49
+ options[:pidfile] :
50
+ File.join(path, options[:pidfile])
51
+ else
52
+ path + '/adhearsion.pid'
53
+ end
54
+
55
+ begin
56
+ pid = File.read(pid_file).to_i
57
+ rescue
58
+ raise CLIException, "Could not read pid file #{pid_file}"
59
+ end
60
+
61
+ raise CLIException, "Could not read pid" if pid.nil?
62
+
63
+ say "Stopping Adhearsion server at #{path} with pid #{pid}"
64
+ waiting_timeout = Time.now + 15
65
+ begin
66
+ ::Process.kill "TERM", pid
67
+ sleep 0.25 while process_exists?(pid) && Time.now < waiting_timeout
68
+ ::Process.kill "KILL", pid
69
+ rescue Errno::ESRCH
70
+ end
71
+ end
72
+
73
+ desc "restart </path/to/directory>", "Restart the Adhearsion server"
74
+ method_option :pidfile, :type => :string, :aliases => %w(--pid-file)
75
+ def restart(path = nil)
76
+ execute_from_app_dir! path, ARGV
77
+ invoke :stop
78
+ invoke :daemon
79
+ end
80
+
81
+ protected
82
+
83
+ def start_app(path, mode, pid_file = nil)
84
+ execute_from_app_dir! path, ARGV
85
+ say "Starting Adhearsion server at #{path}"
86
+ Adhearsion::Initializer.start :mode => mode, :pid_file => pid_file
87
+ end
88
+
89
+ def execute_from_app_dir!(path, *args)
90
+ return if in_app? and running_script_ahn?
91
+
92
+ path ||= '.' if in_app?
93
+
94
+ raise PathRequired, ARGV[0] if path.nil? or path.empty?
95
+ raise PathInvalid, path unless ScriptAhnLoader.in_ahn_application?(path)
96
+
97
+ Dir.chdir path do
98
+ args.flatten!
99
+ args[1] = '.'
100
+ ScriptAhnLoader.exec_script_ahn! args
101
+ end
102
+ end
103
+
104
+ def running_script_ahn?
105
+ $0.to_s == "script/ahn"
106
+ end
107
+
108
+ def in_app?
109
+ ScriptAhnLoader.in_ahn_application? or ScriptAhnLoader.in_ahn_application_subdirectory?
110
+ end
111
+
112
+ def process_exists?(pid = nil)
113
+ # FIXME: Raise some error here
114
+ return false if pid.nil?
115
+ `ps -p #{pid} | sed -e '1d'`.strip.empty?
116
+ end
117
+
118
+ def method_missing(action, *args)
119
+ help
120
+ raise UnknownCommand, [action, *args] * " "
121
+ end
122
+ end # AhnCommand
123
+
124
+ class UnknownCommand < Thor::Error
125
+ def initialize(cmd)
126
+ super "Unknown command: #{cmd}"
127
+ end
128
+ end
129
+
130
+ class PathRequired < Thor::Error
131
+ def initialize(cmd)
132
+ super "A valid path is required for #{cmd}, unless run from an Adhearson app directory"
133
+ end
134
+ end
135
+
136
+ class PathInvalid < Thor::Error
137
+ def initialize(path)
138
+ super "Directory #{path} does not belong to an Adhearsion project!"
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,149 @@
1
+ module Adhearsion
2
+
3
+ class Configuration
4
+
5
+ ##
6
+ # Initialize the configuration object
7
+ #
8
+ # * &block platform configuration block
9
+ # Adhearsion::Configuration.new do
10
+ # foo "bar", :desc => "My description"
11
+ # end
12
+ #
13
+ # @return [Adhearsion::Configuration]
14
+ def initialize(&block)
15
+ initialize_environments
16
+
17
+ Loquacious::Configuration.for :platform do
18
+ root nil, :desc => "Adhearsion application root folder"
19
+ lib "lib", :desc => <<-__
20
+ Folder to include the own libraries to be used. Adhearsion loads any ruby file located into this folder during the bootstrap
21
+ process. Set to nil if you do not want these files to be loaded. This folder is relative to the application root folder.
22
+ __
23
+ automatically_accept_incoming_calls true, :desc => "Adhearsion will accept automatically any inbound call"
24
+
25
+ environment :development, :desc => "Active environment. Supported values: development, production, staging, test"
26
+
27
+ desc "Log configuration"
28
+ logging {
29
+ level :info, :desc => <<-__
30
+ Supported levels (in increasing severity) -- :trace < :debug < :info < :warn < :error < :fatal
31
+ __
32
+ outputters ["log/adhearsion.log"], :desc => <<-__
33
+ An array of log outputters to use. The default is to log to stdout and log/adhearsion.log
34
+ __
35
+ formatter nil, :desc => <<-__
36
+ A log formatter to apply to all active outputters. If nil, the Adhearsion default formatter will be used.
37
+ __
38
+ }
39
+ end
40
+
41
+ Loquacious::Configuration.for :platform, &block if block_given?
42
+
43
+ self
44
+ end
45
+
46
+ def initialize_environments
47
+ # Create a method per each valid environment that, when invoked, may execute
48
+ # the block received if the environment is active
49
+ valid_environments.each do |enviro|
50
+ add_environment enviro
51
+ end
52
+ end
53
+
54
+ def valid_environment?(env)
55
+ env && self.valid_environments.include?(env.to_sym)
56
+ end
57
+
58
+ def valid_environments
59
+ @valid_environments ||= [:production, :development, :staging, :test]
60
+ end
61
+
62
+ def add_environment(env)
63
+ self.class.send(:define_method, env.to_sym) do |*args, &block|
64
+ unless block.nil? || env != self.platform.environment.to_sym
65
+ self.instance_eval &block
66
+ end
67
+ self
68
+ end
69
+ end
70
+
71
+ ##
72
+ # Direct access to a specific configuration object
73
+ #
74
+ # Adhearsion.config[:platform] => returns the configuration object associated to the Adhearsion platform
75
+ #
76
+ # @return [Loquacious::Configuration] configuration object or nil if the plugin does not exist
77
+ def [](value)
78
+ self.send value.to_sym
79
+ end
80
+
81
+ ##
82
+ # Wrapper to access to a specific configuration object
83
+ #
84
+ # Adhearsion.config.foo => returns the configuration object associated to the foo plugin
85
+ def method_missing(method_name, *args, &block)
86
+ config = Loquacious::Configuration.for method_name, &block
87
+ raise Adhearsion::ConfigurationError.new "Invalid plugin #{method_name}" if config.nil?
88
+ config
89
+ end
90
+
91
+ # root accessor
92
+ def root
93
+ platform.root
94
+ end
95
+
96
+ ##
97
+ # Handle the Adhearsion platform configuration
98
+ #
99
+ # It accepts a block that will be executed in the Adhearsion config var environment
100
+ # to update the desired values
101
+ #
102
+ # Adhearsion.config.platform do
103
+ # foo "bar", :desc => "My new description"
104
+ # end
105
+ #
106
+ # values = Adhearsion.config.platform
107
+ # values.foo => "bar"
108
+ #
109
+ # @return [Loquacious::Configuration] configuration object or nil if the plugin does not exist
110
+ def platform(&block)
111
+ Loquacious::Configuration.for :platform, &block
112
+ end
113
+
114
+ ##
115
+ # Fetchs the configuration info for the Adhearsion platform or a specific plugin
116
+ # @param name [Symbol]
117
+ # - :all => Adhearsion platform and all the loaded plugins
118
+ # - nil => Adhearsion platform configuration
119
+ # - :platform => Adhearsion platform configuration
120
+ # - :<plugin-config-name> => Adhearsion plugin configuration
121
+ #
122
+ # @param args [Hash]
123
+ # - @option :show_values [Boolean] true | false to return the current values or just the description
124
+ #
125
+ # @return string with the configuration description/values
126
+ def description(name, args = {:show_values => true})
127
+ desc = StringIO.new
128
+
129
+ name.nil? and name = :platform
130
+ if name.eql? :all
131
+ value = ""
132
+ Loquacious::Configuration.instance_variable_get("@table").keys.map do |config|
133
+ value.concat description config, args
134
+ end
135
+ return value
136
+ else
137
+ return "" if Loquacious::Configuration.for(name).nil?
138
+
139
+ config = Loquacious::Configuration.help_for name,
140
+ :name_leader => "",
141
+ :desc_leader => "# ",
142
+ :colorize => true,
143
+ :io => desc
144
+ config.show :values => args[:show_values]
145
+ "\n# ******* Configuration for #{name} **************\n\n#{desc.string}"
146
+ end
147
+ end
148
+ end
149
+ end
@@ -20,11 +20,12 @@ module Adhearsion
20
20
  end
21
21
  ]
22
22
  Pry.config.command_prefix = "%"
23
- pry
24
- end
25
-
26
- def logger
27
- Adhearsion::Logging
23
+ if libedit?
24
+ logger.error "Cannot start. You are running Adhearsion on Ruby with libedit. You must use readline for the console to work."
25
+ else
26
+ logger.info "Starting up..."
27
+ pry
28
+ end
28
29
  end
29
30
 
30
31
  def calls
@@ -36,14 +37,24 @@ module Adhearsion
36
37
  raise ArgumentError unless Adhearsion.active_calls[call]
37
38
  call = Adhearsion.active_calls[call]
38
39
  end
39
- Pry.prompt = [ proc { "AHN<#{call.channel}> "},
40
- proc { "AHN<#{call.channel}? "} ]
40
+ Pry.prompt = [ proc { "AHN<#{call.channel}> " },
41
+ proc { "AHN<#{call.channel}? " } ]
41
42
 
42
43
  # Pause execution of the thread currently controlling the call
43
44
  call.with_command_lock do
44
45
  CallWrapper.new(call).pry
45
46
  end
46
47
  end
48
+
49
+ def libedit?
50
+ begin
51
+ # If NotImplemented then this might be libedit
52
+ Readline.emacs_editing_mode
53
+ false
54
+ rescue NotImplementedError
55
+ true
56
+ end
57
+ end
47
58
  end
48
59
 
49
60
  class CallWrapper
@@ -51,7 +62,7 @@ module Adhearsion
51
62
 
52
63
  def initialize(call)
53
64
  @call = call
54
- extend Adhearsion::VoIP::Commands.for('asterisk')
65
+ extend Adhearsion::Commands.for('asterisk')
55
66
  end
56
67
  end
57
68
  end
@@ -0,0 +1,9 @@
1
+ module Adhearsion
2
+ class DialplanController < CallController
3
+ attr_accessor :dialplan
4
+
5
+ def run
6
+ instance_exec &dialplan
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,84 @@
1
+ module Adhearsion
2
+ class Events
3
+
4
+ include HasGuardedHandlers
5
+
6
+ Message = Struct.new :type, :object
7
+
8
+ class << self
9
+ def method_missing(method_name, *args, &block)
10
+ instance.send method_name, *args, &block
11
+ end
12
+
13
+ def respond_to?(method_name)
14
+ instance.respond_to?(method_name) || super
15
+ end
16
+
17
+ def instance
18
+ @@instance || refresh!
19
+ end
20
+
21
+ def refresh!
22
+ @@instance = new
23
+ end
24
+ end
25
+
26
+ refresh!
27
+
28
+ def queue
29
+ @queue || reinitialize_queue!
30
+ end
31
+
32
+ def trigger(type, object = nil)
33
+ queue.push_async Message.new(type, object)
34
+ end
35
+
36
+ def trigger_immediately(type, object = nil)
37
+ queue.push_immediately Message.new(type, object)
38
+ end
39
+
40
+ def reinitialize_queue!
41
+ GirlFriday.shutdown! if @queue
42
+ # TODO: Extract number of threads to use from Adhearsion.config
43
+ @queue = GirlFriday::WorkQueue.new 'main_queue', :error_handler => ErrorHandler do |message|
44
+ begin
45
+ handle_message message
46
+ rescue Exception => e
47
+ ErrorHandler.new.handle e
48
+ end
49
+ end
50
+ end
51
+
52
+ def handle_message(message)
53
+ trigger_handler message.type, message.object
54
+ end
55
+
56
+ def draw(&block)
57
+ instance_exec &block
58
+ end
59
+
60
+ def method_missing(method_name, *args, &block)
61
+ register_handler method_name, *args, &block
62
+ end
63
+
64
+ def respond_to?(method_name)
65
+ return true if @handlers && @handlers.has_key?(method_name)
66
+ super
67
+ end
68
+
69
+ alias :register_callback :register_handler
70
+
71
+ private
72
+
73
+ def call_handler(handler, guards, event)
74
+ super && throw(:pass)
75
+ end
76
+
77
+ class ErrorHandler
78
+ def handle(exception)
79
+ Events.trigger :exception, exception
80
+ end
81
+ end
82
+
83
+ end
84
+ end