eric-adhearsion 0.7.999 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/CHANGELOG +8 -2
  2. data/EVENTS +11 -0
  3. data/Rakefile +96 -24
  4. data/adhearsion.gemspec +148 -0
  5. data/app_generators/ahn/ahn_generator.rb +24 -9
  6. data/app_generators/ahn/templates/.ahnrc +25 -3
  7. data/app_generators/ahn/templates/Rakefile +22 -2
  8. data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +15 -0
  9. data/app_generators/ahn/templates/components/disabled/HOW_TO_ENABLE +7 -0
  10. data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +47 -0
  11. data/app_generators/ahn/templates/components/disabled/stomp_gateway/config.yml +12 -0
  12. data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +34 -0
  13. data/app_generators/ahn/templates/components/simon_game/{lib/simon_game.rb → simon_game.rb} +14 -19
  14. data/app_generators/ahn/templates/config/startup.rb +3 -6
  15. data/app_generators/ahn/templates/dialplan.rb +2 -3
  16. data/app_generators/ahn/templates/events.rb +32 -0
  17. data/bin/jahn +10 -0
  18. data/examples/asterisk_manager_interface/standalone.rb +51 -0
  19. data/lib/adhearsion.rb +17 -11
  20. data/lib/adhearsion/cli.rb +141 -24
  21. data/lib/adhearsion/component_manager.rb +169 -238
  22. data/lib/adhearsion/component_manager/component_tester.rb +55 -0
  23. data/lib/adhearsion/component_manager/spec_framework.rb +24 -0
  24. data/lib/adhearsion/events_support.rb +84 -0
  25. data/lib/adhearsion/{core_extensions → foundation}/all.rb +0 -0
  26. data/lib/adhearsion/{blank_slate.rb → foundation/blank_slate.rb} +0 -0
  27. data/lib/adhearsion/{core_extensions → foundation}/custom_daemonizer.rb +0 -0
  28. data/lib/adhearsion/foundation/event_socket.rb +203 -0
  29. data/lib/adhearsion/foundation/future_resource.rb +36 -0
  30. data/lib/adhearsion/{core_extensions → foundation}/global.rb +0 -0
  31. data/lib/adhearsion/{core_extensions → foundation}/metaprogramming.rb +0 -0
  32. data/lib/adhearsion/foundation/numeric.rb +13 -0
  33. data/lib/adhearsion/foundation/pseudo_guid.rb +10 -0
  34. data/lib/adhearsion/{core_extensions → foundation}/relationship_properties.rb +2 -0
  35. data/lib/adhearsion/foundation/string.rb +26 -0
  36. data/lib/adhearsion/foundation/synchronized_hash.rb +96 -0
  37. data/lib/adhearsion/{core_extensions → foundation}/thread_safety.rb +0 -0
  38. data/lib/adhearsion/host_definitions.rb +5 -1
  39. data/lib/adhearsion/initializer.rb +229 -73
  40. data/lib/adhearsion/initializer/asterisk.rb +33 -11
  41. data/lib/adhearsion/initializer/configuration.rb +58 -6
  42. data/lib/adhearsion/initializer/database.rb +3 -46
  43. data/lib/adhearsion/initializer/drb.rb +9 -3
  44. data/lib/adhearsion/initializer/freeswitch.rb +3 -3
  45. data/lib/adhearsion/initializer/rails.rb +1 -1
  46. data/lib/adhearsion/tasks.rb +2 -1
  47. data/lib/adhearsion/tasks/deprecations.rb +59 -0
  48. data/lib/adhearsion/version.rb +3 -3
  49. data/lib/adhearsion/voip/asterisk.rb +2 -2
  50. data/lib/adhearsion/voip/asterisk/agi_server.rb +9 -6
  51. data/lib/adhearsion/voip/asterisk/commands.rb +106 -4
  52. data/lib/adhearsion/voip/asterisk/manager_interface.rb +562 -0
  53. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +1754 -0
  54. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +286 -0
  55. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +78 -0
  56. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +87 -0
  57. data/lib/adhearsion/voip/asterisk/super_manager.rb +19 -0
  58. data/lib/adhearsion/voip/call.rb +51 -2
  59. data/lib/adhearsion/voip/dial_plan.rb +74 -61
  60. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +1 -1
  61. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +2 -6
  62. data/lib/adhearsion/voip/dsl/numerical_string.rb +2 -2
  63. data/lib/adhearsion/voip/freeswitch/oes_server.rb +2 -2
  64. data/lib/theatre.rb +151 -0
  65. data/lib/theatre/README.markdown +64 -0
  66. data/lib/theatre/callback_definition_loader.rb +84 -0
  67. data/lib/theatre/guid.rb +23 -0
  68. data/lib/theatre/invocation.rb +121 -0
  69. data/lib/theatre/namespace_manager.rb +153 -0
  70. data/lib/theatre/version.rb +2 -0
  71. metadata +63 -138
  72. data/Manifest.txt +0 -149
  73. data/README.txt +0 -6
  74. data/ahn_generators/component/USAGE +0 -5
  75. data/ahn_generators/component/component_generator.rb +0 -57
  76. data/ahn_generators/component/templates/configuration.rb +0 -0
  77. data/ahn_generators/component/templates/lib/lib.rb.erb +0 -3
  78. data/ahn_generators/component/templates/test/test.rb.erb +0 -12
  79. data/ahn_generators/component/templates/test/test_helper.rb +0 -14
  80. data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
  81. data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +0 -14
  82. data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +0 -31
  83. data/lib/adhearsion/core_extensions/array.rb +0 -0
  84. data/lib/adhearsion/core_extensions/guid.rb +0 -5
  85. data/lib/adhearsion/core_extensions/hash.rb +0 -0
  86. data/lib/adhearsion/core_extensions/numeric.rb +0 -4
  87. data/lib/adhearsion/core_extensions/proc.rb +0 -0
  88. data/lib/adhearsion/core_extensions/pseudo_uuid.rb +0 -11
  89. data/lib/adhearsion/core_extensions/publishable.rb +0 -73
  90. data/lib/adhearsion/core_extensions/string.rb +0 -26
  91. data/lib/adhearsion/core_extensions/thread.rb +0 -13
  92. data/lib/adhearsion/core_extensions/time.rb +0 -0
  93. data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
  94. data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
  95. data/lib/adhearsion/distributed/gateways/rest_gateway.rb +0 -9
  96. data/lib/adhearsion/distributed/gateways/soap_gateway.rb +0 -9
  97. data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +0 -9
  98. data/lib/adhearsion/distributed/peer_finder.rb +0 -0
  99. data/lib/adhearsion/distributed/remote_cli.rb +0 -0
  100. data/lib/adhearsion/hooks.rb +0 -57
  101. data/lib/adhearsion/initializer/paths.rb +0 -55
  102. data/lib/adhearsion/services/scheduler.rb +0 -5
  103. data/lib/adhearsion/voip/asterisk/ami.rb +0 -147
  104. data/lib/adhearsion/voip/asterisk/ami/actions.rb +0 -238
  105. data/lib/adhearsion/voip/asterisk/ami/machine.rb +0 -871
  106. data/lib/adhearsion/voip/asterisk/ami/machine.rl +0 -109
  107. data/lib/adhearsion/voip/asterisk/ami/parser.rb +0 -262
  108. data/script/destroy +0 -14
  109. data/script/generate +0 -14
  110. data/spec/fixtures/dialplan.rb +0 -3
  111. data/spec/initializer/test_configuration.rb +0 -267
  112. data/spec/initializer/test_loading.rb +0 -162
  113. data/spec/initializer/test_paths.rb +0 -43
  114. data/spec/silence.rb +0 -10
  115. data/spec/test_ahn_command.rb +0 -149
  116. data/spec/test_code_quality.rb +0 -87
  117. data/spec/test_component_manager.rb +0 -97
  118. data/spec/test_constants.rb +0 -8
  119. data/spec/test_drb.rb +0 -104
  120. data/spec/test_helper.rb +0 -94
  121. data/spec/test_hooks.rb +0 -37
  122. data/spec/test_host_definitions.rb +0 -79
  123. data/spec/test_initialization.rb +0 -105
  124. data/spec/test_logging.rb +0 -80
  125. data/spec/test_relationship_properties.rb +0 -54
  126. data/spec/voip/asterisk/ami_response_definitions.rb +0 -23
  127. data/spec/voip/asterisk/config_file_generators/test_agents.rb +0 -253
  128. data/spec/voip/asterisk/config_file_generators/test_queues.rb +0 -325
  129. data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +0 -306
  130. data/spec/voip/asterisk/menu_command/test_calculated_match.rb +0 -111
  131. data/spec/voip/asterisk/menu_command/test_matchers.rb +0 -98
  132. data/spec/voip/asterisk/mock_ami_server.rb +0 -176
  133. data/spec/voip/asterisk/test_agi_server.rb +0 -451
  134. data/spec/voip/asterisk/test_ami.rb +0 -227
  135. data/spec/voip/asterisk/test_commands.rb +0 -2006
  136. data/spec/voip/asterisk/test_config_manager.rb +0 -129
  137. data/spec/voip/dsl/dispatcher_spec_helper.rb +0 -45
  138. data/spec/voip/dsl/test_dialing_dsl.rb +0 -268
  139. data/spec/voip/dsl/test_dispatcher.rb +0 -82
  140. data/spec/voip/dsl/test_parser.rb +0 -87
  141. data/spec/voip/freeswitch/test_basic_connection_manager.rb +0 -39
  142. data/spec/voip/freeswitch/test_inbound_connection_manager.rb +0 -39
  143. data/spec/voip/freeswitch/test_oes_server.rb +0 -9
  144. data/spec/voip/test_call_routing.rb +0 -127
  145. data/spec/voip/test_dialplan_manager.rb +0 -372
  146. data/spec/voip/test_numerical_string.rb +0 -48
  147. data/spec/voip/test_phone_number.rb +0 -36
  148. data/test/test_ahn_generator.rb +0 -59
  149. data/test/test_component_generator.rb +0 -52
  150. data/test/test_generator_helper.rb +0 -20
@@ -1,3 +0,0 @@
1
- class <%= class_name %>
2
-
3
- end
@@ -1,12 +0,0 @@
1
- require File.dirname(__FILE__) + "/test_helper"
2
-
3
- class Test<%= class_name %> < Test::Unit::TestCase
4
-
5
- def setup
6
- @<%= name %> = <%= class_name %>.new
7
- end
8
-
9
- def test_truth
10
-
11
- end
12
- end
@@ -1,14 +0,0 @@
1
- $:.unshift File.dirname(__FILE__) + '/../../../../../lib'
2
- require 'adhearsion'
3
- require 'test/unit'
4
- require 'flexmock/test_unit'
5
- AHN_ROOT = Adhearsion::PathString.new(File.dirname(__FILE__) + '/../../..')
6
- Adhearsion::ComponentManager.load
7
- Adhearsion::ComponentManager.start
8
-
9
- class Test::Unit::TestCase
10
- Adhearsion::ComponentManager.components_with_call_context.each_pair do |component_class_name, component_configuration|
11
- const_set(component_class_name, component_configuration.component_class)
12
- const_get(component_class_name).send(:attr_accessor, :call_context)
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- $:.unshift File.dirname(__FILE__) + '/../../../../../lib'
2
- require 'adhearsion'
3
- require 'test/unit'
4
- require 'flexmock/test_unit'
5
- AHN_ROOT = Adhearsion::PathString.new(File.dirname(__FILE__) + '/../../..')
6
- Adhearsion::ComponentManager.load
7
- Adhearsion::ComponentManager.start
8
-
9
- class Test::Unit::TestCase
10
- Adhearsion::ComponentManager.components_with_call_context.each_pair do |component_class_name, component_configuration|
11
- const_set(component_class_name, component_configuration.component_class)
12
- const_get(component_class_name).send(:attr_accessor, :call_context)
13
- end
14
- end
@@ -1,31 +0,0 @@
1
- require File.dirname(__FILE__) + "/test_helper"
2
-
3
- class TestSimonGame < Test::Unit::TestCase
4
- attr_reader :game
5
- def setup
6
- @game = SimonGame.new
7
- @game.call_context = mock_call_context
8
- end
9
-
10
- def test_game_executes_say_digits_when_asked_to_say_number
11
- flexmock(game).should_receive(:random_number).and_return("2")
12
- mock_call_context.should_receive(:say_digits).once.with('2')
13
- @game.say_number
14
- end
15
-
16
-
17
- # Didn't get very far on this
18
- def xtest_can_play_one_round_and_receive_the_players_score
19
- flexmock(game).should_receive(:random_number).and_return("2")
20
- assert_equal(3, 'x')
21
- end
22
-
23
- private
24
- def mock_call_context
25
- @mock_call_context ||= flexmock("Mock Call Context")
26
- end
27
-
28
- def stub_random_number
29
-
30
- end
31
- end
File without changes
@@ -1,5 +0,0 @@
1
- module Kernel
2
- def new_guid(args)
3
-
4
- end
5
- end
File without changes
@@ -1,4 +0,0 @@
1
- class Numeric
2
- def digit() self end
3
- def digits() self end
4
- end
File without changes
@@ -1,11 +0,0 @@
1
- module PseudoUuidGenerator
2
- def uuid
3
- returning Array.new(32) { String.random_char } do |string|
4
- [8, 13, 18, 23].each do |index|
5
- string.insert index, '-'
6
- end
7
- end.join
8
- end
9
- end
10
-
11
- include PseudoUuidGenerator
@@ -1,73 +0,0 @@
1
- module Adhearsion
2
- class DrbDoor
3
-
4
- include Singleton
5
-
6
- def add(interface, name, meth)
7
- @interfaces ||= {}
8
- @interfaces[interface] ||= returning(Object.new) { |obj| obj.metaclass.send(:attr_accessor, :__methods) }
9
- obj = @interfaces[interface]
10
- obj.__methods ||= {}
11
- obj.__methods[name] = meth
12
- obj.instance_eval(<<-STR, __FILE__, __LINE__)
13
- def #{name}(*args, &block)
14
- begin
15
- __methods["#{name}"].call(*args, &block)
16
- rescue => exception
17
- raise RuntimeError, exception.message, exception.backtrace
18
- end
19
- end
20
- STR
21
- end
22
-
23
- def method_missing(name, *args, &block)
24
- return Module.const_get(name) if name.to_s =~ /^[A-Z]/
25
- super unless @interfaces && @interfaces.has_key?(name.to_s)
26
- @interfaces[name.to_s]
27
- end
28
- end
29
-
30
- module Publishable
31
- def self.included(base)
32
- base.send(:alias_method_chain, :initialize, :publishable)
33
- base.extend(ClassMethods)
34
- end
35
-
36
- def initialize_with_publishable(*args, &block)
37
- initialize_without_publishable(*args, &block)
38
- self.class.published_instance_methods.each do |(sym, interface)|
39
- DrbDoor.instance.add(interface, sym.to_s, self.method(sym))
40
- end
41
- end
42
-
43
- module ClassMethods
44
- attr_reader :interface
45
- attr_reader :published_instance_methods
46
-
47
- def publish(options={}, &block)
48
- @interface = options.delete(:through).to_s || self.to_s
49
- begin
50
- @capture = true
51
- yield
52
- ensure
53
- @capture = false
54
- end
55
- end
56
-
57
- def method_added(sym)
58
- return if not @capture
59
- if sym.to_s !~ /method_added/
60
- @published_instance_methods ||= []
61
- @published_instance_methods << [sym, @interface]
62
- end
63
- end
64
-
65
- def singleton_method_added(sym)
66
- return if not @capture
67
- if sym.to_s !~ /method_added/
68
- DrbDoor.instance.add(@interface, sym.to_s, method(sym.to_s))
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,26 +0,0 @@
1
- class String
2
-
3
- def unindent
4
- gsub(/^\s*/,'')
5
- end
6
-
7
- def unindent!
8
- gsub!(/^\s*/,'')
9
- end
10
-
11
- def self.random_char
12
- case random_digit = rand(62)
13
- when 0...10 : random_digit.to_s
14
- when 10...36 : (random_digit + 55).chr
15
- when 36...62 : (random_digit + 61).chr
16
- end
17
- end
18
-
19
- def self.random(length_of_string=8)
20
- Array.new(length_of_string) { random_char }.join
21
- end
22
-
23
- def nameify() downcase.gsub(/[^\w]/, '') end
24
- def nameify!() replace nameify end
25
-
26
- end
@@ -1,13 +0,0 @@
1
- class Thread
2
- class << self
3
-
4
- # Syntactically sugar Thread.current since it's used so much.
5
- #
6
- # Allows:
7
- # Thread.me.extend DSL::Dialplan::ThreadMixin
8
- # Thread.my.call.io = io
9
-
10
- alias me current
11
- alias my current
12
- end
13
- end
File without changes
@@ -1,9 +0,0 @@
1
- module Adhearsion
2
- module Distributed
3
- module Gateway
4
- module REST
5
-
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Adhearsion
2
- module Distributed
3
- module Gateway
4
- module SOAP
5
-
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Adhearsion
2
- module Distributed
3
- module Gateway
4
- module XMLRPC
5
-
6
- end
7
- end
8
- end
9
- end
File without changes
File without changes
@@ -1,57 +0,0 @@
1
- module Adhearsion
2
-
3
-
4
- module Hooks
5
-
6
- class GenericHook
7
-
8
- def initialize
9
- @hooks = []
10
- end
11
-
12
- def create_hook(&block)
13
- @hooks.synchronize do
14
- @hooks << block
15
- end
16
- end
17
-
18
- # TODO: This is hardly thread safe!
19
- def trigger_hooks
20
- @hooks.each &:call
21
- end
22
-
23
- end
24
-
25
- class HookWithArguments < GenericHook
26
- def trigger_hooks(*args)
27
- @hooks.each { |hook| hook.call(*args) }
28
- end
29
- end
30
-
31
- ThreadsJoinedAfterInitialized = GenericHook.new
32
-
33
- OnFailedCall = HookWithArguments.new
34
- OnHungupCall = HookWithArguments.new
35
- AfterInitialized = GenericHook.new
36
- BeforeCall = GenericHook.new
37
- AfterCall = GenericHook.new
38
- TearDown = GenericHook.new
39
-
40
- class << TearDown
41
- def aliases
42
- [:before_shutdown]
43
- end
44
-
45
- def catch_termination_signals
46
- %w'INT TERM'.each do |sig|
47
- trap sig do
48
- ahn_log "Shutting down gracefully at #{Time.now}."
49
- Adhearsion::Hooks::TearDown.trigger_hooks
50
- exit
51
- end
52
- end
53
- end
54
- end
55
-
56
- end
57
- end
@@ -1,55 +0,0 @@
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
@@ -1,5 +0,0 @@
1
- module Adhearsion
2
- module Scheduler
3
-
4
- end
5
- end
@@ -1,147 +0,0 @@
1
- require 'rubygems'
2
- require 'pp'
3
- require 'yaml'
4
- require 'socket'
5
- require 'thread'
6
- require 'monitor'
7
- require 'adhearsion/voip/asterisk/ami/parser'
8
- require 'adhearsion/voip/asterisk/ami/actions'
9
-
10
- module Adhearsion
11
- module VoIP
12
- module Asterisk
13
- class AMI
14
-
15
- include Actions
16
-
17
- attr_reader :action_sock, :host, :user, :password, :port, :event_thread, :scanner, :version
18
-
19
- def initialize(user, pass, host='127.0.0.1', options={})
20
- @host, @user, @password, @port = host, user, pass, options[:port] || 5038
21
- @events_enabled = options[:events]
22
- end
23
-
24
- include Adhearsion::Publishable
25
-
26
- publish :through => :proxy do
27
-
28
- def originate(options={})
29
- options[:callerid] = options.delete :caller_id if options[:caller_id]
30
- execute_ami_command! :originate, options
31
- end
32
-
33
- def ping
34
- execute_ami_command! :ping
35
- end
36
-
37
- # An introduction connects two endpoints together. The first argument is
38
- # the first person the PBX will call. When she's picked up, Asterisk will
39
- # play ringing while the second person is being dialed.
40
- #
41
- # The first argument is the person called first. Pass this as a canonical
42
- # IAX2/server/user type argument. Destination takes the same format, but
43
- # comma-separated Dial() arguments can be optionally passed after the
44
- # technology.
45
- #
46
- # TODO: Provide an example when this works.
47
- def introduce(caller, callee, opts={})
48
- dial_args = callee
49
- dial_args += "|#{opts[:options]}" if opts[:options]
50
- call_and_exec caller, "Dial", :args => dial_args, :caller_id => opts[:caller_id]
51
- end
52
-
53
- def call_and_exec(channel, app, opts={})
54
- args = { :channel => channel, :application => app }
55
- args[:caller_id] = opts[:caller_id] if opts[:caller_id]
56
- args[:data] = opts[:args] if opts[:args]
57
- originate args
58
- end
59
-
60
- def call_into_context(channel, context, options={})
61
- args = {:channel => channel, :context => context}
62
- args[:priority] = options[:priority] || 1
63
- args[:extension] = options[:extension] if options[:extension]
64
- args[:caller_id] = options[:caller_id] if options[:caller_id]
65
- if options[:variables] && options[:variables].kind_of?(Hash)
66
- args[:variable] = options[:variables].map {|pair| pair.join('=')}.join('|')
67
- end
68
- originate args
69
- end
70
-
71
- def method_missing(name, hash={}, &block)
72
- execute_ami_command! name, hash, &block
73
- end
74
-
75
- end
76
-
77
- def connect!
78
- disconnect!
79
- start_event_thread! if events_enabled?
80
- login! host, user, password, port, events_enabled?
81
- end
82
-
83
- def disconnect!
84
- action_sock.close if action_sock && !action_sock.closed?
85
- event_thread.kill if event_thread
86
- scanner.stop if scanner
87
- end
88
-
89
- def events_enabled?
90
- @events_enabled
91
- end
92
-
93
- private
94
-
95
- def login!(host, user, pass, port, events)
96
- begin
97
- @action_sock = TCPSocket.new host, port
98
- rescue Errno::ECONNREFUSED => refusal_error
99
- raise Errno::ECONNREFUSED, "Could not connect with AMI to Asterisk server at #{host}:#{port}. " +
100
- "Is enabled set to 'yes' in manager.conf?"
101
- end
102
- action_sock.extend(MonitorMixin)
103
- @scanner = Parser.new
104
- @version = scanner.run(action_sock)
105
- begin
106
- execute_ami_command! :login, :username => user, :secret => password, :events => (events_enabled? ? "On" : "Off")
107
- rescue ActionError
108
- raise AuthenticationFailedException, "Invalid AMI username/password! Check manager.conf."
109
- else
110
- # puts "Manager connection established to #{host}:#{port} with user '#{user}'"
111
- end
112
- end
113
-
114
- def execute_ami_command!(name, options={}, &block)
115
- action = Action.build(name, options, &block)
116
- action_sock.synchronize do
117
- connect! if !action_sock || action_sock.closed?
118
- action_sock.write action.to_s
119
- end
120
-
121
- return unless action.has_response?
122
- scanner.wait(action)
123
- end
124
-
125
- def start_event_thread!
126
- @event_thread = Thread.new(scanner) do |scanner|
127
- loop do
128
- # TODO: This is totally screwed up. __read_event doesn't exist.
129
- AMI::EventHandler.handle! __read_event(scanner.events.pop)
130
- end
131
- end
132
- event_thread.abort_on_exception = true
133
- end
134
-
135
- # Method simply defined as private to prevent method_missing from catching it.
136
- def events() end
137
-
138
- class EventHandler
139
- # TODO: Refactor me!
140
- end
141
-
142
- class AuthenticationFailedException < Exception; end
143
- class ActionError < RuntimeError; end
144
- end
145
- end
146
- end
147
- end