adhearsion 2.0.0.rc5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/CHANGELOG.md +28 -126
- data/LICENSE +20 -456
- data/README.markdown +20 -29
- data/adhearsion.gemspec +22 -31
- data/lib/adhearsion.rb +5 -2
- data/lib/adhearsion/call.rb +57 -20
- data/lib/adhearsion/call_controller.rb +83 -13
- data/lib/adhearsion/call_controller/dial.rb +35 -20
- data/lib/adhearsion/call_controller/input.rb +20 -15
- data/lib/adhearsion/call_controller/menu_dsl.rb +1 -0
- data/lib/adhearsion/call_controller/output.rb +53 -42
- data/lib/adhearsion/call_controller/record.rb +3 -3
- data/lib/adhearsion/call_controller/utility.rb +11 -5
- data/lib/adhearsion/cli_commands.rb +2 -1
- data/lib/adhearsion/generators.rb +1 -1
- data/lib/adhearsion/generators/app/templates/README.md +4 -2
- data/lib/adhearsion/generators/plugin/templates/lib/plugin-template.rb.tt +4 -5
- data/lib/adhearsion/linux_proc_name.rb +2 -2
- data/lib/adhearsion/version.rb +2 -2
- data/spec/adhearsion/call_controller/output_spec.rb +10 -12
- metadata +112 -141
data/README.markdown
CHANGED
@@ -1,24 +1,21 @@
|
|
1
|
-
Adhearsion
|
2
|
-
===========
|
1
|
+
# Adhearsion
|
3
2
|
|
4
3
|
Adhearsion is an open-source voice application development framework. Adhearsion users write applications atop the framework with Ruby and **call into their code**.
|
5
4
|
|
6
5
|
Adhearsion rests above a lower-level telephony platform, for example [Asterisk](http://asterisk.org) or [Voxeo PRISM](http://voxeolabs.com/prism/), and provides a framework for integrating with various resources, such as SQL, LDAP and XMPP (Jabber).
|
7
6
|
|
8
|
-
Features
|
9
|
-
--------
|
7
|
+
## Features
|
10
8
|
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
16
|
-
*
|
17
|
-
*
|
18
|
-
*
|
9
|
+
* Simple Ruby code
|
10
|
+
* Flexible CallControllers to handle calls
|
11
|
+
* High-level media handling constructs
|
12
|
+
* Simple interaction between calls
|
13
|
+
* Self-documenting configuration engine
|
14
|
+
* Support for plugins and other code reuse
|
15
|
+
* Integration with databases, web APIs, etc
|
16
|
+
* Event monitoring, async communication
|
19
17
|
|
20
|
-
Requirements
|
21
|
-
------------
|
18
|
+
## Requirements
|
22
19
|
|
23
20
|
* Ruby 1.9.2+ or JRuby 1.6.7+
|
24
21
|
* A VoIP platform:
|
@@ -26,13 +23,11 @@ Requirements
|
|
26
23
|
* Prism 11+ with rayo-server
|
27
24
|
* An interest in building cool new things
|
28
25
|
|
29
|
-
Install
|
30
|
-
-------
|
26
|
+
## Install
|
31
27
|
|
32
28
|
`gem install adhearsion`
|
33
29
|
|
34
|
-
Examples
|
35
|
-
--------
|
30
|
+
## Examples
|
36
31
|
|
37
32
|
An Adhearsion application can be as simple as this:
|
38
33
|
|
@@ -45,17 +40,13 @@ hangup
|
|
45
40
|
|
46
41
|
For more examples, check out [the website](http://adhearsion.com/examples).
|
47
42
|
|
48
|
-
Documentation
|
49
|
-
=============
|
43
|
+
## Documentation
|
50
44
|
|
51
45
|
Visit [Adhearsion's website](http://adhearsion.com) for code examples and more information about the project. Also checkout the [Adhearsion wiki on Github](http://github.com/adhearsion/adhearsion/wiki) for community documentation.
|
52
46
|
|
53
47
|
If you're having trouble, you may want to try asking your question on the IRC channel (#adhearsion on irc.freenode.net), [mailing list](http://groups.google.com/group/adhearsion) or, if you've found a bug, report it on the [bug tracker](https://github.com/adhearsion/adhearsion/issues).
|
54
48
|
|
55
|
-
Author
|
56
|
-
------
|
57
|
-
|
58
|
-
Original author: [Jay Phillips](https://github.com/jicksta)
|
49
|
+
## Author
|
59
50
|
|
60
51
|
Core team:
|
61
52
|
|
@@ -65,13 +56,13 @@ Core team:
|
|
65
56
|
|
66
57
|
Contributors: https://github.com/adhearsion/adhearsion/contributors
|
67
58
|
|
68
|
-
|
69
|
-
|
59
|
+
Original author: [Jay Phillips](https://github.com/jicksta)
|
60
|
+
|
61
|
+
### Contributions
|
70
62
|
|
71
63
|
Adhearsion has a set of [contribution guidelines](https://github.com/adhearsion/adhearsion/wiki/Contributing) which help to smooth the contribution process.
|
72
64
|
There is a pre-commit hook that runs encoding checks available in pre-commit. To use it, please copy it to .git/hooks/pre-commit and make it executable.
|
73
65
|
|
74
|
-
Copyright
|
75
|
-
---------
|
66
|
+
### Copyright
|
76
67
|
|
77
|
-
Copyright (c)
|
68
|
+
Copyright (c) 2012 Adhearsion Foundation Inc. MIT LICENSE (see LICENSE for details).
|
data/adhearsion.gemspec
CHANGED
@@ -7,53 +7,44 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Adhearsion::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Jay Phillips", "Jason Goecke", "Ben Klang", "Ben Langfeld"]
|
10
|
-
s.email = "dev
|
10
|
+
s.email = "dev@adhearsion.com"
|
11
11
|
s.homepage = "http://adhearsion.com"
|
12
12
|
s.summary = "Adhearsion, open-source telephony development framework"
|
13
13
|
s.description = "Adhearsion is an open-source telephony development framework"
|
14
|
-
s.date = Date.today.to_s
|
15
14
|
|
16
15
|
s.files = `git ls-files`.split("\n")
|
17
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
18
|
s.require_paths = ["lib"]
|
20
19
|
|
21
|
-
# Runtime dependencies
|
22
|
-
s.add_runtime_dependency 'bundler', [">= 1.0.10"]
|
23
|
-
s.add_runtime_dependency 'punchblock', [">= 0.12.0"]
|
24
|
-
s.add_runtime_dependency 'logging', [">= 1.6.1"]
|
25
|
-
s.add_runtime_dependency 'adhearsion-loquacious', [">= 1.9.0"]
|
26
20
|
s.add_runtime_dependency 'activesupport', [">= 3.0.10"]
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
s.add_runtime_dependency 'i18n', [">= 0.5.0"]
|
31
|
-
s.add_runtime_dependency 'json'
|
32
|
-
s.add_runtime_dependency 'thor'
|
33
|
-
s.add_runtime_dependency 'rake'
|
34
|
-
s.add_runtime_dependency 'pry'
|
35
|
-
s.add_runtime_dependency 'uuid'
|
36
|
-
s.add_runtime_dependency 'future-resource', [">= 0.0.2"]
|
37
|
-
s.add_runtime_dependency 'ruby_speech', [">= 0.4.0"]
|
21
|
+
s.add_runtime_dependency 'adhearsion-loquacious', [">= 1.9.0"]
|
22
|
+
s.add_runtime_dependency 'bundler', ["~> 1.0"]
|
23
|
+
s.add_runtime_dependency 'celluloid', [">= 0.10.0"]
|
38
24
|
s.add_runtime_dependency 'countdownlatch'
|
39
|
-
s.add_runtime_dependency '
|
25
|
+
s.add_runtime_dependency 'deep_merge'
|
26
|
+
s.add_runtime_dependency 'ffi', [">= 1.0.11"]
|
27
|
+
s.add_runtime_dependency 'future-resource', ["~> 1.0"]
|
40
28
|
s.add_runtime_dependency 'girl_friday'
|
29
|
+
s.add_runtime_dependency 'has-guarded-handlers', ["~> 1.1"]
|
41
30
|
s.add_runtime_dependency 'jruby-openssl' if RUBY_PLATFORM == 'java'
|
42
|
-
s.add_runtime_dependency '
|
43
|
-
s.add_runtime_dependency '
|
44
|
-
s.add_runtime_dependency '
|
31
|
+
s.add_runtime_dependency 'logging', [">= 1.6.1"]
|
32
|
+
s.add_runtime_dependency 'pry'
|
33
|
+
s.add_runtime_dependency 'punchblock', ["~> 1.0"]
|
34
|
+
s.add_runtime_dependency 'rake'
|
35
|
+
s.add_runtime_dependency 'ruby_speech', ["~> 1.0"]
|
36
|
+
s.add_runtime_dependency 'thor'
|
37
|
+
s.add_runtime_dependency 'uuid'
|
45
38
|
|
46
|
-
|
47
|
-
s.add_development_dependency '
|
39
|
+
s.add_development_dependency 'aruba'
|
40
|
+
s.add_development_dependency 'ci_reporter'
|
41
|
+
s.add_development_dependency 'cucumber'
|
48
42
|
s.add_development_dependency 'flexmock'
|
49
|
-
s.add_development_dependency '
|
43
|
+
s.add_development_dependency 'guard-cucumber'
|
44
|
+
s.add_development_dependency 'guard-rspec'
|
45
|
+
s.add_development_dependency 'rspec', ["~> 2.7.0"]
|
46
|
+
s.add_development_dependency 'ruby_gntp'
|
50
47
|
s.add_development_dependency 'simplecov'
|
51
48
|
s.add_development_dependency 'simplecov-rcov'
|
52
|
-
s.add_development_dependency 'ci_reporter'
|
53
49
|
s.add_development_dependency 'yard'
|
54
|
-
s.add_development_dependency 'guard-rspec'
|
55
|
-
s.add_development_dependency 'guard-cucumber'
|
56
|
-
s.add_development_dependency 'ruby_gntp'
|
57
|
-
s.add_development_dependency 'cucumber'
|
58
|
-
s.add_development_dependency 'aruba'
|
59
50
|
end
|
data/lib/adhearsion.rb
CHANGED
@@ -94,7 +94,10 @@ end
|
|
94
94
|
Celluloid.exception_handler { |e| Adhearsion::Events.trigger :exception, e }
|
95
95
|
|
96
96
|
module Celluloid
|
97
|
-
|
98
|
-
|
97
|
+
class << self
|
98
|
+
undef :logger
|
99
|
+
def logger
|
100
|
+
::Logging.logger['Celluloid']
|
101
|
+
end
|
99
102
|
end
|
100
103
|
end
|
data/lib/adhearsion/call.rb
CHANGED
@@ -25,7 +25,10 @@ module Adhearsion
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
# @private
|
29
|
+
attr_accessor :offer, :client, :end_reason, :commands, :controllers
|
30
|
+
|
31
|
+
attr_accessor :variables
|
29
32
|
|
30
33
|
delegate :[], :[]=, :to => :variables
|
31
34
|
delegate :to, :from, :to => :offer, :allow_nil => true
|
@@ -42,28 +45,46 @@ module Adhearsion
|
|
42
45
|
self << offer if offer
|
43
46
|
end
|
44
47
|
|
48
|
+
#
|
49
|
+
# @return [String, nil] The globally unique ID for the call
|
50
|
+
#
|
45
51
|
def id
|
46
52
|
offer.target_call_id if offer
|
47
53
|
end
|
48
54
|
|
55
|
+
#
|
56
|
+
# @return [Array] The set of labels with which this call has been tagged.
|
57
|
+
#
|
49
58
|
def tags
|
50
59
|
@tags.clone
|
51
60
|
end
|
52
61
|
|
53
|
-
#
|
54
|
-
#
|
62
|
+
#
|
63
|
+
# Tag a call with an arbitrary label
|
64
|
+
#
|
55
65
|
# @param [String, Symbol] label String or Symbol with which to tag this call
|
66
|
+
#
|
56
67
|
def tag(label)
|
57
68
|
abort ArgumentError.new "Tag must be a String or Symbol" unless [String, Symbol].include?(label.class)
|
58
69
|
@tags << label
|
59
70
|
end
|
60
71
|
|
61
|
-
|
62
|
-
|
72
|
+
#
|
73
|
+
# Remove a label
|
74
|
+
#
|
75
|
+
# @param [String, Symbol] label
|
76
|
+
#
|
77
|
+
def remove_tag(label)
|
78
|
+
@tags.reject! { |tag| tag == label }
|
63
79
|
end
|
64
80
|
|
65
|
-
|
66
|
-
|
81
|
+
#
|
82
|
+
# Establish if the call is tagged with the provided label
|
83
|
+
#
|
84
|
+
# @param [String, Symbol] label
|
85
|
+
#
|
86
|
+
def tagged_with?(label)
|
87
|
+
@tags.include? label
|
67
88
|
end
|
68
89
|
|
69
90
|
def register_event_handler(*guards, &block)
|
@@ -74,10 +95,10 @@ module Adhearsion
|
|
74
95
|
logger.debug "Receiving message: #{message.inspect}"
|
75
96
|
catching_standard_errors { trigger_handler :event, message }
|
76
97
|
end
|
77
|
-
|
78
98
|
alias << deliver_message
|
79
99
|
|
80
|
-
|
100
|
+
# @private
|
101
|
+
def register_initial_handlers
|
81
102
|
register_event_handler Punchblock::Event::Offer do |offer|
|
82
103
|
@offer = offer
|
83
104
|
@client = offer.client
|
@@ -110,7 +131,8 @@ module Adhearsion
|
|
110
131
|
end
|
111
132
|
end
|
112
133
|
|
113
|
-
|
134
|
+
# @private
|
135
|
+
def after_end_hold_time
|
114
136
|
30
|
115
137
|
end
|
116
138
|
|
@@ -121,6 +143,9 @@ module Adhearsion
|
|
121
143
|
end
|
122
144
|
end
|
123
145
|
|
146
|
+
#
|
147
|
+
# @return [Boolean] if the call is currently active or not (disconnected)
|
148
|
+
#
|
124
149
|
def active?
|
125
150
|
!end_reason
|
126
151
|
end
|
@@ -144,7 +169,8 @@ module Adhearsion
|
|
144
169
|
write_and_await_response Punchblock::Command::Hangup.new(:headers => headers)
|
145
170
|
end
|
146
171
|
|
147
|
-
|
172
|
+
# @private
|
173
|
+
def clear_from_active_calls
|
148
174
|
Adhearsion.active_calls.remove_inactive_call current_actor
|
149
175
|
end
|
150
176
|
|
@@ -157,7 +183,7 @@ module Adhearsion
|
|
157
183
|
# @param [Hash, Optional] options further options to be joined with
|
158
184
|
#
|
159
185
|
def join(target, options = {})
|
160
|
-
command = Punchblock::Command::Join.new join_options_with_target(target
|
186
|
+
command = Punchblock::Command::Join.new options.merge(join_options_with_target(target))
|
161
187
|
write_and_await_response command
|
162
188
|
end
|
163
189
|
|
@@ -173,8 +199,9 @@ module Adhearsion
|
|
173
199
|
write_and_await_response command
|
174
200
|
end
|
175
201
|
|
176
|
-
|
177
|
-
|
202
|
+
# @private
|
203
|
+
def join_options_with_target(target)
|
204
|
+
case target
|
178
205
|
when Call
|
179
206
|
{ :call_id => target.id }
|
180
207
|
when String
|
@@ -184,7 +211,7 @@ module Adhearsion
|
|
184
211
|
target
|
185
212
|
else
|
186
213
|
abort ArgumentError.new "Don't know how to join to #{target.inspect}"
|
187
|
-
end
|
214
|
+
end
|
188
215
|
end
|
189
216
|
|
190
217
|
def wait_for_joined(expected_target)
|
@@ -209,6 +236,7 @@ module Adhearsion
|
|
209
236
|
write_and_await_response ::Punchblock::Command::Unmute.new
|
210
237
|
end
|
211
238
|
|
239
|
+
# @private
|
212
240
|
def write_and_await_response(command, timeout = 60)
|
213
241
|
commands << command
|
214
242
|
write_command command
|
@@ -229,6 +257,7 @@ module Adhearsion
|
|
229
257
|
abort CommandTimeout.new(command.to_s)
|
230
258
|
end
|
231
259
|
|
260
|
+
# @private
|
232
261
|
def write_command(command)
|
233
262
|
abort Hangup.new(@end_reason) unless active? || command.is_a?(Punchblock::Command::Hangup)
|
234
263
|
variables.merge! command.headers_hash if command.respond_to? :headers_hash
|
@@ -236,18 +265,22 @@ module Adhearsion
|
|
236
265
|
client.execute_command command, :call_id => id, :async => true
|
237
266
|
end
|
238
267
|
|
239
|
-
|
268
|
+
# @private
|
269
|
+
def logger_id
|
240
270
|
"#{self.class}: #{id}"
|
241
271
|
end
|
242
272
|
|
243
|
-
|
273
|
+
# @private
|
274
|
+
def logger
|
244
275
|
super
|
245
276
|
end
|
246
277
|
|
278
|
+
# @private
|
247
279
|
def to_ary
|
248
280
|
[current_actor]
|
249
281
|
end
|
250
282
|
|
283
|
+
# @private
|
251
284
|
def inspect
|
252
285
|
attrs = [:offer, :end_reason, :commands, :variables, :controllers, :to, :from].map do |attr|
|
253
286
|
"#{attr}=#{send(attr).inspect}"
|
@@ -268,24 +301,28 @@ module Adhearsion
|
|
268
301
|
end.tap { |t| Adhearsion::Process.important_threads << t }
|
269
302
|
end
|
270
303
|
|
304
|
+
# @private
|
271
305
|
def register_controller(controller)
|
272
306
|
@controllers << controller
|
273
307
|
end
|
274
308
|
|
309
|
+
# @private
|
275
310
|
def pause_controllers
|
276
311
|
controllers.each(&:pause!)
|
277
312
|
end
|
278
313
|
|
314
|
+
# @private
|
279
315
|
def resume_controllers
|
280
316
|
controllers.each(&:resume!)
|
281
317
|
end
|
282
318
|
|
283
|
-
|
319
|
+
# @private
|
320
|
+
class CommandRegistry < ThreadSafeArray
|
284
321
|
def terminate
|
285
322
|
hangup = Hangup.new
|
286
323
|
each { |command| command.response = hangup if command.requested? }
|
287
324
|
end
|
288
325
|
end
|
289
326
|
|
290
|
-
end
|
291
|
-
end
|
327
|
+
end
|
328
|
+
end
|
@@ -35,6 +35,11 @@ module Adhearsion
|
|
35
35
|
end
|
36
36
|
|
37
37
|
class << self
|
38
|
+
#
|
39
|
+
# Execute a call controller, allowing passing control to another controller
|
40
|
+
#
|
41
|
+
# @param [CallController] controller
|
42
|
+
#
|
38
43
|
def exec(controller)
|
39
44
|
new_controller = catch :pass_controller do
|
40
45
|
controller.execute!
|
@@ -44,23 +49,35 @@ module Adhearsion
|
|
44
49
|
exec new_controller if new_controller
|
45
50
|
end
|
46
51
|
|
47
|
-
|
52
|
+
#
|
48
53
|
# Include another module into all CallController classes
|
54
|
+
#
|
49
55
|
def mixin(mod)
|
50
56
|
include mod
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
54
|
-
attr_reader :call, :metadata
|
60
|
+
attr_reader :call, :metadata
|
61
|
+
|
62
|
+
# @private
|
63
|
+
attr_reader :block
|
55
64
|
|
56
65
|
delegate :[], :[]=, :to => :@metadata
|
57
66
|
delegate :variables, :logger, :to => :call
|
58
67
|
|
68
|
+
#
|
69
|
+
# Create a new instance
|
70
|
+
#
|
71
|
+
# @param [Call] call the call to operate the controller on
|
72
|
+
# @param [Hash] metadata generic key-value storage applicable to the controller
|
73
|
+
# @param block to execute on the call
|
74
|
+
#
|
59
75
|
def initialize(call, metadata = nil, &block)
|
60
76
|
@call, @metadata, @block = call, metadata || {}, block
|
61
77
|
end
|
62
78
|
|
63
|
-
|
79
|
+
# @private
|
80
|
+
def execute!(*options)
|
64
81
|
call.register_controller! self
|
65
82
|
execute_callbacks :before_call
|
66
83
|
run
|
@@ -73,20 +90,36 @@ module Adhearsion
|
|
73
90
|
logger.debug "Finished executing controller #{self.inspect}"
|
74
91
|
end
|
75
92
|
|
93
|
+
#
|
94
|
+
# Invoke the block supplied when creating the controller
|
95
|
+
#
|
76
96
|
def run
|
77
97
|
instance_exec(&block) if block
|
78
98
|
end
|
79
99
|
|
100
|
+
#
|
101
|
+
# Invoke another controller class within this controller, returning to this context on completion.
|
102
|
+
#
|
103
|
+
# @param [Class] controller_class The class of controller to execute
|
104
|
+
# @param [Hash] metadata generic key-value storage applicable to the controller
|
105
|
+
#
|
80
106
|
def invoke(controller_class, metadata = nil)
|
81
107
|
controller = controller_class.new call, metadata
|
82
108
|
controller.run
|
83
109
|
end
|
84
110
|
|
111
|
+
#
|
112
|
+
# Cease execution of this controller, and pass to another.
|
113
|
+
#
|
114
|
+
# @param [Class] controller_class The class of controller to pass to
|
115
|
+
# @param [Hash] metadata generic key-value storage applicable to the controller
|
116
|
+
#
|
85
117
|
def pass(controller_class, metadata = nil)
|
86
118
|
throw :pass_controller, controller_class.new(call, metadata)
|
87
119
|
end
|
88
120
|
|
89
|
-
|
121
|
+
# @private
|
122
|
+
def execute_callbacks(type)
|
90
123
|
self.class.callbacks[type].each do |callback|
|
91
124
|
catching_standard_errors do
|
92
125
|
instance_exec(&callback)
|
@@ -94,21 +127,29 @@ module Adhearsion
|
|
94
127
|
end
|
95
128
|
end
|
96
129
|
|
97
|
-
|
130
|
+
# @private
|
131
|
+
def after_call
|
98
132
|
@after_call ||= execute_callbacks :after_call
|
99
133
|
end
|
100
134
|
|
135
|
+
#
|
136
|
+
# Hangup the call, and execute after_call callbacks
|
137
|
+
#
|
138
|
+
# @param [Hash] headers
|
139
|
+
#
|
101
140
|
def hangup(headers = nil)
|
102
141
|
block_until_resumed
|
103
142
|
hangup_response = call.hangup headers
|
104
143
|
after_call unless hangup_response == false
|
105
144
|
end
|
106
145
|
|
146
|
+
# @private
|
107
147
|
def write_and_await_response(command)
|
108
148
|
block_until_resumed
|
109
149
|
call.write_and_await_response command
|
110
150
|
end
|
111
151
|
|
152
|
+
# @private
|
112
153
|
def execute_component_and_await_completion(component)
|
113
154
|
write_and_await_response component
|
114
155
|
|
@@ -119,33 +160,58 @@ module Adhearsion
|
|
119
160
|
component
|
120
161
|
end
|
121
162
|
|
163
|
+
#
|
164
|
+
# Answer the call
|
165
|
+
#
|
166
|
+
# @see Call#answer
|
167
|
+
#
|
122
168
|
def answer(*args)
|
123
169
|
block_until_resumed
|
124
170
|
call.answer(*args)
|
125
171
|
end
|
126
172
|
|
173
|
+
#
|
174
|
+
# Reject the call
|
175
|
+
#
|
176
|
+
# @see Call#reject
|
177
|
+
#
|
127
178
|
def reject(*args)
|
128
179
|
block_until_resumed
|
129
180
|
call.reject(*args)
|
130
181
|
end
|
131
182
|
|
183
|
+
#
|
184
|
+
# Mute the call
|
185
|
+
#
|
186
|
+
# @see Call#mute
|
187
|
+
#
|
132
188
|
def mute(*args)
|
133
189
|
block_until_resumed
|
134
190
|
call.mute(*args)
|
135
191
|
end
|
136
192
|
|
193
|
+
#
|
194
|
+
# Unmute the call
|
195
|
+
#
|
196
|
+
# @see Call#unmute
|
197
|
+
#
|
137
198
|
def unmute(*args)
|
138
199
|
block_until_resumed
|
139
200
|
call.unmute(*args)
|
140
201
|
end
|
141
202
|
|
203
|
+
#
|
204
|
+
# Join the call to another call or a mixer, and block until the call is unjoined (by hangup or otherwise).
|
205
|
+
#
|
206
|
+
# @param [Object] target See Call#join for details
|
207
|
+
# @param [Hash] options
|
208
|
+
# @option options [Boolean] :async Return immediately, without waiting for the calls to unjoin. Defaults to false.
|
209
|
+
#
|
210
|
+
# @see Call#join
|
211
|
+
#
|
142
212
|
def join(target, options = {})
|
143
|
-
async = if target.is_a?(Hash)
|
144
|
-
target.delete :async
|
145
|
-
else
|
146
|
-
options.delete :async
|
147
|
-
end
|
148
213
|
block_until_resumed
|
214
|
+
async = (target.is_a?(Hash) ? target : options).delete :async
|
149
215
|
join_command = call.join target, options
|
150
216
|
waiter = join_command.call_id || join_command.mixer_name
|
151
217
|
if async
|
@@ -155,20 +221,24 @@ module Adhearsion
|
|
155
221
|
end
|
156
222
|
end
|
157
223
|
|
158
|
-
|
224
|
+
# @private
|
225
|
+
def block_until_resumed
|
159
226
|
instance_variable_defined?(:@pause_latch) && @pause_latch.wait
|
160
227
|
end
|
161
228
|
|
162
|
-
|
229
|
+
# @private
|
230
|
+
def pause!
|
163
231
|
@pause_latch = CountDownLatch.new 1
|
164
232
|
end
|
165
233
|
|
166
|
-
|
234
|
+
# @private
|
235
|
+
def resume!
|
167
236
|
return unless @pause_latch
|
168
237
|
@pause_latch.countdown!
|
169
238
|
@pause_latch = nil
|
170
239
|
end
|
171
240
|
|
241
|
+
# @private
|
172
242
|
def inspect
|
173
243
|
"#<#{self.class} call=#{call.id}, metadata=#{metadata.inspect}>"
|
174
244
|
end
|