adhearsion 0.8.4 → 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +12 -0
- data/Rakefile +6 -5
- data/adhearsion.gemspec +9 -5
- data/app_generators/ahn/ahn_generator.rb +5 -0
- data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb +1 -1
- data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.rb +1 -1
- data/app_generators/ahn/templates/components/disabled/xmpp_gateway/README.markdown +3 -0
- data/app_generators/ahn/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +11 -0
- data/app_generators/ahn/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
- data/app_generators/ahn/templates/config/startup.rb +10 -1
- data/lib/adhearsion/cli.rb +7 -2
- data/lib/adhearsion/foundation/event_socket.rb +1 -1
- data/lib/adhearsion/foundation/future_resource.rb +1 -1
- data/lib/adhearsion/host_definitions.rb +1 -1
- data/lib/adhearsion/initializer.rb +21 -8
- data/lib/adhearsion/initializer/configuration.rb +44 -3
- data/lib/adhearsion/initializer/database.rb +11 -1
- data/lib/adhearsion/initializer/ldap.rb +7 -1
- data/lib/adhearsion/initializer/xmpp.rb +42 -0
- data/lib/adhearsion/version.rb +26 -2
- data/lib/adhearsion/voip/asterisk/agi_server.rb +2 -1
- data/lib/adhearsion/voip/asterisk/commands.rb +186 -85
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +147 -50
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +1 -1
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +1 -1
- data/lib/adhearsion/voip/call.rb +15 -8
- data/lib/adhearsion/voip/dial_plan.rb +21 -4
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +1 -1
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +2 -2
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +2 -2
- data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +2 -2
- data/lib/adhearsion/xmpp/connection.rb +61 -0
- data/lib/theatre/invocation.rb +1 -1
- data/lib/theatre/namespace_manager.rb +1 -1
- metadata +12 -6
- data/lib/adhearsion/foundation/global.rb +0 -1
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
0.8.5
|
2
|
+
- Added XMPP module and sample component. This allows you to easily write components which utilise a persistent XMPP connection maintained by Adhearsion
|
3
|
+
- Prefer finding the dialplan.rb entry point by the AGI request URI instead of the calling context
|
4
|
+
- Added :use_static_conf option for "meetme" to allow the use of disk-file-managed conferences
|
5
|
+
- Logging object now shared with ActiveRecord and Blather
|
6
|
+
- Fixed a longstanding bug where newlines were not sent after each AGI command
|
7
|
+
- Fixed parsing of DBGet AMI command/response
|
8
|
+
- Better shutdown handling/cleanup
|
9
|
+
- Attempt to allow the AMI socket to reconnect if connection is lost
|
10
|
+
- Improved support for Ruby 1.9
|
11
|
+
- Numerous smaller bugs fixed. See: https://adhearsion.lighthouseapp.com/projects/5871-adhearsion/milestones/76510-085
|
12
|
+
|
1
13
|
0.8.4
|
2
14
|
- Add configurable argument delimiter for talking to Asterisk. This enables Adhearsion to support Asterisk versions 1.4 (and prior) as well as 1.6 (and later).
|
3
15
|
- Fixed using ActiveRecord in Adhearsion components
|
data/Rakefile
CHANGED
@@ -3,6 +3,7 @@ ENV['RUBY_FLAGS'] = "-I#{%w(lib ext bin test).join(File::PATH_SEPARATOR)}"
|
|
3
3
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'rake/gempackagetask'
|
6
|
+
require 'rake/testtask'
|
6
7
|
|
7
8
|
begin
|
8
9
|
require 'spec/rake/spectask'
|
@@ -45,13 +46,13 @@ Rake::GemPackageTask.new(GEMSPEC).define
|
|
45
46
|
# # t.options = ['--any', '--extra', '--opts'] # optional
|
46
47
|
# end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
load file
|
52
|
-
end
|
49
|
+
Rake::TestTask.new('spec') do |t|
|
50
|
+
t.verbose = true
|
51
|
+
t.pattern = AHN_TESTS
|
53
52
|
end
|
54
53
|
|
54
|
+
task :default => :spec
|
55
|
+
|
55
56
|
desc "Check Ragel version"
|
56
57
|
task :check_ragel_version do
|
57
58
|
ragel_version_match = `ragel --version`.match(/(\d)\.(\d)+/)
|
data/adhearsion.gemspec
CHANGED
@@ -14,6 +14,9 @@ ADHEARSION_FILES = %w{
|
|
14
14
|
app_generators/ahn/templates/components/disabled/restful_rpc/README.markdown
|
15
15
|
app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb
|
16
16
|
app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb
|
17
|
+
app_generators/ahn/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb
|
18
|
+
app_generators/ahn/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml
|
19
|
+
app_generators/ahn/templates/components/disabled/xmpp_gateway/README.markdown
|
17
20
|
app_generators/ahn/templates/components/simon_game/simon_game.rb
|
18
21
|
app_generators/ahn/templates/config/startup.rb
|
19
22
|
app_generators/ahn/templates/dialplan.rb
|
@@ -38,7 +41,6 @@ ADHEARSION_FILES = %w{
|
|
38
41
|
lib/adhearsion/foundation/custom_daemonizer.rb
|
39
42
|
lib/adhearsion/foundation/event_socket.rb
|
40
43
|
lib/adhearsion/foundation/future_resource.rb
|
41
|
-
lib/adhearsion/foundation/global.rb
|
42
44
|
lib/adhearsion/foundation/metaprogramming.rb
|
43
45
|
lib/adhearsion/foundation/numeric.rb
|
44
46
|
lib/adhearsion/foundation/pseudo_guid.rb
|
@@ -55,6 +57,7 @@ ADHEARSION_FILES = %w{
|
|
55
57
|
lib/adhearsion/initializer/drb.rb
|
56
58
|
lib/adhearsion/initializer/freeswitch.rb
|
57
59
|
lib/adhearsion/initializer/rails.rb
|
60
|
+
lib/adhearsion/initializer/xmpp.rb
|
58
61
|
lib/adhearsion/logging.rb
|
59
62
|
lib/adhearsion/tasks.rb
|
60
63
|
lib/adhearsion/tasks/database.rb
|
@@ -100,6 +103,7 @@ ADHEARSION_FILES = %w{
|
|
100
103
|
lib/adhearsion/voip/menu_state_machine/matchers.rb
|
101
104
|
lib/adhearsion/voip/menu_state_machine/menu_builder.rb
|
102
105
|
lib/adhearsion/voip/menu_state_machine/menu_class.rb
|
106
|
+
lib/adhearsion/xmpp/connection.rb
|
103
107
|
lib/theatre.rb
|
104
108
|
lib/theatre/callback_definition_loader.rb
|
105
109
|
lib/theatre/guid.rb
|
@@ -113,14 +117,14 @@ ADHEARSION_FILES = %w{
|
|
113
117
|
|
114
118
|
Gem::Specification.new do |s|
|
115
119
|
s.name = "adhearsion"
|
116
|
-
s.version = "0.8.
|
120
|
+
s.version = "0.8.5"
|
117
121
|
|
118
122
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
119
|
-
s.authors = ["Jay Phillips"]
|
123
|
+
s.authors = ["Jay Phillips", "Jason Goecke", "Ben Klang"]
|
120
124
|
|
121
|
-
s.date = "
|
125
|
+
s.date = "2010-08-24"
|
122
126
|
s.description = "Adhearsion is an open-source telephony development framework"
|
123
|
-
s.email = "
|
127
|
+
s.email = "dev&Adhearsion.com"
|
124
128
|
s.executables = ["ahn", "ahnctl", "jahn"]
|
125
129
|
|
126
130
|
s.files = ADHEARSION_FILES
|
@@ -27,6 +27,10 @@ class AhnGenerator < RubiGen::Base
|
|
27
27
|
m.file *["components/simon_game/simon_game.rb"]*2
|
28
28
|
m.file *["components/ami_remote/ami_remote.rb"]*2
|
29
29
|
|
30
|
+
m.file *["components/disabled/xmpp_gateway/xmpp_gateway.rb"]*2
|
31
|
+
m.file *["components/disabled/xmpp_gateway/xmpp_gateway.yml"]*2
|
32
|
+
m.file *["components/disabled/xmpp_gateway/README.markdown"]*2
|
33
|
+
|
30
34
|
m.file *["components/disabled/stomp_gateway/stomp_gateway.rb"]*2
|
31
35
|
m.file *["components/disabled/stomp_gateway/stomp_gateway.yml"]*2
|
32
36
|
m.file *["components/disabled/stomp_gateway/README.markdown"]*2
|
@@ -83,6 +87,7 @@ EOS
|
|
83
87
|
BASEDIRS = %w(
|
84
88
|
components/simon_game
|
85
89
|
components/disabled/stomp_gateway
|
90
|
+
components/disabled/xmpp_gateway
|
86
91
|
components/disabled/sandbox
|
87
92
|
components/ami_remote
|
88
93
|
components/disabled/restful_rpc/spec
|
@@ -55,7 +55,7 @@ RESTFUL_API_HANDLER = lambda do |env|
|
|
55
55
|
rpc_object = Adhearsion::Components.component_manager.extend_object_with(Object.new, :rpc)
|
56
56
|
|
57
57
|
# TODO: set the content-type and other HTTP headers
|
58
|
-
response_object =
|
58
|
+
response_object = rpc_object.send(path, *json)
|
59
59
|
[200, {"Content-Type" => "application/json"}, response_object.to_json]
|
60
60
|
|
61
61
|
end
|
File without changes
|
@@ -27,7 +27,8 @@ Adhearsion::Configuration.configure do |config|
|
|
27
27
|
# NOTE: Pay special attention to the argument_delimiter field below:
|
28
28
|
# For Asterisk <= 1.4, use "|" (default)
|
29
29
|
# For Asterisk >= 1.6, use ","
|
30
|
-
#
|
30
|
+
# The delimiter can also be specified in Asterisk's asterisk.conf.
|
31
|
+
# This setting applies only to AGI. The AMI delimiter is auto-detected.
|
31
32
|
config.enable_asterisk :argument_delimiter => '|'
|
32
33
|
# config.asterisk.enable_ami :host => "127.0.0.1", :username => "admin", :password => "password", :events => true
|
33
34
|
|
@@ -44,6 +45,8 @@ Adhearsion::Configuration.configure do |config|
|
|
44
45
|
|
45
46
|
# Configure a database to use ActiveRecord-backed models. See ActiveRecord::Base.establish_connection
|
46
47
|
# for the appropriate settings here.
|
48
|
+
# You can also override the default log destination by supplying an alternate
|
49
|
+
# logging object with :logger. The default is ahn_log.db.
|
47
50
|
# config.enable_database :adapter => 'mysql',
|
48
51
|
# :username => 'joe',
|
49
52
|
# :password => 'secret',
|
@@ -59,6 +62,12 @@ Adhearsion::Configuration.configure do |config|
|
|
59
62
|
# :password => 'password12345',
|
60
63
|
# :allow_anonymous => false,
|
61
64
|
# :try_sasl => false
|
65
|
+
|
66
|
+
# Configure XMPP call controller
|
67
|
+
# config.enable_xmpp :jid => 'active-calls.xmpp.example.com',
|
68
|
+
# :password => 'passwd',
|
69
|
+
# :server => 'xmpp.example.com',
|
70
|
+
# :port => 5347
|
62
71
|
|
63
72
|
end
|
64
73
|
|
data/lib/adhearsion/cli.rb
CHANGED
@@ -143,12 +143,17 @@ USAGE
|
|
143
143
|
app_path = PathString.from_application_subdirectory Dir.pwd
|
144
144
|
if app_path
|
145
145
|
disabled_component_path = File.join app_path, "components", "disabled", name
|
146
|
+
disabled_components_path = File.join app_path, "components", "disabled"
|
146
147
|
enabled_component_path = File.join app_path, "components", name
|
147
148
|
if File.directory? disabled_component_path
|
148
149
|
FileUtils.mv disabled_component_path, enabled_component_path
|
149
150
|
puts "Enabled component #{name}"
|
150
|
-
|
151
|
+
elsif File.directory? enabled_component_path
|
152
|
+
raise ComponentError.new("This component is already enabled.")
|
153
|
+
elsif !File.directory? disabled_components_path
|
151
154
|
raise ComponentError.new("There is no components/disabled directory!")
|
155
|
+
else
|
156
|
+
raise ComponentError.new("The requested component was not found.")
|
152
157
|
end
|
153
158
|
else
|
154
159
|
raise PathInvalid.new(Dir.pwd)
|
@@ -196,7 +201,7 @@ USAGE
|
|
196
201
|
|
197
202
|
end
|
198
203
|
|
199
|
-
class CLIException <
|
204
|
+
class CLIException < StandardError; end
|
200
205
|
|
201
206
|
class UnknownCommand < CLIException
|
202
207
|
def initialize(cmd)
|
@@ -1,12 +1,22 @@
|
|
1
1
|
module Adhearsion
|
2
2
|
|
3
|
+
mattr_accessor :status
|
4
|
+
|
3
5
|
class << self
|
4
6
|
|
5
7
|
##
|
6
8
|
# Shuts down the framework.
|
7
9
|
#
|
8
10
|
def shutdown!
|
11
|
+
if self.status == :stopping
|
12
|
+
# This is the second shutdown request we've received while attempting
|
13
|
+
# to shut down gracefully. At this point, let's pull the plug...
|
14
|
+
ahn_log.warning "Shutting down immediately at #{Time.now}"
|
15
|
+
exit
|
16
|
+
end
|
9
17
|
ahn_log "Shutting down gracefully at #{Time.now}."
|
18
|
+
self.status = :stopping
|
19
|
+
Events.trigger_immediately :shutdown
|
10
20
|
Events.stop!
|
11
21
|
exit
|
12
22
|
end
|
@@ -115,7 +125,7 @@ module Adhearsion
|
|
115
125
|
def initialize(path=nil, options={})
|
116
126
|
@@started = true
|
117
127
|
@path = path
|
118
|
-
@daemon = options[:daemon]
|
128
|
+
@daemon = options[:daemon] || ENV['DAEMON']
|
119
129
|
@pid_file = options[:pid_file].nil? ? ENV['PID_FILE'] : options[:pid_file]
|
120
130
|
@loaded_init_files = options[:loaded_init_files]
|
121
131
|
end
|
@@ -123,6 +133,8 @@ module Adhearsion
|
|
123
133
|
def start
|
124
134
|
self.class.ahn_root = path
|
125
135
|
|
136
|
+
Adhearsion.status = :starting
|
137
|
+
|
126
138
|
resolve_pid_file_path
|
127
139
|
resolve_log_file_path
|
128
140
|
daemonize! if should_daemonize?
|
@@ -140,6 +152,7 @@ module Adhearsion
|
|
140
152
|
init_events_file
|
141
153
|
|
142
154
|
ahn_log "Adhearsion initialized!"
|
155
|
+
Adhearsion.status = :running
|
143
156
|
|
144
157
|
trigger_after_initialized_hooks
|
145
158
|
join_important_threads
|
@@ -172,9 +185,7 @@ module Adhearsion
|
|
172
185
|
def catch_termination_signal
|
173
186
|
%w'INT TERM'.each do |process_signal|
|
174
187
|
trap process_signal do
|
175
|
-
|
176
|
-
Events.trigger_immediately :shutdown
|
177
|
-
exit
|
188
|
+
Adhearsion.shutdown!
|
178
189
|
end
|
179
190
|
end
|
180
191
|
end
|
@@ -273,11 +284,13 @@ Adhearsion will abort until you fix this. Sorry for the incovenience.
|
|
273
284
|
require 'adhearsion/initializer/asterisk.rb'
|
274
285
|
require 'adhearsion/initializer/drb.rb'
|
275
286
|
require 'adhearsion/initializer/rails.rb'
|
287
|
+
require 'adhearsion/initializer/xmpp.rb'
|
276
288
|
# require 'adhearsion/initializer/freeswitch.rb'
|
277
289
|
|
278
290
|
AsteriskInitializer.start if AHN_CONFIG.asterisk_enabled?
|
279
291
|
DrbInitializer.start if AHN_CONFIG.drb_enabled?
|
280
292
|
RailsInitializer.start if AHN_CONFIG.rails_enabled?
|
293
|
+
XMPPInitializer.start if AHN_CONFIG.xmpp_enabled?
|
281
294
|
# FreeswitchInitializer.start if AHN_CONFIG.freeswitch_enabled?
|
282
295
|
|
283
296
|
end
|
@@ -303,7 +316,7 @@ Adhearsion will abort until you fix this. Sorry for the incovenience.
|
|
303
316
|
end
|
304
317
|
|
305
318
|
def should_daemonize?
|
306
|
-
@daemon
|
319
|
+
@daemon
|
307
320
|
end
|
308
321
|
|
309
322
|
def daemonize!
|
@@ -324,8 +337,8 @@ Adhearsion will abort until you fix this. Sorry for the incovenience.
|
|
324
337
|
Logging::DefaultAdhearsionLogger.redefine_outputters
|
325
338
|
end
|
326
339
|
|
327
|
-
def create_pid_file
|
328
|
-
if
|
340
|
+
def create_pid_file
|
341
|
+
if pid_file
|
329
342
|
File.open pid_file, 'w' do |file|
|
330
343
|
file.puts Process.pid
|
331
344
|
end
|
@@ -377,6 +390,6 @@ Adhearsion will abort until you fix this. Sorry for the incovenience.
|
|
377
390
|
end
|
378
391
|
end
|
379
392
|
|
380
|
-
class InitializationFailedError <
|
393
|
+
class InitializationFailedError < StandardError; end
|
381
394
|
end
|
382
395
|
end
|
@@ -129,8 +129,8 @@ module Adhearsion
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def initialize(overrides = {})
|
132
|
-
@listening_port = self.class.default_listening_port
|
133
|
-
@listening_host = self.class.default_listening_host
|
132
|
+
@listening_port = overrides.has_key?(:port) ? overrides[:port] : self.class.default_listening_port
|
133
|
+
@listening_host = overrides.has_key?(:host) ? overrides[:host] : self.class.default_listening_host
|
134
134
|
super
|
135
135
|
end
|
136
136
|
end
|
@@ -144,8 +144,10 @@ module Adhearsion
|
|
144
144
|
4573
|
145
145
|
end
|
146
146
|
|
147
|
+
# Keep Asterisk 1.4 (and prior) as the default to protect upgraders
|
148
|
+
# This setting only applies to AGI. AMI delimiters are always
|
149
|
+
# auto-detected.
|
147
150
|
def default_argument_delimiter
|
148
|
-
# Keep Asterisk 1.4 (and prior) as the default to protect upgraders
|
149
151
|
'|'
|
150
152
|
end
|
151
153
|
end
|
@@ -265,5 +267,44 @@ module Adhearsion
|
|
265
267
|
end
|
266
268
|
add_configuration_for :Rails
|
267
269
|
|
270
|
+
class XMPPConfiguration < AbstractConfiguration
|
271
|
+
|
272
|
+
attr_accessor :jid, :password, :server, :port
|
273
|
+
def initialize(options)
|
274
|
+
jid, password, server, port = check_options options
|
275
|
+
@jid = jid
|
276
|
+
@password = password
|
277
|
+
@server = server
|
278
|
+
@port = port
|
279
|
+
end
|
280
|
+
|
281
|
+
class << self
|
282
|
+
def default_port
|
283
|
+
5222
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
private
|
288
|
+
|
289
|
+
def check_options(options)
|
290
|
+
options = options.clone
|
291
|
+
jid = options.delete :jid
|
292
|
+
password = options.delete :password
|
293
|
+
server = options.delete :server
|
294
|
+
port = options.delete :port
|
295
|
+
raise ArgumentError, "Unrecognied argument(s) #{options.keys.to_sentence} in XMPP initializer!" unless options.size.zero?
|
296
|
+
raise ArgumentError, "Must supply a :jid argument to the XMPP initializer!" unless jid
|
297
|
+
raise ArgumentError, "Must supply a :password argument to the XMPP initializer!" unless password
|
298
|
+
if server
|
299
|
+
port ||= self.class.default_port
|
300
|
+
else
|
301
|
+
raise ArgumentError, "Must supply a :server argument as well as :port to the XMPP initializer!" if port
|
302
|
+
end
|
303
|
+
[jid, password, server, port]
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
add_configuration_for :XMPP
|
308
|
+
|
268
309
|
end
|
269
310
|
end
|
@@ -14,6 +14,10 @@ module Adhearsion
|
|
14
14
|
# You may need to uncomment the following line for older versions of ActiveRecord
|
15
15
|
# ActiveRecord::Base.allow_concurrency = true
|
16
16
|
establish_connection
|
17
|
+
ActiveRecord::Base.logger =
|
18
|
+
@@config.connection_options.has_key?(:logger) ?
|
19
|
+
@@config.connection_options[:logger] :
|
20
|
+
ahn_log.db
|
17
21
|
create_call_hook_for_connection_cleanup
|
18
22
|
end
|
19
23
|
|
@@ -30,7 +34,13 @@ module Adhearsion
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def require_dependencies
|
33
|
-
|
37
|
+
begin
|
38
|
+
require 'active_record'
|
39
|
+
rescue LoadError
|
40
|
+
ahn_log.fatal "Database support requires the \"activerecord\" gem."
|
41
|
+
# Silence the abort so we don't get an ugly backtrace
|
42
|
+
abort ""
|
43
|
+
end
|
34
44
|
end
|
35
45
|
|
36
46
|
def require_models
|
@@ -31,7 +31,13 @@ module Adhearsion
|
|
31
31
|
#end
|
32
32
|
|
33
33
|
def require_dependencies
|
34
|
-
|
34
|
+
begin
|
35
|
+
require 'active_ldap'
|
36
|
+
rescue LoadError
|
37
|
+
ahn_log.fatal "LDAP support requires the \"activeldap\" gem."
|
38
|
+
# Silence the abort so we don't get an ugly backtrace
|
39
|
+
abort ""
|
40
|
+
end
|
35
41
|
end
|
36
42
|
|
37
43
|
def require_models
|