adhearsion 0.7.6 → 0.7.7
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/.version +1 -1
- data/CHANGELOG +43 -25
- data/Rakefile +0 -5
- data/TODO +51 -2
- data/ahn +2 -1
- data/apps/default/Rakefile +16 -7
- data/apps/default/config/adhearsion.yml +22 -1
- data/apps/default/config/helpers/manager_proxy.yml +1 -0
- data/apps/default/config/helpers/micromenus/images/arrow-off.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/arrow-on.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/error.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/folder-off.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/folder-on.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/folder.png +0 -0
- data/apps/default/config/helpers/micromenus/images/ggbridge.jpg +0 -0
- data/apps/default/config/helpers/micromenus/images/green.png +0 -0
- data/apps/default/config/helpers/micromenus/images/microbrowser.bg.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/red.png +0 -0
- data/apps/default/config/helpers/micromenus/images/url-off.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/url-on.gif +0 -0
- data/apps/default/config/helpers/micromenus/images/yellow.png +0 -0
- data/apps/default/config/helpers/micromenus/javascripts/animation.js +1341 -0
- data/apps/default/config/helpers/micromenus/javascripts/carousel.js +1238 -0
- data/apps/default/config/helpers/micromenus/javascripts/columnav.js +306 -0
- data/apps/default/config/helpers/micromenus/javascripts/connection.js +965 -0
- data/apps/default/config/helpers/micromenus/javascripts/container.js +4727 -0
- data/apps/default/config/helpers/micromenus/javascripts/container_core.js +2915 -0
- data/apps/default/config/helpers/micromenus/javascripts/dom.js +892 -0
- data/apps/default/config/helpers/micromenus/javascripts/dragdrop.js +2921 -907
- data/apps/default/config/helpers/micromenus/javascripts/event.js +1771 -0
- data/apps/default/config/helpers/micromenus/javascripts/yahoo.js +433 -0
- data/apps/default/config/helpers/micromenus/stylesheets/carousel.css +78 -0
- data/apps/default/config/helpers/micromenus/stylesheets/columnav.css +135 -0
- data/apps/default/config/helpers/micromenus/stylesheets/microbrowsers.css +42 -0
- data/apps/default/config/helpers/multi_messenger.yml +5 -1
- data/apps/default/config/migration.rb +10 -0
- data/apps/default/extensions.rb +1 -1
- data/apps/default/helpers/factorial.alien.c +3 -3
- data/apps/default/helpers/lookup.rb +2 -1
- data/apps/default/helpers/manager_proxy.rb +67 -15
- data/apps/default/helpers/micromenus.rb +173 -31
- data/apps/default/helpers/multi_messenger.rb +20 -3
- data/lib/adhearsion.rb +218 -88
- data/lib/constants.rb +1 -0
- data/lib/core_extensions.rb +15 -9
- data/lib/phone_number.rb +85 -0
- data/lib/rami.rb +3 -2
- data/lib/servlet_container.rb +47 -24
- data/lib/sexy_migrations.rb +70 -0
- data/test/asterisk_module_test.rb +9 -9
- data/test/specs/numerical_string_spec.rb +53 -0
- metadata +31 -11
- data/apps/default/config/helpers/micromenus/javascripts/builder.js +0 -131
- data/apps/default/config/helpers/micromenus/javascripts/controls.js +0 -834
- data/apps/default/config/helpers/micromenus/javascripts/effects.js +0 -956
- data/apps/default/config/helpers/micromenus/javascripts/prototype.js +0 -2319
- data/apps/default/config/helpers/micromenus/javascripts/scriptaculous.js +0 -51
- data/apps/default/config/helpers/micromenus/javascripts/slider.js +0 -278
- data/apps/default/config/helpers/micromenus/javascripts/unittest.js +0 -557
- data/apps/default/config/helpers/micromenus/stylesheets/firefox.css +0 -10
- data/apps/default/config/helpers/micromenus/stylesheets/firefox.xul.css +0 -44
@@ -7,10 +7,10 @@ require 'xmpp4r-simple'
|
|
7
7
|
class MultiMessenger
|
8
8
|
|
9
9
|
Format = /\A[\w\._%-]+@[\w\.-]+\.[a-zA-Z]{2,4}\z/
|
10
|
-
|
11
|
-
def initialize username, password
|
10
|
+
def initialize username, password, accept_subs=false
|
12
11
|
@username, @password = username, password
|
13
12
|
@connection = Jabber::Simple.new username, password
|
13
|
+
@connection.accept_subscriptions = accept_subs
|
14
14
|
end
|
15
15
|
|
16
16
|
def connected?() @connection.connected? end
|
@@ -28,9 +28,26 @@ config = $HELPERS['multi_messenger']
|
|
28
28
|
|
29
29
|
username = config['username']||''
|
30
30
|
password = config['password']||''
|
31
|
+
accept_subs = config['accept_subscriptions']
|
31
32
|
|
32
33
|
log "MultiMessenger: Connecting to #{username}"
|
33
|
-
jabber = MultiMessenger.new username, password
|
34
|
+
jabber = MultiMessenger.new username, password, accept_subs
|
35
|
+
|
36
|
+
jabber.connection.received_messages do |msg|
|
37
|
+
# Need to do something with each message? Do it here.
|
38
|
+
end
|
39
|
+
|
40
|
+
jabber.connection.presence_updates do |friend, old_presence, new_presence|
|
41
|
+
# Handle presence updates here, optionally
|
42
|
+
end
|
43
|
+
|
44
|
+
jabber.connection.subscription_requests do |friend, presence|
|
45
|
+
# When a subscription request comes in, handle it here.
|
46
|
+
end
|
47
|
+
|
48
|
+
jabber.connection.new_subscriptions do |friend, presence|
|
49
|
+
# Handle each subscription notification
|
50
|
+
end
|
34
51
|
|
35
52
|
InstantMessenger.use_service jabber
|
36
53
|
$HUTDOWN.hook { jabber.connection.disconnect }
|
data/lib/adhearsion.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
17
17
|
|
18
18
|
require 'core_extensions'
|
19
|
+
require 'phone_number'
|
19
20
|
|
20
21
|
module Asterisk
|
21
22
|
|
@@ -41,18 +42,18 @@ module Asterisk
|
|
41
42
|
# AGI. This code has been kept here in case these bugs are fixed.
|
42
43
|
def old_input digits=nil, user_options=Hash.new('')
|
43
44
|
used_options = {:variable => String.random, :digits => digits}
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
45
|
+
used_options.default = ''
|
46
|
+
used_options.merge! user_options
|
47
|
+
args = []
|
48
|
+
%w(variable soundfile digits option attempts timeout).each do |x|
|
49
|
+
args << used_options[x.to_sym]
|
50
|
+
end
|
51
|
+
log "THESE ARE THE INPUT ARGS: " + args.inspect
|
52
|
+
exec :read, args
|
53
|
+
$OSCAR[:VARS] << args.first
|
54
|
+
x = get_variable(args.first).gsub(/[\(\)]/, "")
|
55
|
+
debug "RETURN: #{x.inspect}"
|
56
|
+
x.simplify
|
56
57
|
end
|
57
58
|
|
58
59
|
# Input is used to receive keypad input from the user, pausing until they
|
@@ -66,6 +67,8 @@ module Asterisk
|
|
66
67
|
#
|
67
68
|
# When called without any arguments (or a first argument of -1), the user is
|
68
69
|
# able to enter digits ad infinitum until they press the pound (#) key.
|
70
|
+
#
|
71
|
+
# Note: input() does NOT catch "#" character! Use wait_for_digit instead.
|
69
72
|
def input digits=nil, hash={}
|
70
73
|
timeout, file = (hash[:timeout] || -1), (hash[:play] || hash[:file] || 'beep')
|
71
74
|
result = rawr "GET DATA #{file} #{timeout} #{digits}"
|
@@ -150,7 +153,7 @@ module Asterisk
|
|
150
153
|
# returns nil. If the asterisk or pound key was pressed, a String is returned of that
|
151
154
|
# response. In all other cases, the Fixnum of the number pressed is returned.
|
152
155
|
def wait_for_digit timeout=-1
|
153
|
-
digit = rawr("WAIT FOR DIGIT #{timeout < 0 ? -1 : timeout
|
156
|
+
digit = rawr("WAIT FOR DIGIT #{timeout < 0 ? -1 : timeout * 1000.0}").match(/=(.*)$/)[1].to_i
|
154
157
|
return nil if digit <= 0 # If there was an error or timeout
|
155
158
|
return digit.chr if (32..45).include? digit
|
156
159
|
digit - ?0
|
@@ -167,12 +170,34 @@ module Asterisk
|
|
167
170
|
end
|
168
171
|
end
|
169
172
|
|
173
|
+
def detach!
|
174
|
+
PBX.io.close
|
175
|
+
end
|
176
|
+
|
170
177
|
# An abstracted remote accessor for retrieving Asterisk variables.
|
171
178
|
def get_variable(key, default=nil)
|
172
179
|
result = rawr "GET VARIABLE #{key}"
|
173
|
-
result[0..12] == "200 result=0" ? default : result[
|
180
|
+
result[0..12] == "200 result=0" ? default : result[14..-2].strip
|
174
181
|
end
|
175
182
|
|
183
|
+
# Plays a tone over the call.
|
184
|
+
#
|
185
|
+
# Usage:
|
186
|
+
# - tone:busy
|
187
|
+
# - tone:dial
|
188
|
+
# - tone:info
|
189
|
+
# - tone:record
|
190
|
+
# - tone "3333/33,0/15000" # Random custom tone
|
191
|
+
def tone type
|
192
|
+
exec 'PlayTones', (case type
|
193
|
+
when :busy then "480+620/500,0/500"
|
194
|
+
when :dial then "440+480/2000,0/4000"
|
195
|
+
when :info then "!950/330,!1400/330,!1800/330,0"
|
196
|
+
when :record then "1400/500,0/15000"
|
197
|
+
else type
|
198
|
+
end)
|
199
|
+
end
|
200
|
+
|
176
201
|
# == Dialing Users
|
177
202
|
#
|
178
203
|
# This method will be used in most dial plans written with Adhearsion.
|
@@ -230,7 +255,18 @@ module Asterisk
|
|
230
255
|
# last_dial_status. Note: last_dial_status returns a Symbol representing
|
231
256
|
# the result of the last call. For more information, see its appropriate
|
232
257
|
# documentation.
|
233
|
-
#
|
258
|
+
#
|
259
|
+
# === Setting CallerID
|
260
|
+
#
|
261
|
+
# To set the callerid number, simply pass either a number or a String of the
|
262
|
+
# digits to dial() as a Symbol key argument.
|
263
|
+
#
|
264
|
+
# dial :crusher, :callerid => 1_555_123_4567
|
265
|
+
# dial :picard, :callerid => 12224561701
|
266
|
+
# dial :laforge, :callerid => '14442223333'
|
267
|
+
#
|
268
|
+
# === Dial options
|
269
|
+
#
|
234
270
|
# Additionally, you can use the :options hash key argument to specify options
|
235
271
|
# which Asterisk's Dial() application normally takes. For example:
|
236
272
|
#
|
@@ -243,7 +279,17 @@ module Asterisk
|
|
243
279
|
# http://www.voip-info.org/wiki-Asterisk+cmd+Dial
|
244
280
|
def dial who, hash={}
|
245
281
|
# if who.is_a_group? TODO: Set the CDR GROUP() value if a Group is dialed.
|
246
|
-
|
282
|
+
|
283
|
+
# TODO Must be provided as a number until the Set(CALLERID(name)=something)
|
284
|
+
# stuff is figured out.
|
285
|
+
cid = hash.delete :callerid
|
286
|
+
if cid
|
287
|
+
cid = cid.to_s
|
288
|
+
cid = "1" << cid if cid.size == 10
|
289
|
+
rawr %(SET CALLERID "#{cid}") if cid
|
290
|
+
end
|
291
|
+
|
292
|
+
exec :dial, PBX.properize(who), *[hash[:for], hash[:options]]
|
247
293
|
end
|
248
294
|
|
249
295
|
# As you might expect, last_call_successful? returns a boolean depending on whether
|
@@ -258,6 +304,11 @@ module Asterisk
|
|
258
304
|
!last_call_successful?
|
259
305
|
end
|
260
306
|
|
307
|
+
# Send a DTMF tone over the line
|
308
|
+
def dtmf digits
|
309
|
+
exec "SendDTMF", digits.to_s
|
310
|
+
end
|
311
|
+
|
261
312
|
# The stream_file() method comes right over from the AGI protocol.
|
262
313
|
# Its use is very similar to the Background() application from
|
263
314
|
# Asterisk's extensions.conf language. A file is played in the
|
@@ -293,8 +344,29 @@ module Asterisk
|
|
293
344
|
# Festival is pretty buggy (and pretty inefficient). In theory,
|
294
345
|
# this should speak out any text supplied to it.
|
295
346
|
def speak text
|
296
|
-
text.gsub!
|
297
|
-
|
347
|
+
text.gsub! "\n",''
|
348
|
+
text.gsub! "\r",''
|
349
|
+
text.strip!
|
350
|
+
exec :Festival, "#{text.inspect}"
|
351
|
+
end
|
352
|
+
|
353
|
+
def build_local first, second=nil
|
354
|
+
num = 1
|
355
|
+
context = nil
|
356
|
+
if first.kind_of? Fixnum
|
357
|
+
num = first
|
358
|
+
context = second if second
|
359
|
+
else
|
360
|
+
context = first
|
361
|
+
num = second if second
|
362
|
+
end
|
363
|
+
returning("Local/#{num}") do |s|
|
364
|
+
s << "@#{context}" if context
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def external_invoke *args
|
369
|
+
dial build_local(*args)
|
298
370
|
end
|
299
371
|
|
300
372
|
# Since voicemail is used so frequently, extra effort has been made to
|
@@ -362,12 +434,40 @@ module Asterisk
|
|
362
434
|
def play *files
|
363
435
|
files.flatten!
|
364
436
|
files.each do |f|
|
365
|
-
if f.
|
437
|
+
if f.kind_of? Time
|
438
|
+
exec :SayUnixTime, f.to_i
|
439
|
+
elsif f.kind_of? Symbol then exec :playback, f
|
440
|
+
elsif f[0] == ?$
|
441
|
+
# Speak a currency. TODO: support currencies other than dollars.
|
442
|
+
full,dollars,decimal,cents = *f.match(/^\$(\d+)(\.(\d{1,2}).*)?$/)
|
443
|
+
if full
|
444
|
+
exec :saynumber, dollars
|
445
|
+
exec :playback, (dollars == '1') ? 'dollar' : 'dollars'
|
446
|
+
if decimal
|
447
|
+
exec :playback, 'and'
|
448
|
+
exec :saynumber, cents
|
449
|
+
exec :playback, (cents == '1') ? 'cent' : 'cents'
|
450
|
+
end
|
451
|
+
else exec :playback, f
|
452
|
+
end
|
453
|
+
elsif f.simplify.kind_of? Numeric then exec :saynumber, f
|
366
454
|
else exec :playback, f
|
367
455
|
end
|
368
456
|
end
|
369
457
|
end
|
370
458
|
|
459
|
+
# Compiles the provided Asterisk dialplan pattern into a Ruby regular
|
460
|
+
# expression. For more usage of Asterisk's pattern syntax, see
|
461
|
+
# http://www.voip-info.org/wiki/view/Asterisk+Dialplan+Patterns
|
462
|
+
def _ pattern
|
463
|
+
# Uncomment the following code fragment for complete compatability.
|
464
|
+
# The fragment handles the seldom-used hyphen number spacer with no
|
465
|
+
# meaning.
|
466
|
+
Regexp.new '^' << pattern.#gsub(/(?!\[[\w+-]+)-(?![\w-]+\])/,'').
|
467
|
+
gsub('X', '[0-9]').gsub('Z', '[1-9]').gsub('N','[2-9]').
|
468
|
+
gsub('.','.+').gsub('!','.*') << '$'
|
469
|
+
end
|
470
|
+
|
371
471
|
# == Dialplan Instruction Caching
|
372
472
|
#
|
373
473
|
# If a cynic ever says Ruby doesn't make an efficient dial plan manager,
|
@@ -548,37 +648,7 @@ module Asterisk
|
|
548
648
|
end
|
549
649
|
|
550
650
|
# Very simply sends the command over the AGI IO socket and forgets about it.
|
551
|
-
def putc(what) PBX.io.print "#{what}" end
|
552
|
-
|
553
|
-
# The magical method that handles how objects passed to dial() are converted to their
|
554
|
-
# corresponding Asterisk-recognizable technology/extension identifier. This likely
|
555
|
-
# wouldn't be used much outside of dial(), but you may find it useful.
|
556
|
-
def properize who
|
557
|
-
# These are the convention methods for Group-like objects
|
558
|
-
group_method = who.is_a_group?
|
559
|
-
|
560
|
-
# If 'who' has any of the possible_methods, replace 'who' with the return value
|
561
|
-
# of that method
|
562
|
-
who = who.send group_method if group_method
|
563
|
-
return nil unless who
|
564
|
-
|
565
|
-
# In case we can't perform collection algorithms on 'who', let's encapsulate it in
|
566
|
-
# an Array
|
567
|
-
who = [who] unless who.kind_of?(Enumerable) && !who.kind_of?(String)
|
568
|
-
|
569
|
-
user_method = who.first.is_a_user?
|
570
|
-
# If the first thing in the Enumerable responds to a User-like convention, then
|
571
|
-
# set 'who' equal to the extension(s) accessor of those objects. We refine the "who"
|
572
|
-
# argument more and more in this way until it's finally in a way Asterisk can read.
|
573
|
-
who.map! { |p| p.send user_method }.compact! if user_method
|
574
|
-
|
575
|
-
# Now replace each item in the Enumerable with its form converted to
|
576
|
-
# extension (assuming it's not already in that format)
|
577
|
-
who.map! do |ext|
|
578
|
-
(ext.kind_of?(String) && ext.index(?/)) ? ext : "SIP/#{ext}"
|
579
|
-
end
|
580
|
-
who * '&' # Finally, join() anything left in the Array with an '&'
|
581
|
-
end
|
651
|
+
def putc(what) PBX.io.print "#{what}" end
|
582
652
|
|
583
653
|
# Returns the status of the last dial(). Possible dial
|
584
654
|
# statuses include :answer, :busy, :noanswer, :cancel,
|
@@ -600,59 +670,119 @@ module Asterisk
|
|
600
670
|
# Direct translation of the Asterisk NoOp() application. Used primarily for
|
601
671
|
# viewing debug information in the Asterisk CLI.
|
602
672
|
def noop(*options) rawr "NOOP #{options}" end
|
603
|
-
end
|
604
|
-
|
605
|
-
# This SIP class abstracts several SIP-related functions. In your dialplan,
|
606
|
-
# if you should want to set a SIP header specifically, simply use the class
|
607
|
-
# []= operator. For example, you may want to do SIP['Alert-Info'] = 'Ring-Answer'
|
608
|
-
# which will affect the next SIP call placed. Additionally, you can use this
|
609
|
-
# class's division operator to naturally represent "technology/channel"
|
610
|
-
# endpoints (e.g. SIP/1550 or SIP/:tweedledum)
|
611
|
-
class SIP
|
612
|
-
|
613
|
-
# This will set the header value specified within the square bracked to the
|
614
|
-
# value given after the equals sign. Note: this can only be called if the
|
615
|
-
# current call's thread is handling an Asterisk call over AGI (i.e. dialplan).
|
616
|
-
def self.[]=(header, value)
|
617
|
-
exec :SipAddHeader, "#{header}: #{value}"
|
618
|
-
end
|
619
673
|
|
620
|
-
# Simple convenience method to make Adhearsion's DSL more Asterisk-like.
|
621
|
-
# Virtually anything can be provided after the "/", as long as its to_s()
|
622
|
-
# method is what you intended to represent.
|
623
|
-
def self./(ext) "SIP/#{ext}" end
|
624
674
|
end
|
625
675
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
676
|
+
# # This Endpoint module is only used when using the
|
677
|
+
# # forward-slash operator on the dialplan technology
|
678
|
+
# # classes such as IAX, SIP, Zap, Local, SCCP, etc.
|
679
|
+
# # The String's eigencalss returned from IAX/:foobar
|
680
|
+
# # extends this module.
|
681
|
+
# module Endpoint
|
682
|
+
# def /(x) to_s << "/" << x.to_s end
|
683
|
+
# end
|
684
|
+
#
|
685
|
+
# # Use like IAX/:trunk/12345
|
686
|
+
# class IAX
|
687
|
+
# def self./(x) "IAX2/#{x}".extend Endpoint end
|
688
|
+
# end
|
689
|
+
# # Use like SIP/:trunk/12345
|
690
|
+
# class SIP
|
691
|
+
# def self./(x) "SIP/#{x}".extend Endpoint end
|
692
|
+
# end
|
693
|
+
# # Use like SCCP/:trunk/12345
|
694
|
+
# class SCCP
|
695
|
+
# def self./(x) "SCCP/#{x}".extend Endpoint end
|
696
|
+
# end
|
697
|
+
# # Use like Zap/:channel/12345
|
698
|
+
# class Zap
|
699
|
+
# def self./(x) "ZAP/#{x}".extend Endpoint end
|
700
|
+
# end
|
701
|
+
# # Use like Local/'extension@context'
|
702
|
+
# class Local
|
703
|
+
# def self./(x) "Local/#{x}".extend Endpoint end
|
704
|
+
# end
|
705
|
+
# class GTalk
|
706
|
+
# def self./(x) "gtalk/#{x}".extend Endpoint end
|
707
|
+
# end
|
708
|
+
#
|
709
|
+
# # Use like IAX2/:trunk/12345
|
710
|
+
# class IAX2 < IAX;end
|
711
|
+
# # Use like ZAP/:channel/12345
|
712
|
+
# class ZAP < Zap;end
|
713
|
+
|
714
|
+
# Contributed by Bruce Williams of Five Runs.
|
715
|
+
module DialplanTechnologies
|
716
|
+
module Endpoint
|
717
|
+
def /(x) to_s << "/" << x.to_s end
|
718
|
+
end
|
719
|
+
|
720
|
+
class Base
|
721
|
+
def self./(x) "#{self}/#{x}".extend(Endpoint) end
|
722
|
+
end
|
723
|
+
|
724
|
+
class << self
|
725
|
+
def define(&block)
|
726
|
+
instance_eval(&block)
|
727
|
+
end
|
728
|
+
def add(*technologies)
|
729
|
+
options = technologies.last.is_a?(Hash) ? technologies.pop : {}
|
730
|
+
technologies.each do |name|
|
731
|
+
eval %{class ::#{name} < Base; def self.to_s; "#{options[:as] || name}"; end; end}
|
732
|
+
end
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
631
736
|
end
|
632
737
|
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
738
|
+
DialplanTechnologies.define do
|
739
|
+
add :IAX2, :SIP, :SCCP, :ZAP, :Local
|
740
|
+
add :GTalk, :as => :gtalk
|
741
|
+
add :Zap, :as => :ZAP
|
742
|
+
add :IAX, :as => :IAX2
|
638
743
|
end
|
639
744
|
|
640
|
-
# For users who may try to use the (proper) IAX2 form. See IAX for more info.
|
641
|
-
class IAX2 < IAX; end
|
642
|
-
|
643
|
-
# For users who may try to use the (common) "Zap" form. See ZAP for more info.
|
644
|
-
class Zap < ZAP; end
|
645
745
|
|
646
746
|
# The PBX object is an object manifestation of the PBX with which Adhearsion will be
|
647
747
|
# associated. Helpers often open up this class and add methods to it. Note: when doing
|
648
748
|
# this in your own helpers, all methods will need to be class (a.k.a. static) methods
|
649
749
|
# since no actual instance of this object is passed around.
|
650
750
|
class PBX
|
651
|
-
def method_missing name
|
751
|
+
def self.method_missing name
|
652
752
|
raise NameError, "Method #{name} not found! Are you sure manager_proxy is configured properly?"
|
653
753
|
end
|
754
|
+
|
755
|
+
# The magical method that handles how objects passed to dial() are converted to their
|
756
|
+
# corresponding Asterisk-recognizable technology/extension identifier. This likely
|
757
|
+
# wouldn't be used much outside of dial(), but you may find it useful.
|
758
|
+
def self.properize who
|
759
|
+
|
760
|
+
group_method = who.is_a_group?
|
761
|
+
|
762
|
+
# If 'who' has any of the possible_methods, replace 'who' with the return value
|
763
|
+
# of that method
|
764
|
+
who = who.send group_method if group_method
|
765
|
+
return nil unless who
|
766
|
+
|
767
|
+
# In case we can't perform collection algorithms on 'who', let's encapsulate it in
|
768
|
+
# an Array
|
769
|
+
who = [who] unless who.kind_of?(Enumerable) && !who.kind_of?(String)
|
770
|
+
|
771
|
+
user_method = who.first.is_a_user?
|
772
|
+
# If the first thing in the Enumerable responds to a User-like convention, then
|
773
|
+
# set 'who' equal to the extension(s) accessor of those objects. We refine the "who"
|
774
|
+
# argument more and more in this way until it's finally in a way Asterisk can read.
|
775
|
+
who.map! { |p| p.send user_method }.compact! if user_method
|
776
|
+
|
777
|
+
# Now replace each item in the Enumerable with its form converted to
|
778
|
+
# extension (assuming it's not already in that format)
|
779
|
+
who.map! do |ext|
|
780
|
+
(ext.kind_of?(String) && ext.index(?/)) ? ext : "SIP/#{ext}"
|
781
|
+
end
|
782
|
+
who * '&' # Finally, join() anything left in the Array with an '&'
|
783
|
+
end
|
654
784
|
|
655
|
-
def
|
785
|
+
def self.io() Thread.current[:io] end
|
656
786
|
end
|
657
787
|
|
658
788
|
# The Contexts class is a blank slate in which the extensions.rb file is evaluated.
|
@@ -822,4 +952,4 @@ end
|
|
822
952
|
# is one of the names you're signed into AIM with. Note: this example doesn't use the :through
|
823
953
|
# Hash-key argument because it assumes no other helpers are installed with this same format.
|
824
954
|
# If you had a MSN or Yahoo helper installed too, you'd need to do specify :through because
|
825
|
-
def im(sn, msg, hash={}) InstantMessenger.im(sn,msg,hash) end
|
955
|
+
def im(sn, msg, hash={}) InstantMessenger.im(sn,msg,hash) end
|