adhearsion 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +11 -2
- data/EVENTS +1 -1
- data/Rakefile +4 -4
- data/adhearsion.gemspec +8 -4
- data/app_generators/ahn/USAGE +3 -3
- data/app_generators/ahn/ahn_generator.rb +11 -11
- data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +3 -3
- data/app_generators/ahn/templates/components/disabled/restful_rpc/example-client.rb +6 -6
- data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb +16 -16
- data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +42 -42
- data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.rb +11 -11
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +1 -1
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +6 -6
- data/app_generators/ahn/templates/components/simon_game/simon_game.rb +4 -4
- data/app_generators/ahn/templates/config/startup.rb +31 -16
- data/bin/ahn +3 -3
- data/bin/ahnctl +8 -8
- data/bin/jahn +3 -3
- data/examples/asterisk_manager_interface/standalone.rb +2 -2
- data/lib/adhearsion.rb +4 -2
- data/lib/adhearsion/cli.rb +31 -31
- data/lib/adhearsion/component_manager.rb +39 -39
- data/lib/adhearsion/component_manager/component_tester.rb +14 -14
- data/lib/adhearsion/component_manager/spec_framework.rb +1 -1
- data/lib/adhearsion/events_support.rb +12 -12
- data/lib/adhearsion/foundation/blank_slate.rb +1 -1
- data/lib/adhearsion/foundation/custom_daemonizer.rb +2 -2
- data/lib/adhearsion/foundation/event_socket.rb +26 -26
- data/lib/adhearsion/foundation/future_resource.rb +6 -6
- data/lib/adhearsion/foundation/metaprogramming.rb +2 -2
- data/lib/adhearsion/foundation/numeric.rb +3 -3
- data/lib/adhearsion/foundation/relationship_properties.rb +7 -7
- data/lib/adhearsion/foundation/string.rb +8 -8
- data/lib/adhearsion/foundation/synchronized_hash.rb +8 -8
- data/lib/adhearsion/host_definitions.rb +16 -16
- data/lib/adhearsion/initializer.rb +74 -65
- data/lib/adhearsion/initializer/asterisk.rb +15 -9
- data/lib/adhearsion/initializer/configuration.rb +54 -39
- data/lib/adhearsion/initializer/database.rb +4 -4
- data/lib/adhearsion/initializer/drb.rb +6 -6
- data/lib/adhearsion/initializer/freeswitch.rb +1 -1
- data/lib/adhearsion/initializer/ldap.rb +51 -0
- data/lib/adhearsion/initializer/rails.rb +8 -8
- data/lib/adhearsion/logging.rb +16 -16
- data/lib/adhearsion/tasks/deprecations.rb +12 -12
- data/lib/adhearsion/tasks/generating.rb +2 -2
- data/lib/adhearsion/tasks/testing.rb +7 -7
- data/lib/adhearsion/version.rb +1 -1
- data/lib/adhearsion/voip/asterisk/agi_server.rb +44 -14
- data/lib/adhearsion/voip/asterisk/commands.rb +281 -237
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +8 -8
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +14 -14
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +16 -16
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +39 -39
- data/lib/adhearsion/voip/asterisk/config_manager.rb +13 -13
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +91 -87
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +739 -739
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +60 -60
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +16 -16
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +1 -1
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +13 -13
- data/lib/adhearsion/voip/asterisk/super_manager.rb +3 -3
- data/lib/adhearsion/voip/call.rb +101 -64
- data/lib/adhearsion/voip/call_routing.rb +9 -9
- data/lib/adhearsion/voip/constants.rb +7 -7
- data/lib/adhearsion/voip/conveniences.rb +1 -1
- data/lib/adhearsion/voip/dial_plan.rb +42 -40
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +27 -27
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +1 -1
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +6 -6
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +17 -17
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +7 -7
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +2 -2
- data/lib/adhearsion/voip/dsl/numerical_string.rb +3 -3
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +7 -7
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +1 -1
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +20 -20
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +5 -5
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +33 -33
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +1 -1
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +2 -2
- data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +9 -9
- data/lib/theatre.rb +18 -18
- data/lib/theatre/callback_definition_loader.rb +17 -17
- data/lib/theatre/guid.rb +6 -6
- data/lib/theatre/invocation.rb +19 -19
- data/lib/theatre/namespace_manager.rb +28 -28
- 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
|
@@ -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 =
|
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
|