adhearsion 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/CHANGELOG +11 -2
  2. data/EVENTS +1 -1
  3. data/Rakefile +4 -4
  4. data/adhearsion.gemspec +8 -4
  5. data/app_generators/ahn/USAGE +3 -3
  6. data/app_generators/ahn/ahn_generator.rb +11 -11
  7. data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +3 -3
  8. data/app_generators/ahn/templates/components/disabled/restful_rpc/example-client.rb +6 -6
  9. data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb +16 -16
  10. data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +42 -42
  11. data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.rb +11 -11
  12. data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +1 -1
  13. data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +6 -6
  14. data/app_generators/ahn/templates/components/simon_game/simon_game.rb +4 -4
  15. data/app_generators/ahn/templates/config/startup.rb +31 -16
  16. data/bin/ahn +3 -3
  17. data/bin/ahnctl +8 -8
  18. data/bin/jahn +3 -3
  19. data/examples/asterisk_manager_interface/standalone.rb +2 -2
  20. data/lib/adhearsion.rb +4 -2
  21. data/lib/adhearsion/cli.rb +31 -31
  22. data/lib/adhearsion/component_manager.rb +39 -39
  23. data/lib/adhearsion/component_manager/component_tester.rb +14 -14
  24. data/lib/adhearsion/component_manager/spec_framework.rb +1 -1
  25. data/lib/adhearsion/events_support.rb +12 -12
  26. data/lib/adhearsion/foundation/blank_slate.rb +1 -1
  27. data/lib/adhearsion/foundation/custom_daemonizer.rb +2 -2
  28. data/lib/adhearsion/foundation/event_socket.rb +26 -26
  29. data/lib/adhearsion/foundation/future_resource.rb +6 -6
  30. data/lib/adhearsion/foundation/metaprogramming.rb +2 -2
  31. data/lib/adhearsion/foundation/numeric.rb +3 -3
  32. data/lib/adhearsion/foundation/relationship_properties.rb +7 -7
  33. data/lib/adhearsion/foundation/string.rb +8 -8
  34. data/lib/adhearsion/foundation/synchronized_hash.rb +8 -8
  35. data/lib/adhearsion/host_definitions.rb +16 -16
  36. data/lib/adhearsion/initializer.rb +74 -65
  37. data/lib/adhearsion/initializer/asterisk.rb +15 -9
  38. data/lib/adhearsion/initializer/configuration.rb +54 -39
  39. data/lib/adhearsion/initializer/database.rb +4 -4
  40. data/lib/adhearsion/initializer/drb.rb +6 -6
  41. data/lib/adhearsion/initializer/freeswitch.rb +1 -1
  42. data/lib/adhearsion/initializer/ldap.rb +51 -0
  43. data/lib/adhearsion/initializer/rails.rb +8 -8
  44. data/lib/adhearsion/logging.rb +16 -16
  45. data/lib/adhearsion/tasks/deprecations.rb +12 -12
  46. data/lib/adhearsion/tasks/generating.rb +2 -2
  47. data/lib/adhearsion/tasks/testing.rb +7 -7
  48. data/lib/adhearsion/version.rb +1 -1
  49. data/lib/adhearsion/voip/asterisk/agi_server.rb +44 -14
  50. data/lib/adhearsion/voip/asterisk/commands.rb +281 -237
  51. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +8 -8
  52. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +14 -14
  53. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +16 -16
  54. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +39 -39
  55. data/lib/adhearsion/voip/asterisk/config_manager.rb +13 -13
  56. data/lib/adhearsion/voip/asterisk/manager_interface.rb +91 -87
  57. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +739 -739
  58. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +60 -60
  59. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +16 -16
  60. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +1 -1
  61. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +13 -13
  62. data/lib/adhearsion/voip/asterisk/super_manager.rb +3 -3
  63. data/lib/adhearsion/voip/call.rb +101 -64
  64. data/lib/adhearsion/voip/call_routing.rb +9 -9
  65. data/lib/adhearsion/voip/constants.rb +7 -7
  66. data/lib/adhearsion/voip/conveniences.rb +1 -1
  67. data/lib/adhearsion/voip/dial_plan.rb +42 -40
  68. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +27 -27
  69. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +1 -1
  70. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +6 -6
  71. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +17 -17
  72. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +7 -7
  73. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +2 -2
  74. data/lib/adhearsion/voip/dsl/numerical_string.rb +3 -3
  75. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +7 -7
  76. data/lib/adhearsion/voip/freeswitch/event_handler.rb +1 -1
  77. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +20 -20
  78. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +5 -5
  79. data/lib/adhearsion/voip/freeswitch/oes_server.rb +33 -33
  80. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +1 -1
  81. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +2 -2
  82. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +9 -9
  83. data/lib/theatre.rb +18 -18
  84. data/lib/theatre/callback_definition_loader.rb +17 -17
  85. data/lib/theatre/guid.rb +6 -6
  86. data/lib/theatre/invocation.rb +19 -19
  87. data/lib/theatre/namespace_manager.rb +28 -28
  88. metadata +55 -14
@@ -10,58 +10,58 @@ module Adhearsion
10
10
 
11
11
  %%{
12
12
  machine ami_protocol_parser;
13
-
13
+
14
14
  # All required Ragel actions are implemented as Ruby methods.
15
-
15
+
16
16
  # Executed after a "Respone: Success" or "Response: Pong"
17
17
  action init_success { init_success }
18
-
18
+
19
19
  action init_response_follows { init_response_follows }
20
-
20
+
21
21
  action init_error { init_error }
22
-
22
+
23
23
  action message_received { message_received @current_message }
24
24
  action error_received { error_received @current_message }
25
-
25
+
26
26
  action version_starts { version_starts }
27
27
  action version_stops { version_stops }
28
-
28
+
29
29
  action key_starts { key_starts }
30
30
  action key_stops { key_stops }
31
-
31
+
32
32
  action value_starts { value_starts }
33
33
  action value_stops { value_stops }
34
-
34
+
35
35
  action error_reason_starts { error_reason_starts }
36
36
  action error_reason_stops { error_reason_stops }
37
-
37
+
38
38
  action syntax_error_starts { syntax_error_starts }
39
39
  action syntax_error_stops { syntax_error_stops }
40
-
40
+
41
41
  action immediate_response_starts { immediate_response_starts }
42
42
  action immediate_response_stops { immediate_response_stops }
43
-
43
+
44
44
  action follows_text_starts { follows_text_starts }
45
45
  action follows_text_stops { follows_text_stops }
46
-
46
+
47
47
  action event_name_starts { event_name_starts }
48
48
  action event_name_stops { event_name_stops }
49
-
49
+
50
50
  include ami_protocol_parser_machine "ami_protocol_lexer_machine.rl";
51
-
51
+
52
52
  }%%##
53
53
 
54
54
  attr_accessor(:ami_version)
55
55
  def initialize
56
-
56
+
57
57
  @data = ""
58
58
  @current_pointer = 0
59
59
  @ragel_stack = []
60
-
60
+
61
61
  %%{
62
62
  # All other variables become local, letting Ruby garbage collect them. This
63
63
  # prevents us from having to manually reset them.
64
-
64
+
65
65
  variable data @data;
66
66
  variable p @current_pointer;
67
67
  variable pe @data_ending_pointer;
@@ -73,22 +73,22 @@ module Adhearsion
73
73
  variable eof @eof;
74
74
  variable stack @ragel_stack;
75
75
  variable top @ragel_stack_top;
76
-
76
+
77
77
  write data;
78
78
  write init;
79
79
  }%%##
80
-
80
+
81
81
  end
82
-
82
+
83
83
  def <<(new_data)
84
84
  extend_buffer_with new_data
85
85
  resume!
86
86
  end
87
-
87
+
88
88
  def resume!
89
89
  %%{ write exec; }%%##
90
90
  end
91
-
91
+
92
92
  def extend_buffer_with(new_data)
93
93
  if new_data.size + @data.size > BUFFER_SIZE
94
94
  @data.slice! 0...new_data.size
@@ -98,9 +98,9 @@ module Adhearsion
98
98
  @data << new_data
99
99
  @data_ending_pointer = @data.size
100
100
  end
101
-
101
+
102
102
  protected
103
-
103
+
104
104
  ##
105
105
  # Called after a response or event has been successfully parsed.
106
106
  #
@@ -130,117 +130,117 @@ module Adhearsion
130
130
  def syntax_error_encountered(ignored_chunk)
131
131
  raise NotImplementedError, "Must be implemented in subclass!"
132
132
  end
133
-
133
+
134
134
  def init_success
135
135
  @current_message = ManagerInterfaceResponse.new
136
136
  end
137
-
137
+
138
138
  def init_response_follows
139
139
  @current_message = ManagerInterfaceResponse.new
140
140
  end
141
-
141
+
142
142
  def init_error
143
143
  @current_message = ManagerInterfaceError.new()
144
144
  end
145
-
145
+
146
146
  def version_starts
147
147
  @start_of_version = @current_pointer
148
148
  end
149
-
149
+
150
150
  def version_stops
151
151
  self.ami_version = @data[@start_of_version...@current_pointer].to_f
152
152
  @start_of_version = nil
153
153
  end
154
-
154
+
155
155
  def event_name_starts
156
156
  @event_name_start = @current_pointer
157
157
  end
158
-
158
+
159
159
  def event_name_stops
160
160
  event_name = @data[@event_name_start...@current_pointer]
161
161
  @event_name_start = nil
162
162
  @current_message = ManagerInterfaceEvent.new(event_name)
163
163
  end
164
-
164
+
165
165
  def key_starts
166
166
  @current_key_position = @current_pointer
167
167
  end
168
-
168
+
169
169
  def key_stops
170
170
  @current_key = @data[@current_key_position...@current_pointer]
171
171
  end
172
-
172
+
173
173
  def value_starts
174
174
  @current_value_position = @current_pointer
175
175
  end
176
-
176
+
177
177
  def value_stops
178
178
  @current_value = @data[@current_value_position...@current_pointer]
179
179
  @last_seen_value_end = @current_pointer + 2 # 2 for \r\n
180
180
  add_pair_to_current_message
181
181
  end
182
-
182
+
183
183
  def error_reason_starts
184
184
  @error_reason_start = @current_pointer
185
185
  end
186
-
186
+
187
187
  def error_reason_stops
188
188
  @current_message.message = @data[@error_reason_start...@current_pointer]
189
189
  end
190
-
190
+
191
191
  def follows_text_starts
192
192
  @follows_text_start = @current_pointer
193
193
  end
194
-
194
+
195
195
  def follows_text_stops
196
196
  text = @data[@last_seen_value_end..@current_pointer]
197
197
  text.sub! /\r?\n--END COMMAND--/, ""
198
198
  @current_message.text_body = text
199
199
  @follows_text_start = nil
200
200
  end
201
-
201
+
202
202
  def add_pair_to_current_message
203
203
  @current_message[@current_key] = @current_value
204
204
  reset_key_and_value_positions
205
205
  end
206
-
206
+
207
207
  def reset_key_and_value_positions
208
208
  @current_key, @current_value, @current_key_position, @current_value_position = nil
209
209
  end
210
-
210
+
211
211
  def syntax_error_starts
212
212
  @current_syntax_error_start = @current_pointer # Adding 1 since the pointer is still set to the last successful match
213
213
  end
214
-
214
+
215
215
  def syntax_error_stops
216
216
  # Subtracting 3 from @current_pointer below for "\r\n" which separates a stanza
217
217
  offending_data = @data[@current_syntax_error_start...@current_pointer - 1]
218
218
  syntax_error_encountered offending_data
219
219
  @current_syntax_error_start = nil
220
220
  end
221
-
221
+
222
222
  def immediate_response_starts
223
223
  @immediate_response_start = @current_pointer
224
224
  end
225
-
225
+
226
226
  def immediate_response_stops
227
227
  message = @data[@immediate_response_start...(@current_pointer -1)]
228
228
  message_received ManagerInterfaceResponse.from_immediate_response(message)
229
229
  end
230
-
230
+
231
231
  ##
232
232
  # This method is used primarily in debugging.
233
233
  #
234
234
  def view_buffer(message=nil)
235
-
235
+
236
236
  message ||= "Viewing the buffer"
237
-
237
+
238
238
  buffer = @data.clone
239
239
  buffer.insert(@current_pointer, "\033[0;31m\033[1;31m^\033[0m")
240
-
240
+
241
241
  buffer.gsub!("\r", "\\\\r")
242
242
  buffer.gsub!("\n", "\\n\n")
243
-
243
+
244
244
  puts <<-INSPECTION
245
245
  VVVVVVVVVVVVVVVVVVVVVVVVVVVVV
246
246
  #### #{message}
@@ -249,37 +249,37 @@ VVVVVVVVVVVVVVVVVVVVVVVVVVVVV
249
249
  #############################
250
250
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
251
251
  INSPECTION
252
-
252
+
253
253
  end
254
254
  end
255
255
  class DelegatingAsteriskManagerInterfaceLexer < AbstractAsteriskManagerInterfaceStreamLexer
256
-
256
+
257
257
  def initialize(delegate, method_delegation_map=nil)
258
258
  super()
259
259
  @delegate = delegate
260
-
260
+
261
261
  @message_received_method = method_delegation_map && method_delegation_map.has_key?(:message_received) ?
262
262
  method_delegation_map[:message_received] : :message_received
263
-
263
+
264
264
  @error_received_method = method_delegation_map && method_delegation_map.has_key?(:error_received) ?
265
265
  method_delegation_map[:error_received] : :error_received
266
-
266
+
267
267
  @syntax_error_method = method_delegation_map && method_delegation_map.has_key?(:syntax_error_encountered) ?
268
268
  method_delegation_map[:syntax_error_encountered] : :syntax_error_encountered
269
269
  end
270
-
270
+
271
271
  def message_received(message)
272
272
  @delegate.send(@message_received_method, message)
273
273
  end
274
-
274
+
275
275
  def error_received(message)
276
276
  @delegate.send(@error_received_method, message)
277
277
  end
278
-
278
+
279
279
  def syntax_error_encountered(ignored_chunk)
280
280
  @delegate.send(@syntax_error_method, ignored_chunk)
281
281
  end
282
-
282
+
283
283
  end
284
284
  end
285
285
  end
@@ -10,7 +10,7 @@ module Adhearsion
10
10
  # Note: not all responses have an ActionID!
11
11
  #
12
12
  class ManagerInterfaceResponse
13
-
13
+
14
14
  class << self
15
15
  def from_immediate_response(text)
16
16
  returning new do |instance|
@@ -18,59 +18,59 @@ module Adhearsion
18
18
  end
19
19
  end
20
20
  end
21
-
21
+
22
22
  attr_accessor :action,
23
23
  :action_id,
24
24
  :text_body # For "Response: Follows" sections
25
25
  attr_reader :events
26
-
26
+
27
27
  def initialize
28
28
  @headers = HashWithIndifferentAccess.new
29
29
  end
30
-
30
+
31
31
  def has_text_body?
32
32
  !! @text_body
33
33
  end
34
-
34
+
35
35
  def headers
36
36
  @headers.clone
37
37
  end
38
-
38
+
39
39
  def [](arg)
40
40
  @headers[arg]
41
41
  end
42
-
42
+
43
43
  def []=(key,value)
44
44
  @headers[key] = value
45
45
  end
46
-
46
+
47
47
  end
48
-
48
+
49
49
  class ManagerInterfaceError < Exception
50
-
50
+
51
51
  attr_accessor :message
52
52
  def initialize
53
53
  @headers = HashWithIndifferentAccess.new
54
54
  end
55
-
55
+
56
56
  def [](key)
57
57
  @headers[key]
58
58
  end
59
-
59
+
60
60
  def []=(key,value)
61
61
  @headers[key] = value
62
62
  end
63
-
63
+
64
64
  end
65
-
65
+
66
66
  class ManagerInterfaceEvent < ManagerInterfaceResponse
67
-
67
+
68
68
  attr_reader :name
69
69
  def initialize(name)
70
70
  super()
71
71
  @name = name
72
72
  end
73
-
73
+
74
74
  end
75
75
  end
76
76
  end
@@ -83,5 +83,5 @@ response_follows := |*
83
83
  FollowsBody;
84
84
  crlf @{ message_received @current_message; fgoto protocol; };
85
85
  *|;
86
-
86
+
87
87
  }%%
@@ -1,9 +1,9 @@
1
1
  module Adhearsion
2
2
  class DialPlan
3
3
  class ConfirmationManager
4
-
4
+
5
5
  class << self
6
-
6
+
7
7
  def encode_hash_for_dial_macro_argument(options)
8
8
  options = options.clone
9
9
  macro_name = options.delete :macro
@@ -11,20 +11,20 @@ module Adhearsion
11
11
  encoded_options = URI.escape options.map { |key,value| "#{key}:#{value}" }.join('!')
12
12
  returning "M(#{macro_name}^#{encoded_options})" do |str|
13
13
  if str.rindex('^') != str.index('^')
14
- raise ArgumentError, "You seem to have supplied a :confirm option with a caret (^) in it!" +
14
+ raise ArgumentError, "You seem to have supplied a :confirm option with a caret (^) in it!" +
15
15
  " Please remove it. This will blow Asterisk up."
16
16
  end
17
17
  end
18
18
  end
19
-
19
+
20
20
  def handle(call)
21
21
  new(call).handle
22
22
  end
23
-
23
+
24
24
  def confirmation_call?(call)
25
25
  call.variables.has_key?(:network_script) && call.variables[:network_script].starts_with?('confirm!')
26
26
  end
27
-
27
+
28
28
  def decode_hash(encoded_hash)
29
29
  encoded_hash = encoded_hash =~ /^M\((.+)\)$/ ? $1 : encoded_hash
30
30
  encoded_hash = encoded_hash =~ /^([^:]+\^)?(.+)$/ ? $2 : encoded_hash # Remove the macro name if it's there
@@ -38,19 +38,19 @@ module Adhearsion
38
38
  end
39
39
 
40
40
  end
41
-
41
+
42
42
  attr_reader :call
43
43
  def initialize(call)
44
44
  @call = call
45
45
  extend Adhearsion::VoIP::Commands.for(call.originating_voip_platform)
46
46
  end
47
-
47
+
48
48
  def handle
49
49
  variables = self.class.decode_hash call.variables[:network_script]
50
-
50
+
51
51
  answer
52
52
  loop do
53
- response = interruptable_play(*variables[:play])
53
+ response = interruptible_play(*variables[:play])
54
54
  if response && response.to_s == variables[:key].to_s
55
55
  # Don't set a variable to pass through to dial()
56
56
  break
@@ -58,7 +58,7 @@ module Adhearsion
58
58
  next
59
59
  else
60
60
  response = wait_for_digit variables[:timeout]
61
- if response
61
+ if response
62
62
  if response.to_s == variables[:key].to_s
63
63
  # Don't set a variable to pass through to dial()
64
64
  break
@@ -72,9 +72,9 @@ module Adhearsion
72
72
  end
73
73
  end
74
74
  end
75
-
75
+
76
76
  end
77
-
77
+
78
78
  end
79
79
  end
80
80
  end