sevenscale-adhearsion 0.7.1000
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.
- data/CHANGELOG +3 -0
- data/LICENSE +456 -0
- data/Manifest.txt +149 -0
- data/README.txt +6 -0
- data/Rakefile +48 -0
- data/ahn_generators/component/USAGE +5 -0
- data/ahn_generators/component/component_generator.rb +57 -0
- data/ahn_generators/component/templates/configuration.rb +0 -0
- data/ahn_generators/component/templates/lib/lib.rb.erb +3 -0
- data/ahn_generators/component/templates/test/test.rb.erb +12 -0
- data/ahn_generators/component/templates/test/test_helper.rb +14 -0
- data/app_generators/ahn/USAGE +5 -0
- data/app_generators/ahn/ahn_generator.rb +76 -0
- data/app_generators/ahn/templates/.ahnrc +12 -0
- data/app_generators/ahn/templates/README +8 -0
- data/app_generators/ahn/templates/Rakefile +3 -0
- data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
- data/app_generators/ahn/templates/components/simon_game/lib/simon_game.rb +61 -0
- data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +14 -0
- data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +31 -0
- data/app_generators/ahn/templates/config/startup.rb +53 -0
- data/app_generators/ahn/templates/dialplan.rb +4 -0
- data/bin/ahn +28 -0
- data/bin/ahnctl +68 -0
- data/bin/jahn +32 -0
- data/lib/adhearsion/blank_slate.rb +5 -0
- data/lib/adhearsion/cli.rb +106 -0
- data/lib/adhearsion/component_manager.rb +277 -0
- data/lib/adhearsion/core_extensions/all.rb +9 -0
- data/lib/adhearsion/core_extensions/array.rb +0 -0
- data/lib/adhearsion/core_extensions/custom_daemonizer.rb +45 -0
- data/lib/adhearsion/core_extensions/global.rb +1 -0
- data/lib/adhearsion/core_extensions/guid.rb +5 -0
- data/lib/adhearsion/core_extensions/hash.rb +0 -0
- data/lib/adhearsion/core_extensions/metaprogramming.rb +17 -0
- data/lib/adhearsion/core_extensions/numeric.rb +4 -0
- data/lib/adhearsion/core_extensions/proc.rb +0 -0
- data/lib/adhearsion/core_extensions/pseudo_uuid.rb +11 -0
- data/lib/adhearsion/core_extensions/publishable.rb +73 -0
- data/lib/adhearsion/core_extensions/relationship_properties.rb +40 -0
- data/lib/adhearsion/core_extensions/string.rb +26 -0
- data/lib/adhearsion/core_extensions/thread.rb +13 -0
- data/lib/adhearsion/core_extensions/thread_safety.rb +7 -0
- data/lib/adhearsion/core_extensions/time.rb +0 -0
- data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/rest_gateway.rb +9 -0
- data/lib/adhearsion/distributed/gateways/soap_gateway.rb +9 -0
- data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +9 -0
- data/lib/adhearsion/distributed/peer_finder.rb +0 -0
- data/lib/adhearsion/distributed/remote_cli.rb +0 -0
- data/lib/adhearsion/hooks.rb +57 -0
- data/lib/adhearsion/host_definitions.rb +63 -0
- data/lib/adhearsion/initializer/asterisk.rb +59 -0
- data/lib/adhearsion/initializer/configuration.rb +202 -0
- data/lib/adhearsion/initializer/database.rb +92 -0
- data/lib/adhearsion/initializer/drb.rb +25 -0
- data/lib/adhearsion/initializer/freeswitch.rb +22 -0
- data/lib/adhearsion/initializer/paths.rb +55 -0
- data/lib/adhearsion/initializer/rails.rb +40 -0
- data/lib/adhearsion/initializer.rb +217 -0
- data/lib/adhearsion/logging.rb +92 -0
- data/lib/adhearsion/services/scheduler.rb +5 -0
- data/lib/adhearsion/tasks/database.rb +5 -0
- data/lib/adhearsion/tasks/generating.rb +20 -0
- data/lib/adhearsion/tasks/lint.rb +4 -0
- data/lib/adhearsion/tasks/testing.rb +37 -0
- data/lib/adhearsion/tasks.rb +15 -0
- data/lib/adhearsion/version.rb +9 -0
- data/lib/adhearsion/voip/asterisk/agi_server.rb +78 -0
- data/lib/adhearsion/voip/asterisk/ami/actions.rb +238 -0
- data/lib/adhearsion/voip/asterisk/ami/machine.rb +871 -0
- data/lib/adhearsion/voip/asterisk/ami/machine.rl +109 -0
- data/lib/adhearsion/voip/asterisk/ami/parser.rb +262 -0
- data/lib/adhearsion/voip/asterisk/ami.rb +147 -0
- data/lib/adhearsion/voip/asterisk/commands.rb +1186 -0
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
- data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
- data/lib/adhearsion/voip/asterisk.rb +4 -0
- data/lib/adhearsion/voip/call.rb +402 -0
- data/lib/adhearsion/voip/call_routing.rb +64 -0
- data/lib/adhearsion/voip/commands.rb +9 -0
- data/lib/adhearsion/voip/constants.rb +39 -0
- data/lib/adhearsion/voip/conveniences.rb +18 -0
- data/lib/adhearsion/voip/dial_plan.rb +205 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +75 -0
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
- data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -0
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
- data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
- data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
- data/lib/adhearsion.rb +31 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/fixtures/dialplan.rb +3 -0
- data/spec/initializer/test_configuration.rb +267 -0
- data/spec/initializer/test_loading.rb +162 -0
- data/spec/initializer/test_paths.rb +43 -0
- data/spec/silence.rb +10 -0
- data/spec/test_ahn_command.rb +149 -0
- data/spec/test_code_quality.rb +87 -0
- data/spec/test_component_manager.rb +97 -0
- data/spec/test_constants.rb +8 -0
- data/spec/test_drb.rb +104 -0
- data/spec/test_helper.rb +94 -0
- data/spec/test_hooks.rb +37 -0
- data/spec/test_host_definitions.rb +79 -0
- data/spec/test_initialization.rb +105 -0
- data/spec/test_logging.rb +80 -0
- data/spec/test_relationship_properties.rb +54 -0
- data/spec/voip/asterisk/ami_response_definitions.rb +23 -0
- data/spec/voip/asterisk/config_file_generators/test_agents.rb +253 -0
- data/spec/voip/asterisk/config_file_generators/test_queues.rb +325 -0
- data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +306 -0
- data/spec/voip/asterisk/menu_command/test_calculated_match.rb +111 -0
- data/spec/voip/asterisk/menu_command/test_matchers.rb +98 -0
- data/spec/voip/asterisk/mock_ami_server.rb +176 -0
- data/spec/voip/asterisk/test_agi_server.rb +453 -0
- data/spec/voip/asterisk/test_ami.rb +227 -0
- data/spec/voip/asterisk/test_commands.rb +2006 -0
- data/spec/voip/asterisk/test_config_manager.rb +129 -0
- data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
- data/spec/voip/dsl/test_dialing_dsl.rb +268 -0
- data/spec/voip/dsl/test_dispatcher.rb +82 -0
- data/spec/voip/dsl/test_parser.rb +87 -0
- data/spec/voip/freeswitch/test_basic_connection_manager.rb +39 -0
- data/spec/voip/freeswitch/test_inbound_connection_manager.rb +39 -0
- data/spec/voip/freeswitch/test_oes_server.rb +9 -0
- data/spec/voip/test_call_routing.rb +127 -0
- data/spec/voip/test_dialplan_manager.rb +372 -0
- data/spec/voip/test_numerical_string.rb +48 -0
- data/spec/voip/test_phone_number.rb +36 -0
- data/test/test_ahn_generator.rb +59 -0
- data/test/test_component_generator.rb +52 -0
- data/test/test_generator_helper.rb +20 -0
- metadata +254 -0
@@ -0,0 +1,238 @@
|
|
1
|
+
module Adhearsion
|
2
|
+
module VoIP
|
3
|
+
module Asterisk
|
4
|
+
class AMI
|
5
|
+
module Actions
|
6
|
+
class Action
|
7
|
+
@@subclasses = []
|
8
|
+
@@actions = {}
|
9
|
+
|
10
|
+
attr_accessor :action
|
11
|
+
attr_accessor :action_id
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Return a new instance of the command. Make sure to return an instance
|
15
|
+
# of the command-specific subclass if it exists.
|
16
|
+
def build(name, hash, &block)
|
17
|
+
name = name.to_s
|
18
|
+
entry = @@subclasses.find { |klass| klass.downcase == name.downcase }
|
19
|
+
klass = entry ? Actions.const_get("#{entry}Action") : self
|
20
|
+
obj = klass.new(name, hash, &block)
|
21
|
+
self[obj.action_id] = obj
|
22
|
+
end
|
23
|
+
|
24
|
+
# Keep a list of the subclasses.
|
25
|
+
def inherited(klass)
|
26
|
+
@@subclasses << klass.to_s.split("::").last.match(/(.*?)Action/)[1]
|
27
|
+
end
|
28
|
+
|
29
|
+
def [](key)
|
30
|
+
@@actions[key]
|
31
|
+
end
|
32
|
+
|
33
|
+
def []=(key, action)
|
34
|
+
@@actions[key] = action
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(name, hash, &block)
|
39
|
+
@action = name.downcase
|
40
|
+
@action_id = __action_id
|
41
|
+
@arguments = {}
|
42
|
+
@packets = []
|
43
|
+
@sync_complete = false
|
44
|
+
@error = nil
|
45
|
+
|
46
|
+
# Normalize the keys
|
47
|
+
hash.each_pair { |k,v| @arguments[k.to_s.downcase] = v }
|
48
|
+
|
49
|
+
if block and not async?
|
50
|
+
raise RuntimeError, "Cannot specify completion callback for synchronous command"
|
51
|
+
end
|
52
|
+
@async_completion_callback = block
|
53
|
+
end
|
54
|
+
|
55
|
+
def <<(packet)
|
56
|
+
if packet.error?
|
57
|
+
@error = packet.message
|
58
|
+
complete_sync!
|
59
|
+
end
|
60
|
+
|
61
|
+
# We don't keep every packet, just the important ones.
|
62
|
+
@packets << packet if keep?(packet)
|
63
|
+
|
64
|
+
# Check if the synchronous portion of the action is done.
|
65
|
+
if completed_by?(packet)
|
66
|
+
# The synchronous portion is done.
|
67
|
+
complete_sync!
|
68
|
+
|
69
|
+
# We're totally done if it is not asynchronous.
|
70
|
+
complete! if not async?
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check if this is an asynchronous action, and we have received the last event
|
74
|
+
complete_async! if completed_by_async?(packet)
|
75
|
+
end
|
76
|
+
|
77
|
+
def done?
|
78
|
+
@sync_complete
|
79
|
+
end
|
80
|
+
|
81
|
+
def packets!
|
82
|
+
packets, @packets = @packets, []
|
83
|
+
packets.inject([]) do |arr, pkt|
|
84
|
+
pkt = pkt.body.inject({}) do |hash, (k, v)|
|
85
|
+
hash[k] = v
|
86
|
+
hash
|
87
|
+
end
|
88
|
+
arr << pkt if not pkt.blank?
|
89
|
+
arr
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def check_error!
|
94
|
+
raise ActionError, @error if @error
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return true if this is an 'immediate' command, i.e., it returns raw
|
98
|
+
# results synchronously without a response header.
|
99
|
+
# Don't bother doing this in subclasses. It is easy enough.
|
100
|
+
def immediate?
|
101
|
+
%w(iaxpeers queues).include? @action
|
102
|
+
end
|
103
|
+
|
104
|
+
# Return true if this action will return matching events that we will wait on.
|
105
|
+
def waits_for_events?
|
106
|
+
follows? or %w(dbget).include? @action
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return true if this action returns matching events that we will not wait on,
|
110
|
+
# but can access at a later time.
|
111
|
+
def async?
|
112
|
+
false
|
113
|
+
end
|
114
|
+
|
115
|
+
# Actions of the form "Response: <Action> results will follow"
|
116
|
+
def follows?
|
117
|
+
%w(parkedcalls queuestatus agents status sippeers zapshowchannels).include? @action
|
118
|
+
end
|
119
|
+
|
120
|
+
# Virtually all commands return a response. There is at least one
|
121
|
+
# exception, handled with a command-specific subclass.
|
122
|
+
def has_response?
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
# Return true if this packet completes the command, i.e., there is
|
127
|
+
# no more synchronous response data to receive for this command.
|
128
|
+
def completed_by?(packet)
|
129
|
+
return true if not waits_for_events?
|
130
|
+
return false if not packet.is_event?
|
131
|
+
packet.event.downcase == "#{@action}complete"
|
132
|
+
end
|
133
|
+
|
134
|
+
# Return true if this packet completes the matching asynchronous
|
135
|
+
# events for this command.
|
136
|
+
def completed_by_async?(packet)
|
137
|
+
return false if not async?
|
138
|
+
return false if not packet.is_event?
|
139
|
+
statuses = %w(success failure).collect { |status| "#{@action}#{status}" }
|
140
|
+
statuses.include?(packet.event.downcase)
|
141
|
+
end
|
142
|
+
|
143
|
+
def complete_sync!
|
144
|
+
@sync_complete = true
|
145
|
+
end
|
146
|
+
|
147
|
+
def complete_async!
|
148
|
+
@async_completion_callback.call(self.packets!) if @async_completion_callback
|
149
|
+
complete!
|
150
|
+
end
|
151
|
+
|
152
|
+
def complete!
|
153
|
+
Action[@action_id] = nil
|
154
|
+
end
|
155
|
+
|
156
|
+
# Return true if the packet should be included in the response. Raw and
|
157
|
+
# synchronous responses are kept. Some event responses are rejected.
|
158
|
+
def keep?(packet)
|
159
|
+
return true if not waits_for_events?
|
160
|
+
return false if not packet.is_event?
|
161
|
+
return keep_event?(packet)
|
162
|
+
end
|
163
|
+
|
164
|
+
# By default, we keep any event packet, unless it is the completion
|
165
|
+
# packet for a 'follows' command. These are just marker packets that
|
166
|
+
# signify the end of the event stream for the response.
|
167
|
+
# TODO: They do contain a count of the events generated, which perhaps
|
168
|
+
# we want to verify matches the number we think we have received?
|
169
|
+
def keep_event?(packet)
|
170
|
+
return false if (follows? and completed_by?(packet))
|
171
|
+
true
|
172
|
+
end
|
173
|
+
|
174
|
+
def to_s
|
175
|
+
__args_to_str
|
176
|
+
end
|
177
|
+
|
178
|
+
private
|
179
|
+
|
180
|
+
# Immediate commands do not return response headers, so there is no
|
181
|
+
# chance (or need) to get an action id. We'll make those packets
|
182
|
+
# action ids to be 0 artificially.
|
183
|
+
def __action_id
|
184
|
+
immediate? ? 0 : Time.now.to_f.to_s
|
185
|
+
end
|
186
|
+
|
187
|
+
def __args_to_str
|
188
|
+
action = ""
|
189
|
+
action << "action: #{@action}\r\n"
|
190
|
+
action << "actionid: #{@action_id}\r\n"
|
191
|
+
@arguments.keys.sort { |a,b| a.to_s <=> b.to_s }.each { |k| action << "#{k}: #{@arguments[k]}\r\n" }
|
192
|
+
action << "\r\n"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class OriginateAction < Action
|
197
|
+
# Return true if this action will return events, i.e. it is asynchronous.
|
198
|
+
# This is controlled by the 'Async' argument to the command.
|
199
|
+
def async?
|
200
|
+
@arguments['async'] == true
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
class DBGetAction < Action
|
205
|
+
# Needed only because this asynchronous response (when the
|
206
|
+
# command succeeds) does not return a response with the
|
207
|
+
# name "DBGetComplete".
|
208
|
+
def completed_by?(packet)
|
209
|
+
return true if not waits_for_events?
|
210
|
+
return false if not packet.is_event?
|
211
|
+
packet.event == "DBGetResponse"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
class SIPpeersAction < Action
|
216
|
+
# Sigh. The only reason for this is that the naming
|
217
|
+
# convention differs.
|
218
|
+
def completed_by?(packet)
|
219
|
+
return true if not waits_for_events?
|
220
|
+
return false if not packet.is_event?
|
221
|
+
packet.event == "PeerlistComplete"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class EventsAction < Action
|
226
|
+
# Again, this is a command that is subclassed due to interface
|
227
|
+
# inconsistency. If the command turns on events with the mask
|
228
|
+
# of "On", there is no response. If it is "Off" or set on for
|
229
|
+
# specific events, there is a reponse. Ugly.
|
230
|
+
def has_response?
|
231
|
+
@arguments['eventmask'] !~ /^on$/i
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|