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
@@ -1,58 +0,0 @@
1
- module Adhearsion
2
- module VoIP
3
- module FreeSwitch
4
-
5
- # Subclass this to register a new event handler
6
- class EventHandler
7
-
8
- @@events = {}
9
- @@compound_events = {}
10
-
11
- @@connection = nil
12
-
13
- def self.start!(hash=nil)
14
- login hash if hash
15
- raise "You must login to the FreeSWITCH EventSocket!" unless @@connection
16
- loop do
17
- # debug "Waiting for an event"
18
- dispatch_event! @@connection.get_header
19
- end
20
- end
21
-
22
- def self.dispatch_event!(data)
23
- #puts "\nHandling an event! #{data.inspect}"
24
- name = data['Event-Name']
25
- normal_event = name && @@events[name.underscore.to_sym]
26
- # puts "THIS IS WHAT I THINK IT MIGHT BE : #{normal_event.inspect} (with #{name.underscore.to_sym.inspect})"
27
- if normal_event then normal_event.call(data)
28
- else
29
- #debug "Trying compound events"
30
- @@compound_events.each do |(event, block)|
31
- mini_event = {}
32
- event.keys.each { |k| mini_event[k] = data[k] }
33
- block.call(data) if event == mini_event
34
- end
35
- end
36
- rescue => e
37
- p e
38
- puts e.backtrace.map { |x| " " * 4 + x }
39
- end
40
-
41
- protected
42
-
43
- # Can be specified in the subclass
44
- def self.login(hash)
45
- debug "Creating a new event connection manager"
46
- @@connection = InboundConnectionManager.new hash
47
- debug "Enabling events"
48
- @@connection.enable_events!
49
- end
50
-
51
- def self.on(event, &block)
52
- event = event.underscore.to_sym if event.is_a? String
53
- (event.kind_of?(Hash) ? @@compound_events : @@events)[event] = block
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,129 +0,0 @@
1
- require 'adhearsion/voip/dsl/dialplan/dispatcher'
2
-
3
- module Adhearsion
4
- module VoIP
5
- module FreeSwitch
6
- class FreeSwitchDialplanCommandFactory
7
-
8
- def initialize(context=nil)
9
- @context = context
10
- end
11
-
12
- # These should all return those objects...
13
- def speak(text, hash={})
14
- voice, engine = hash[:voice] || "Dianne", hash[:engine] || "cepstral"
15
-
16
- dtmf = hash[:on_keypress]
17
- speak_cmd = cmd 'speak', "#{engine}|#{voice}|%p" % text, :on_keypress => dtmf
18
-
19
- if hash[:timeout] == 0
20
- [speak_cmd, DSL::Dialplan::NoOpEventCommand.new(hash[:timeout], :on_keypress => dtmf)]
21
- else
22
- puts "Returning the normal speak command"
23
- speak_cmd
24
- end
25
- end
26
-
27
- def set(key, value)
28
- cmd 'set', "#{key}=#{value}"
29
- end
30
-
31
- def play(*files)
32
- hash = files.last.kind_of?(Hash) ? files.pop : {}
33
- conference, to = hash[:conference], hash[:to]
34
- puts "conference: #{conference.inspect}, to: #{to.inspect}, hash: #{hash.inspect}, files: #{files.inspect}"
35
- if conference
36
- # Normal (inbound) event socket playing to a conference
37
- files.map do |file|
38
- cmd "conference", "#{conference} play #{file} #{to}"
39
- end
40
- elsif to
41
- # Normal event socket syntax
42
- files.map do |file|
43
- # TODO: Support playing to an individual leg of the call.
44
- cmd "broadcast", "#{to} #{file} both"
45
- end
46
- else
47
- # Outbound event sockets
48
- files.map { |file| cmd('playback', file) }
49
- end
50
- end
51
-
52
- def join(id)
53
- DSL::Dialplan::ExitingEventCommand.new "conference", id.to_s
54
- end
55
-
56
- def hangup!
57
- cmd "exit"
58
- end
59
-
60
- def return!(obj)
61
- raise DSL::Dialplan::ReturnValue.new(obj)
62
- end
63
-
64
- def hangup!
65
- raise DSL::Dialplan::Hangup
66
- end
67
-
68
- def wait(seconds=nil, &block)
69
- DSL::Dialplan::NoOpEventCommand.new(seconds)
70
- end
71
-
72
- def record(hash={}, &block)
73
- # TODO: Could want to record a conference or a UUID
74
- p hash
75
- if hash[:stop]
76
- cmd 'stop_record_session', hash[:stop]
77
- else
78
- file = hash[:file] || File.join(Dir::tmpdir, String.random(32), '.wav')
79
-
80
- raise "Cannot supply both a timeout and a block!" if hash[:timeout] && block_given?
81
-
82
- dtmf_breaker = lambda do |digit|
83
- return! file if digit == hash[:break_on]
84
- end
85
-
86
- rec_cmd = cmd "record", file, :on_keypress => dtmf_breaker
87
- [].tap do |cmds|
88
- cmds << play('beep') if hash[:beep]
89
- cmds << rec_cmd
90
- if hash[:timeout]
91
- cmds << DSL::Dialplan::NoOpEventCommand.new(hash[:timeout])
92
- elsif block_given?
93
- cmds << block
94
- cmds << record(:stop => file)
95
- end
96
- cmds << file
97
- p cmds
98
- cmds
99
- end
100
- end
101
- end
102
-
103
- def input(number=nil, hash={})
104
- timeout, file = hash[:timeout], hash[:play] || hash[:file]
105
- break_on = hash[:break_on] || '#'
106
-
107
- # TODO: compile play() and set its DTMF callback to this one
108
- digits = []
109
- dtmf_hook = lambda do |digit|
110
- puts "RECEIVED #{digit} WITH #{digits}"
111
- return! digits.to_s if digit.to_s == break_on.to_s
112
- digits << digit
113
- return! digits.to_s if number && digits.size >= number
114
- end
115
- DSL::Dialplan::NoOpEventCommand.new.tap do |command|
116
- command.on_keypress &dtmf_hook
117
- end
118
- end
119
-
120
- private
121
-
122
- def cmd(*args, &block)
123
- DSL::Dialplan::EventCommand.new(*args, &block)
124
- end
125
-
126
- end
127
- end
128
- end
129
- end
@@ -1,38 +0,0 @@
1
- require 'adhearsion/voip/freeswitch/basic_connection_manager'
2
- module Adhearsion
3
- module VoIP
4
- module FreeSwitch
5
- class InboundConnectionManager < BasicConnectionManager
6
-
7
- DEFAULTS = { :pass => "ClueCon", :host => '127.0.0.1', :port => 8021 }
8
-
9
- def initialize(arg)
10
- if arg.kind_of? Hash
11
- @opts = DEFAULTS.merge arg
12
- @io = TCPSocket.new(@opts[:host], @opts[:port])
13
- super @io
14
- unless login(@opts[:pass])
15
- raise "Your FreeSwitch Event Socket password for #{@opts[:host]} was invalid!"
16
- end
17
- else arg.kind_of? IO
18
- @io = arg
19
- super @io
20
- end
21
- end
22
-
23
- def enable_events!(which='ALL')
24
- self << "event plain #{which}"
25
- get_raw_header
26
- end
27
-
28
- # Only called when nothing has been sent over the socket.
29
- def login(pass)
30
- get_raw_header
31
- self << "auth #{pass}"
32
- get_raw_header.include? "+OK"
33
- end
34
-
35
- end
36
- end
37
- end
38
- end
@@ -1,195 +0,0 @@
1
- require 'gserver'
2
-
3
- require 'adhearsion/voip/dsl/dialplan/thread_mixin'
4
- require 'adhearsion/voip/dsl/dialplan/parser'
5
- require 'adhearsion/voip/dsl/dialplan/dispatcher'
6
- require 'adhearsion/voip/freeswitch/basic_connection_manager'
7
- require 'adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory'
8
-
9
- module Adhearsion
10
- module VoIP
11
- module FreeSwitch
12
- class OesServer < GServer
13
-
14
- def initialize(port, host=nil)
15
- @port, @host = port || 4572, host || "0.0.0.0"
16
- @cache_lock = Mutex.new
17
- super @port, @host, (1.0/0.0)
18
- log "Starting FreeSwitch OES Server"
19
- end
20
-
21
- def serve(io)
22
-
23
- log "Incoming call on the FreeSwitch outbound event socket..."
24
- Thread.me.extend DSL::Dialplan::ThreadMixin
25
- Thread.me.call.io = io
26
- conn = BasicConnectionManager.new io
27
-
28
- Thread.my.call.mgr = conn
29
- conn << "connect"
30
- @vars = conn.get_header
31
- answered = @vars['variable_endpoint_disposition'] == "ANSWER"
32
-
33
- conn << "myevents"
34
- myevents_response = conn.get_header
35
- answered ||= myevents_response['Event-Name'] == 'CHANNEL_ANSWER'
36
-
37
- log "Connected to Freeswitch. Waiting for answer state."
38
-
39
- until answered
40
- answered ||= conn.get_header['Event-Name'] == 'CHANNEL_ANSWER'
41
- end
42
-
43
- log "Loading cached dialplan"
44
- contexts, dispatcher = cached_dialplan_data
45
- log "Finished loading cached dialplans"
46
-
47
- first_context_name = @vars['variable_context'] || @vars["Channel-Context"]
48
- first_context = contexts[first_context_name.to_sym]
49
-
50
- log "Found context #{first_context_name} from call variables."
51
-
52
- # If the target context does not exist, warn and don't handle the call
53
- unless first_context
54
- log "No context '#{first_context_name}' found in " +
55
- "#{AHN_CONFIG.files_from_setting("paths", "").to_sentence(:connector => "or")}. Ignoring request!"
56
- return
57
- end
58
-
59
- # Enable events
60
-
61
- # Now that we have the code, let's dispatch it back.
62
-
63
- pretty_vars = rubyize_keys_for @vars
64
- dispatcher.def_keys! pretty_vars
65
- dispatcher.instance_eval(&first_context.block)
66
-
67
- rescue => e
68
- p e
69
- puts e.backtrace.map {|x| " " * 4 + x }
70
- end
71
-
72
- def cached_dialplan_data
73
- @cache_lock.synchronize do
74
- log "Checking whether the contexts should be reloaded"
75
- if should_reload_contexts?
76
- log "Getting the contexts"
77
- @abstract_contexts = DSL::Dialplan::DialplanParser.get_contexts
78
- log "Creating a new OesDispatcher"
79
- @abstract_dispatcher = OesDispatcher.new @vars['Channel-Unique-ID']
80
- log "Done creating it"
81
- @abstract_dispatcher.def_keys! @abstract_contexts
82
- else
83
- log "Should not reload context."
84
- @abstract_dispatcher.instance_variable_set :@uuid, @vars['Channel-Unique-ID']
85
- end
86
- return [@abstract_contexts.clone, @abstract_dispatcher.clone]
87
- end
88
- end
89
-
90
- # TODO. This is broken. Always returns true. Should cache the last reload
91
- # time.
92
- def should_reload_contexts?
93
- !@abstract_contexts || !@abstract_dispatcher ||
94
- AHN_CONFIG.files_from_setting("paths", "dialplan").map { |x| File.mtime(x) }.max < Time.now
95
- end
96
-
97
- def rubyize_keys_for(hash)
98
- {}.tap do |pretty|
99
- hash.each { |k,v| pretty[k.to_s.underscore] = v }
100
- end
101
- end
102
-
103
- class OesDispatcher < DSL::Dialplan::CommandDispatcher
104
-
105
- def initialize(uuid=nil)
106
- super FreeSwitchDialplanCommandFactory, uuid
107
- end
108
-
109
- def dispatch!(event)
110
- if event.kind_of?(DSL::Dialplan::NoOpEventCommand) && event.on_keypress
111
- return_value = nil
112
- dispatch = lambda do
113
- loop do
114
- Thread.my.call.mgr.get_raw_header
115
- async_event = Thread.my.call.mgr.get_header
116
- if async_event['Event-Name'] == 'DTMF'
117
- key = async_event['DTMF-String']
118
- return_value = event.on_keypress.call(('0'..'9').include?(key) ? key.to_i : key)
119
- end
120
- end
121
- end
122
- if event.timeout
123
- begin
124
- Timeout.timeout event.timeout, &dispatch
125
- rescue Timeout::Error
126
- break!
127
- return_value
128
- end
129
- else dispatch.call
130
- end
131
-
132
- else
133
- log "Not a noop. Sending #{event.app}(#{event.args.to_a * " "})"
134
- Thread.my.call.mgr << "SendMsg\ncall-command: execute\nexecute-app-name: " +
135
- "#{event.app}\nexecute-app-arg: #{event.args.to_a * " "}"
136
-
137
- if event.kind_of? DSL::Dialplan::ExitingEventCommand
138
- Thread.my.call.io.close
139
- Thread.me.exit
140
- end
141
-
142
- # Useless "command/reply" +OK and content-length headers
143
- lambda do
144
- Thread.my.call.mgr.get_raw_header
145
- redo if Thread.my.call.mgr.get_header['Event-Name'] == "CHANNEL_EXECUTE_COMPLETE"
146
- end.call
147
-
148
- # Main event information. Keep track of the Core-UUID and wait for
149
- # it to come back to us as a CHANNEL_EXECUTE_COMPLETE event.
150
- execution_header = Thread.my.call.mgr.get_header
151
- execution_uuid = execution_header['Core-UUID']
152
-
153
- loop do
154
- log "Waiting for either a DTMF or the app to finish"
155
- hdr = Thread.my.call.mgr.get_raw_header
156
- log "Got head #{hdr}"
157
-
158
- if hdr == "Content-Type: api/response\nContent-Length: 0"
159
- break
160
- end
161
-
162
- async_event = Thread.my.call.mgr.get_header
163
- event_name = async_event['Event-Name']
164
- if event_name == 'DTMF' && event.on_keypress
165
- key = async_event['DTMF-String']
166
- event.on_keypress.call(('0'..'9') === key ? key.to_i : key)
167
- elsif event_name == 'CHANNEL_EXECUTE_COMPLETE' && async_event['Core-UUID'] == execution_uuid
168
- break async_event
169
- else
170
-
171
- end
172
- end
173
- end
174
- rescue DSL::Dialplan::ReturnValue => r
175
- log "Dispatch!: Got a return value with #{r.obj}"
176
- break!
177
- raise r
178
- rescue DSL::Dialplan::Hangup
179
- Thread.my.call.mgr << "SendMsg\ncall-command: hangup"
180
- Thread.my.call.mgr.io.close rescue nil
181
- end
182
-
183
- def break!(uuid=@context)
184
- log "Breaking with #{uuid}"
185
- Thread.my.call.mgr << "api break #{uuid}"
186
- Thread.my.call.mgr.get_raw_header
187
- # Thread.my.call.mgr.get_raw_header
188
- # Thread.my.call.mgr.get_raw_header
189
- end
190
- end
191
-
192
- end
193
- end
194
- end
195
- end
@@ -1,80 +0,0 @@
1
- module Adhearsion
2
- module VoIP
3
- class CalculatedMatch
4
-
5
- # Convenience method for instantiating failed matches
6
- def self.failed_match!(pattern, query, match_payload)
7
- new :pattern => pattern, :query => query, :match_payload => match_payload
8
- end
9
-
10
- attr_reader :match_payload, :potential_matches, :exact_matches, :pattern, :query
11
-
12
- def initialize(options={})
13
- @pattern, @query, @match_payload = options.values_at :pattern, :query, :match_payload
14
- @potential_matches = options[:potential_matches] ? Array(options[:potential_matches]) : []
15
- @exact_matches = options[:exact_matches] ? Array(options[:exact_matches]) : []
16
- end
17
-
18
- def exact_match?
19
- exact_matches.any?
20
- end
21
-
22
- def potential_match?
23
- potential_matches.any?
24
- end
25
-
26
- def failed_match?
27
- !potential_match? && !exact_match?
28
- end
29
-
30
- def type_of_match
31
- if exact_match?
32
- :exact
33
- elsif potential_match?
34
- :potential
35
- end
36
- end
37
-
38
- end
39
-
40
- class CalculatedMatchCollection
41
-
42
- attr_reader :calculated_matches, :potential_matches, :exact_matches,
43
- :actual_potential_matches, :actual_exact_matches
44
-
45
- def initialize
46
- @calculated_matches = []
47
- @potential_matches = []
48
- @exact_matches = []
49
- @actual_potential_matches = []
50
- @actual_exact_matches = []
51
- end
52
-
53
- def <<(calculated_match)
54
- calculated_matches << calculated_match
55
- actual_potential_matches.concat calculated_match.potential_matches
56
- actual_exact_matches.concat calculated_match.exact_matches
57
-
58
- potential_matches << calculated_match if calculated_match.potential_match?
59
- exact_matches << calculated_match if calculated_match.exact_match?
60
- end
61
-
62
- def potential_match_count
63
- actual_potential_matches.size
64
- end
65
-
66
- def exact_match_count
67
- actual_exact_matches.size
68
- end
69
-
70
- def potential_match?
71
- potential_match_count > 0
72
- end
73
-
74
- def exact_match?
75
- exact_match_count > 0
76
- end
77
-
78
- end
79
- end
80
- end