adhearsion 2.0.0.rc5 → 2.0.0
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/.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
|