adhearsion 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
data/.version CHANGED
@@ -1 +1 @@
1
- 0.7.4
1
+ 0.7.5
@@ -0,0 +1,18 @@
1
+ CHANGELOG since 0.7.4
2
+ ----------------------------------------------------------------------
3
+ Regexp for US number is a little more accurate
4
+ Context names like foo-bar are converted to foo_bar in extensions.rb.
5
+ Reverted the weather helper hack in trunk
6
+ Added last_dial_successful? and last_dial_unsuccessful?
7
+ Fixed bug in last_dial_status()
8
+ Added join() method back. Now supports MeetMe options, specifying the PIN code, and named conferences from adhearsion.yml.
9
+ Improved documentation for a few methods in adhearsion.rb
10
+ Dialing timeouts can now be done with a syntax like "dial :jay, :for => 2.minutes"
11
+ Dialing options can now be given with "dial :options => 'mwt'"
12
+ Fixed a bug in voicemail() which caused special mailboxes (busy, unavailable) to be malformed when Asterisk got the command.
13
+ Added the ability for voicemail() to skip Allison's standard instructions.
14
+ Made the SIP,ZAP,IAX/Zap/IAX2 sugary classes accessible globally
15
+ Implemented Object#is_a_group? and Object#is_a_user?. Return values for these found convention method.
16
+ Added the lookup() method as the "lookup" helper. Provides reverse-lookups for phone numbers from WhitePages.com. Require hpricot.
17
+ Cleaned up properize()
18
+ Removed the properize() assumption that dialed national numbers should have the international code (1) before them.
data/Rakefile CHANGED
@@ -112,4 +112,4 @@ end
112
112
  desc 'Creates the Trixbox RPM.'
113
113
  task :trixbox => [:repackage] do
114
114
  # Coming soon
115
- end
115
+ end
data/ahn CHANGED
@@ -38,8 +38,6 @@ ADHEARSION_VERSION = File.read(File.join(File.dirname(__FILE__), '.version')).st
38
38
  ARGV.unshift 'start' if ARGV.empty? # Set the default operation
39
39
 
40
40
  require 'yaml'
41
- adhearsion_config = File.join('config', 'adhearsion.yml')
42
- CONFIG = File.readable?(adhearsion_config) ? YAML.load_file(adhearsion_config) : {}
43
41
 
44
42
  $HUTDOWN = []
45
43
  class << $HUTDOWN
@@ -54,9 +52,6 @@ end
54
52
  trap sig do $HUTDOWN.now! end
55
53
  end
56
54
 
57
- require 'logging'
58
- register_logger StandardLogger.new(STDOUT)
59
-
60
55
  case ARGV.shift
61
56
  when 'help', '-h', '--h', '-help', '--help' then puts usage
62
57
  when 'version' then puts "Adhearsion v#{ADHEARSION_VERSION}"
@@ -69,7 +64,7 @@ when /^create(:[\w_.]+)?$/
69
64
  base_dir = File.expand_path File.dirname(__FILE__)
70
65
  App = $&.index(':') ? $&.split(':')[1..-1] * ':' : "default"
71
66
 
72
- abort %'No app "#{App}" found!' unless File.directory? "#{base_dir}/apps/#{App}"
67
+ abort %'No app "#{App}" found!' unless File.exists? "#{base_dir}/apps/#{App}"
73
68
 
74
69
  from, to = [], []
75
70
  (Dir["{#{base_dir}/apps/#{App},docs}/**/*"] + ["#{base_dir}/LICENSE"]).each do |key|
@@ -77,6 +72,7 @@ when /^create(:[\w_.]+)?$/
77
72
  value.sub! "apps/#{App}/", '' if value.index "apps/#{App}/"
78
73
 
79
74
  to << dest_dir + value
75
+
80
76
  from << key
81
77
  end
82
78
 
@@ -143,6 +139,12 @@ when 'start'
143
139
 
144
140
  Dir.chdir target
145
141
 
142
+ adhearsion_config = File.join('config', 'adhearsion.yml')
143
+ CONFIG = File.readable?(adhearsion_config) ? YAML.load_file(adhearsion_config) : {}
144
+
145
+ require 'logging'
146
+ register_logger StandardLogger.new(STDOUT)
147
+
146
148
  register_logger StandardLogger.new('logs/adhearsion.log')
147
149
 
148
150
  puts %{\nStarting Adhearsion v#{ADHEARSION_VERSION}
@@ -156,6 +158,7 @@ when 'start'
156
158
  require 'adhearsion'
157
159
  require 'database' if CONFIG['enable_database']
158
160
  require 'servlet_container'
161
+ require "constants"
159
162
 
160
163
  # Load appropriate helpers
161
164
  $HELPERS = {}
@@ -16,3 +16,8 @@ port: 4573
16
16
  # state: Texas
17
17
  # zip: 77777
18
18
  # country: United States
19
+
20
+ # conferences:
21
+ # management: 1000
22
+ # marketing: 1001
23
+ # development: 1002
@@ -0,0 +1 @@
1
+ enabled: false
@@ -0,0 +1,34 @@
1
+ =begin Adhearsion metadata
2
+ name: Number Metadata Lookup
3
+ author: Jay Phillips
4
+ =end
5
+
6
+ require "hpricot"
7
+ require "open-uri"
8
+
9
+ def lookup number
10
+ hash = {}
11
+ url = "http://www.whitepages.com/9901/search/ReversePhone?phone=#{number}"
12
+ doc = Hpricot open(url)
13
+
14
+ # This div contains all the information we need
15
+ results = doc.at "#results_single_listing"
16
+
17
+ # This div's h3 contains the name of the caller
18
+ hash[:first_name], hash[:last_name] = results.at('h3').inner_html.split(/,\s*/).reverse
19
+
20
+ # Now we just need the rest of the information contained in p's.
21
+ meta = results/'p'
22
+ meta.pop # Discard the useless p element
23
+
24
+ hash[:number] = meta.pop.inner_html
25
+ city_info = meta.pop.inner_html
26
+ city_info = city_info.match /(.+), ([A-Za-z]{2}) (\d{5})/
27
+ hash[:city] = city_info[1]
28
+ hash[:state] = city_info[2]
29
+ hash[:zip] = city_info[3]
30
+
31
+ hash[:address] = meta.map(&:inner_html) * " "
32
+
33
+ hash
34
+ end
@@ -89,7 +89,7 @@ module Asterisk
89
89
  # within it will be recorded. If no arguments are given, a String
90
90
  # for the filename will be generated from the current time and a
91
91
  # sequence of random alphanumeric characters.
92
- def record hash, &block
92
+ def record hash={}, &block
93
93
  defaults = {:file => "#{String.random(5)}", :folder => nil,
94
94
  :channel => Thread.current[:VARS]['channel'], :format => 'wav', :mix => '1'}
95
95
  defaults = defaults.merge hash
@@ -109,7 +109,7 @@ module Asterisk
109
109
  return digit.chr if [32,45].include? digit
110
110
  digit - ?0
111
111
  end
112
-
112
+
113
113
  # An abstracted remote mutator for setting Asterisk variables.
114
114
  # You may optionally pass as a third argument ":normally" to
115
115
  # have the variable set with Set() instead of AGI.
@@ -127,10 +127,90 @@ module Asterisk
127
127
  result[0..12] == "200 result=0" ? default : result[13..-1]
128
128
  end
129
129
 
130
- def dial who, *options
131
- #group = who.group if who.respond_to :group
132
- exec :dial, properize(who)
130
+ # == Dialing Users
131
+ #
132
+ # This method will be used in most dial plans written with Adhearsion.
133
+ # The first argument is the destination which can be given in a number
134
+ # of syntactically sweet formats:
135
+ #
136
+ # - A "Group" of users. This is determined by whether the passed group
137
+ # responds to the +members+, +users+, +member+, or +user+ methods. If
138
+ # so, all members of that group will ring simultaneously. This would
139
+ # be especially useful for, say, technical support groups which all
140
+ # share the same line. When the first person picks up the line, the
141
+ # rest of the phones will stop ringing. The array of users supplied
142
+ # by one of the aforementioned methods can follow any of the
143
+ # standards below.
144
+ # - An Array of "Users".
145
+ # - A single "User". A User is defined by something that responds to the
146
+ # +extension+ or +extensions+ methods. The return value of these two
147
+ # methods can either be any of the following formats:
148
+ # - A String. The String can contain a simple number or be a fully
149
+ # qualified Asterisk-ready String. e.g. 'SIP/codemecca@sipphone'.
150
+ # - A Numeric or Symbol. In this case, the SIP technology is used by
151
+ # default. See the examples below.
152
+ #
153
+ # == Dialing Examples
154
+ #
155
+ # - dial 123 # => SIP/123
156
+ # - dial "123" # => SIP/123
157
+ # - dial SIP/123 # => SIP/123
158
+ # - dial "SIP/123" # => SIP/123
159
+ # - dial IAX/123 # => IAX2/123
160
+ # - dial IAX/:jay # => IAX2/jay
161
+ # - dial IAX2/123 # => IAX2/123
162
+ # - dial ZAP/123 # => Zap/123
163
+ # - dial Zap/:out # => Zap/out
164
+ # - dial :mikey # => SIP/mikey
165
+ # - dial SIP/:mikey # => SIP/mikey
166
+ # - dial "SIP/:mikey" # Don't do this
167
+ # - dial SIP/'mikey' # => SIP/mikey
168
+ # - dial 1_555_123_7890 # => SIP/1_555_123_7890
169
+ # - dial 'SIP/15551237890@sipphone' # => SIP/15551237890@sipphone
170
+ #
171
+ # Note, in the last example, the part following the @ sign is a section
172
+ # from sip.conf.
173
+ #
174
+ # == More complex usage
175
+ #
176
+ # If you should want to have the phone ring for only a pre-determined set
177
+ # of time (which you likely will to have the call redirect to voicemail for
178
+ # example), then a :for => 15.seconds type of syntax can be used. Examples:
179
+ #
180
+ # - dial :jay, :for => 2.minutes
181
+ #
182
+ # The result of the last call can be retrieved by using the dial plan
183
+ # methods +last_call_successful?+, +last_call_unsuccessful?+, or
184
+ # +last_dial_status+. Note: +last_dial_status+ returns a Symbol representing
185
+ # the result of the last call. For more information, see its appropriate
186
+ # documentation.
187
+ #
188
+ # Additionally, you can use the :options hash key argument to specify options
189
+ # which Asterisk's Dial() application normally takes. For example:
190
+ #
191
+ # - dial :jay, :for => 30.seconds, :options => 'tmw'
192
+ # - dial 1_444_555_6666, :options => 'S(30)'
193
+ #
194
+ # == Resources
195
+ #
196
+ # For more information, see the VoIP-Info.org page on dialing in Asterisk at
197
+ # http://www.voip-info.org/wiki-Asterisk+cmd+Dial
198
+ def dial who, hash={}
199
+ # if who.is_a_group? TODO: Set the CDR GROUP() value if a Group is dialed.
200
+ exec :dial, properize(who), *[hash[:for], hash[:options]]
133
201
  end
202
+
203
+ # As you might expect, last_call_successful? returns a boolean depending on whether
204
+ # the last call to dial() finished successfully. Success is determined only if the
205
+ # call was answered.
206
+ def last_call_successful?
207
+ last_dial_status == :answer
208
+ end
209
+
210
+ # The opposite of last_call_successful?. Here for syntactical sugar.
211
+ def last_call_unsuccessful?
212
+ !last_call_successful?
213
+ end
134
214
 
135
215
  # The stream_file() method comes right over from the AGI protocol.
136
216
  # Its use is very similar to the Background() application from
@@ -183,12 +263,15 @@ module Asterisk
183
263
  # Usage: voicemail :busy, 4544
184
264
  # or: voicemail 4544
185
265
  # or: voicemail 4544, :unavailable, :at => 'codemecca'
186
- def voicemail msg_or_who=nil, who_or_msg=nil, hash={}
187
- opts = [msg_or_who, who_or_msg]
188
- type = opts & [:normal, :busy, :unavailable]
189
- box = opts - type
190
- box.last <<= "@#{hash[:at]}}" if hash[:at]
191
- exec :Voicemail, *(type + box)
266
+ def voicemail *args
267
+ hash = args.last.is_a?(Hash) ? args.pop : {}
268
+ type = [:skip, :busy, :unavailable] & args
269
+
270
+ box = (args - type).to_s # Destination mailbox
271
+ box = type.map { |x| x.to_s[0].chr }.to_s + box
272
+ box += "@#{hash[:at]}" if hash[:at]
273
+
274
+ exec :Voicemail, box
192
275
  end
193
276
 
194
277
  # Execute VoiceMailMain behind the scenes to check a specified
@@ -203,6 +286,20 @@ module Asterisk
203
286
  exec :VoiceMailMain, args.compact
204
287
  end
205
288
 
289
+ # Used to join a particular conference with the MeetMe application. To
290
+ # use MeetMe, be sure you have a proper timing device configured on your
291
+ # Asterisk box. MeetMe is Asterisk's built-in conferencing program.
292
+ # More info: http://www.voip-info.org/wiki-Asterisk+cmd+MeetMe
293
+ def join conference=nil, hash={}
294
+ unless conference.kind_of? Numeric
295
+ raise ArgumentError, "If you want to use named conferences, " +
296
+ "specify them in adhearsion.yml" unless CONFIG['conferences']
297
+ conference = CONFIG['conferences'][conference.to_s]
298
+ end
299
+ exec :MeetMe, conference, hash[:options], hash[:pin]
300
+ end
301
+ alias meetme join
302
+
206
303
  # Play is a long-overdue easy way to play audio files in a dialplan with Asterisk. It can take a
207
304
  # single String of the filename (defaults to /var/lib/asterisk/sounds) just as you
208
305
  # would give it to Playback(), or it can take any number of trailed on Strings.
@@ -247,36 +344,27 @@ module Asterisk
247
344
  # wouldn't be used much outside of dial(), but you may find it useful.
248
345
  def properize who
249
346
  # These are the convention methods for Group-like objects
250
- possible_methods = [:users, :members, :user, :member].select do |pm|
251
- who.respond_to? pm
252
- end
347
+ group_method = who.is_a_group?
253
348
 
254
349
  # If 'who' has any of the possible_methods, replace 'who' with the return value
255
350
  # of that method
256
- who = who.send possible_methods.first if possible_methods.any?
351
+ who = who.send group_method if group_method
257
352
  return nil unless who
258
353
 
259
354
  # In case we can't perform collection algorithms on 'who', let's encapsulate it in
260
355
  # an Array
261
356
  who = [who] unless who.kind_of?(Enumerable) && !who.kind_of?(String)
262
357
 
358
+ user_method = who.first.is_a_user?
263
359
  # If the first thing in the Enumerable responds to a User-like convention, then
264
- # set 'who' equal to the extension accessor of those objects. We refine the "who"
360
+ # set 'who' equal to the extension(s) accessor of those objects. We refine the "who"
265
361
  # argument more and more in this way until it's finally in a way Asterisk can read.
266
- who.map! do |p|
267
- p.send possible_methods.first
268
- end.compact! if (possible_methods = [:extension, :extensions].select do |pm|
269
- who.first.respond_to? pm
270
- end).any?
362
+ who.map! { |p| p.send user_method }.compact! if user_method
271
363
 
272
364
  # Now replace each item in the Enumerable with its form converted to
273
365
  # extension (assuming it's not already in that format)
274
366
  who.map! do |ext|
275
- if ext.kind_of?(String) && ext.index(?/) then ext
276
- else
277
- ext = "1#{ext}" if ext.is_national_number? && ext.to_s[0] != ?1
278
- "SIP/#{ext}"
279
- end
367
+ (ext.kind_of?(String) && ext.index(?/)) ? ext : "SIP/#{ext}"
280
368
  end
281
369
  who * '&' # Finally, join() anything left in the Array with an '&'
282
370
  end
@@ -289,7 +377,7 @@ module Asterisk
289
377
  # probably doesn't exist. If :chanunavail, the callee
290
378
  # phone may not be registered.
291
379
  def last_dial_status
292
- get_variable(:DIALSTATUS).downcase.to_sym
380
+ get_variable(:DIALSTATUS)[1..-2].downcase.to_sym
293
381
  end
294
382
 
295
383
  # Answer the channel. Adhearsion is configured by default to automatically do this
@@ -301,41 +389,49 @@ module Asterisk
301
389
  # Direct translation of the Asterisk NoOp() application. Used primarily for
302
390
  # viewing debug information in the Asterisk CLI.
303
391
  def noop(*options) rawr "NOOP #{options}" end
392
+ end
304
393
 
305
- # This SIP class abstracts several SIP-related functions. In your dialplan,
306
- # if you should want to set a SIP header specifically, simply use the class
307
- # []= operator. For example, you may want to do SIP['Alert-Info'] = 'Ring-Answer'
308
- # which will affect the next SIP call placed. Additionally, you can use this
309
- # class's division operator to naturally represent "technology/channel"
310
- # endpoints (e.g. SIP/1550 or SIP/:tweedledum)
311
- class SIP
312
- def self.[](header)
313
- exec
314
- end
315
- def self.[]=(header, value)
316
- exec :SipAddHeader, "#{header}: #{value}"
317
- end
318
- def self./(ext) "SIP/#{ext}" end
319
- end
320
-
321
- class IAX
322
- def self.[](arg=nil) IAX(arg) end
323
- def self./(arg=nil) IAX(arg) end
324
- end
325
-
394
+ # This SIP class abstracts several SIP-related functions. In your dialplan,
395
+ # if you should want to set a SIP header specifically, simply use the class
396
+ # []= operator. For example, you may want to do SIP['Alert-Info'] = 'Ring-Answer'
397
+ # which will affect the next SIP call placed. Additionally, you can use this
398
+ # class's division operator to naturally represent "technology/channel"
399
+ # endpoints (e.g. SIP/1550 or SIP/:tweedledum)
400
+ class SIP
326
401
 
327
- class ZAP
328
- def self.[](arg=nil) ZAP(arg) end
329
- def self./(arg=nil) ZAP(arg) end
330
- end
402
+ # This will set the header value specified within the square bracked to the
403
+ # value given after the equals sign. Note: this can only be called if the
404
+ # current call's thread is handling an Asterisk call over AGI (i.e. dialplan).
405
+ def self.[]=(header, value)
406
+ exec :SipAddHeader, "#{header}: #{value}"
407
+ end
408
+
409
+ # Simple convenience method to make Adhearsion's DSL more Asterisk-like.
410
+ # Virtually anything can be provided after the "/", as long as its to_s()
411
+ # method is what you intended to represent.
412
+ def self./(ext) "SIP/#{ext}" end
413
+ end
331
414
 
332
- # For users who may try to use the (proper) IAX2 form. See IAX for more info.
333
- class IAX2 < IAX; end
415
+ class IAX
416
+ # Simple convenience method to make Adhearsion's DSL more Asterisk-like.
417
+ # Virtually anything can be provided after the "/", as long as its to_s()
418
+ # method is what you intended to represent.
419
+ def self./(arg=nil) IAX(arg) end
420
+ end
334
421
 
335
- # For users who may try to use the (common) "Zap" form. See ZAP for more info.
336
- class Zap < ZAP; end
422
+ class ZAP
423
+ # Simple convenience method to make Adhearsion's DSL more Asterisk-like.
424
+ # Virtually anything can be provided after the "/", as long as its to_s()
425
+ # method is what you intended to represent.
426
+ def self./(arg=nil) ZAP(arg) end
337
427
  end
338
428
 
429
+ # For users who may try to use the (proper) IAX2 form. See IAX for more info.
430
+ class IAX2 < IAX; end
431
+
432
+ # For users who may try to use the (common) "Zap" form. See ZAP for more info.
433
+ class Zap < ZAP; end
434
+
339
435
  # The PBX object is an object manifestation of the PBX with which Adhearsion will be
340
436
  # associated. Helpers often open up this class and add methods to it. Note: when doing
341
437
  # this in your own helpers, all methods will need to be class (a.k.a. static) methods
@@ -17,4 +17,4 @@
17
17
 
18
18
  # Please help adjust these if they may be inaccurate!
19
19
  LOCAL_NUMBER = /^[1-9]\d{6}$/
20
- US_NUMBER = /^1?[1-9]\d{2})?[1-9]\d{6}$/
20
+ US_NUMBER = /^1?[1-9]\d{2}[1-9]\d{6}$/
@@ -31,10 +31,12 @@ class Object
31
31
  self
32
32
  end
33
33
  def is_a_group?
34
- # TODO: check if it responds to the conventions.
34
+ [:users, :members, :user, :member].each { |x| return x if respond_to? x }
35
+ nil
35
36
  end
36
37
  def is_a_user?
37
- # TODO: check if it responds to the conventions.
38
+ [:extension, :extensions].each { |x| return x if respond_to? x }
39
+ nil
38
40
  end
39
41
 
40
42
  def is_local_number?
@@ -42,7 +44,7 @@ class Object
42
44
  end
43
45
 
44
46
  def is_national_number?
45
- to_s =~ national_number
47
+ to_s =~ US_NUMBER
46
48
  end
47
49
 
48
50
  def mutex() @mutex ||= Mutex.new end
@@ -97,6 +97,11 @@ class ServletContainer
97
97
  end
98
98
 
99
99
  log "Parsing of extensions.rb complete"
100
+
101
+ # Because Asterisk allows dashes in its context names and Ruby interprets
102
+ # these as minuses, let's convert them to underscores.
103
+ call_variables['context'].gsub! '-', '_'
104
+
100
105
  begin
101
106
  target_context = call_variables['context']
102
107
  if target_context
@@ -127,8 +132,8 @@ class ServletContainer
127
132
  detail.backtrace.each do |msg| log " "*8 << msg end
128
133
  end
129
134
 
130
- [$AFTER_CALl_HIGH, $AFTER_CALL, $AFTER_CALL_LOW].flatten.compact.each &:call
131
- +lambda { hangup if CONFIG.hangup_after_call }
135
+ [$AFTER_CALL_HIGH, $AFTER_CALL, $AFTER_CALL_LOW].flatten.compact.each &:call
136
+ +lambda { hangup if CONFIG['hangup_after_call'] }
132
137
  end
133
138
  end
134
139
 
@@ -0,0 +1,14 @@
1
+ context "The Asterisk module"
2
+ specify "should properize properly" do
3
+ properize("123").should == 'SIP/123'
4
+ properize(1_555_444_1234).should == 'SIP/15554441234'
5
+ properize(:jay).should == 'SIP/jay'
6
+ properize("jay").should == 'SIP/jay'
7
+ properize("SIP/123").should == 'SIP/123'
8
+ properize("IAX2/jay").should == 'IAX2/jay'
9
+ properize((100..110).to_a).should == 'SIP/100&SIP/101&SIP/102&SIP/103&SIP/104&SIP/105&SIP/106&SIP/107&SIP/108&SIP/109&SIP/110'
10
+ properize(["SIP/123", "SIP/456"]).should == 'SIP/123&SIP/456'
11
+ # TODO: Should mock up dialing a user
12
+ # TODO: Should mock up dialing a group
13
+ end
14
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: adhearsion
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.7.4
7
- date: 2007-01-20 00:00:00 -06:00
6
+ version: 0.7.5
7
+ date: 2007-02-10 00:00:00 -06:00
8
8
  summary: Adhearsion is a professional integration system for integrating anything and everything.
9
9
  require_paths:
10
10
  - lib
@@ -31,10 +31,10 @@ authors:
31
31
  files:
32
32
  - ahn
33
33
  - apps
34
+ - CHANGELOG
34
35
  - docs
35
36
  - lib
36
37
  - LICENSE
37
- - pkg
38
38
  - Rakefile
39
39
  - test
40
40
  - apps/codemeccollab
@@ -52,6 +52,7 @@ files:
52
52
  - apps/default/config/migration.rb
53
53
  - apps/default/config/helpers/drb_server.yml
54
54
  - apps/default/config/helpers/factorial.alien.c.yml
55
+ - apps/default/config/helpers/lookup.yml
55
56
  - apps/default/config/helpers/manager_proxy.yml
56
57
  - apps/default/config/helpers/micromenus
57
58
  - apps/default/config/helpers/micromenus.yml
@@ -75,6 +76,7 @@ files:
75
76
  - apps/default/config/helpers/micromenus/stylesheets/firefox.xul.css
76
77
  - apps/default/helpers/drb_server.rb
77
78
  - apps/default/helpers/factorial.alien.c
79
+ - apps/default/helpers/lookup.rb
78
80
  - apps/default/helpers/manager_proxy.rb
79
81
  - apps/default/helpers/micromenus.rb
80
82
  - apps/default/helpers/multi_messenger.rb
@@ -86,10 +88,10 @@ files:
86
88
  - lib/adhearsion.rb
87
89
  - lib/constants.rb
88
90
  - lib/core_extensions.rb
89
- - lib/database_functions.rb
90
91
  - lib/logging.rb
91
92
  - lib/rami.rb
92
93
  - lib/servlet_container.rb
94
+ - test/asterisk_module_test.rb
93
95
  - test/core_extensions_test.rb
94
96
  - test/dial_test.rb
95
97
  - test/test_micromenus.rb
@@ -1,76 +0,0 @@
1
- # Adhearsion, open source technology integrator
2
- # Copyright 2006 Jay Phillips
3
- #
4
- # This program is free software; you can redistribute it and/or
5
- # modify it under the terms of the GNU General Public License
6
- # as published by the Free Software Foundation; either version 2
7
- # of the License, or (at your option) any later version.
8
- #
9
- # This program is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with this program; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
-
18
- class Definition
19
-
20
- def initialize(*constraints)
21
- @options = {}
22
- if constraints then @constraints = constraints.flatten!
23
- else @constraints = []
24
- end
25
- end
26
-
27
- attr_reader :options
28
-
29
- # The method_missing method is a crown-jewel of Ruby. When a method is
30
- # called on an object that doesn't exist, Ruby will invoke the method_missing
31
- # method. The Kernel module holds the initial definition of this method and
32
- # the Ruby interpreter raises a NameError when Kernel#method_missing is
33
- # invoked.
34
- def method_missing(name, *args)
35
- # Let's ensure the names stay simple
36
- super unless name.to_s =~ /^[a-z][\w_]*=?$/i || args.empty?
37
- @options[name] = args.simplify
38
- end
39
- end
40
-
41
- # The user(), group() and use_users_and_group() methods are presently alpha and
42
- # really shouldn't be used yet. They're experimental ways of establishing user
43
- # and group objects in the database.rb file.
44
-
45
- def user &options
46
- establish_connection :internal
47
- her = Definition.new
48
- yield her
49
- User.create her.options
50
- end
51
-
52
- def group &options
53
- establish_connection :internal
54
- her = Definition.new
55
- yield her
56
- Group.create her.options
57
- end
58
-
59
- def use_users_and_groups clause
60
- estabish_connection :external
61
- case clause.class.inspect.to_sym
62
- when :Hash
63
- group_table = clause[:from].delete :group_table
64
- user_table = clause[:from].delete :user_table
65
- # XXX: Note: User.table doesn't exist! Needs fixing!
66
- User.table = user_table if user_table
67
- Group.table = group_table if group_table
68
-
69
- establish_connection :external, clause[:from]
70
- when :String || :File
71
- clause = File.open clause, 'a' if clause.is_a? String
72
- raise ArgumentError.new("Not a directory!") unless clause.directory?
73
- else raise ArgumentError.new("Wrong argument type!")
74
- end
75
- end
76
- alias use_groups_and_users use_users_and_groups