adhearsion 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/CHANGELOG +11 -2
  2. data/EVENTS +1 -1
  3. data/Rakefile +4 -4
  4. data/adhearsion.gemspec +8 -4
  5. data/app_generators/ahn/USAGE +3 -3
  6. data/app_generators/ahn/ahn_generator.rb +11 -11
  7. data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +3 -3
  8. data/app_generators/ahn/templates/components/disabled/restful_rpc/example-client.rb +6 -6
  9. data/app_generators/ahn/templates/components/disabled/restful_rpc/restful_rpc.rb +16 -16
  10. data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +42 -42
  11. data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.rb +11 -11
  12. data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +1 -1
  13. data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +6 -6
  14. data/app_generators/ahn/templates/components/simon_game/simon_game.rb +4 -4
  15. data/app_generators/ahn/templates/config/startup.rb +31 -16
  16. data/bin/ahn +3 -3
  17. data/bin/ahnctl +8 -8
  18. data/bin/jahn +3 -3
  19. data/examples/asterisk_manager_interface/standalone.rb +2 -2
  20. data/lib/adhearsion.rb +4 -2
  21. data/lib/adhearsion/cli.rb +31 -31
  22. data/lib/adhearsion/component_manager.rb +39 -39
  23. data/lib/adhearsion/component_manager/component_tester.rb +14 -14
  24. data/lib/adhearsion/component_manager/spec_framework.rb +1 -1
  25. data/lib/adhearsion/events_support.rb +12 -12
  26. data/lib/adhearsion/foundation/blank_slate.rb +1 -1
  27. data/lib/adhearsion/foundation/custom_daemonizer.rb +2 -2
  28. data/lib/adhearsion/foundation/event_socket.rb +26 -26
  29. data/lib/adhearsion/foundation/future_resource.rb +6 -6
  30. data/lib/adhearsion/foundation/metaprogramming.rb +2 -2
  31. data/lib/adhearsion/foundation/numeric.rb +3 -3
  32. data/lib/adhearsion/foundation/relationship_properties.rb +7 -7
  33. data/lib/adhearsion/foundation/string.rb +8 -8
  34. data/lib/adhearsion/foundation/synchronized_hash.rb +8 -8
  35. data/lib/adhearsion/host_definitions.rb +16 -16
  36. data/lib/adhearsion/initializer.rb +74 -65
  37. data/lib/adhearsion/initializer/asterisk.rb +15 -9
  38. data/lib/adhearsion/initializer/configuration.rb +54 -39
  39. data/lib/adhearsion/initializer/database.rb +4 -4
  40. data/lib/adhearsion/initializer/drb.rb +6 -6
  41. data/lib/adhearsion/initializer/freeswitch.rb +1 -1
  42. data/lib/adhearsion/initializer/ldap.rb +51 -0
  43. data/lib/adhearsion/initializer/rails.rb +8 -8
  44. data/lib/adhearsion/logging.rb +16 -16
  45. data/lib/adhearsion/tasks/deprecations.rb +12 -12
  46. data/lib/adhearsion/tasks/generating.rb +2 -2
  47. data/lib/adhearsion/tasks/testing.rb +7 -7
  48. data/lib/adhearsion/version.rb +1 -1
  49. data/lib/adhearsion/voip/asterisk/agi_server.rb +44 -14
  50. data/lib/adhearsion/voip/asterisk/commands.rb +281 -237
  51. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +8 -8
  52. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +14 -14
  53. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +16 -16
  54. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +39 -39
  55. data/lib/adhearsion/voip/asterisk/config_manager.rb +13 -13
  56. data/lib/adhearsion/voip/asterisk/manager_interface.rb +91 -87
  57. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +739 -739
  58. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +60 -60
  59. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +16 -16
  60. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +1 -1
  61. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +13 -13
  62. data/lib/adhearsion/voip/asterisk/super_manager.rb +3 -3
  63. data/lib/adhearsion/voip/call.rb +101 -64
  64. data/lib/adhearsion/voip/call_routing.rb +9 -9
  65. data/lib/adhearsion/voip/constants.rb +7 -7
  66. data/lib/adhearsion/voip/conveniences.rb +1 -1
  67. data/lib/adhearsion/voip/dial_plan.rb +42 -40
  68. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +27 -27
  69. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +1 -1
  70. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +6 -6
  71. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +17 -17
  72. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +7 -7
  73. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +2 -2
  74. data/lib/adhearsion/voip/dsl/numerical_string.rb +3 -3
  75. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +7 -7
  76. data/lib/adhearsion/voip/freeswitch/event_handler.rb +1 -1
  77. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +20 -20
  78. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +5 -5
  79. data/lib/adhearsion/voip/freeswitch/oes_server.rb +33 -33
  80. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +1 -1
  81. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +2 -2
  82. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +9 -9
  83. data/lib/theatre.rb +18 -18
  84. data/lib/theatre/callback_definition_loader.rb +17 -17
  85. data/lib/theatre/guid.rb +6 -6
  86. data/lib/theatre/invocation.rb +19 -19
  87. data/lib/theatre/namespace_manager.rb +28 -28
  88. metadata +55 -14
@@ -3,14 +3,14 @@ module Adhearsion
3
3
  module CallRouting
4
4
  class Rule
5
5
  attr_reader :patterns, :providers, :options
6
-
6
+
7
7
  def initialize(*args, &block)
8
8
  @options = args.pop
9
9
  @patterns = Array(args)
10
10
  @providers = Array(options[:to])
11
11
  end
12
12
  end
13
-
13
+
14
14
  class RuleSet < Array
15
15
  def [](index)
16
16
  case index
@@ -25,36 +25,36 @@ module Adhearsion
25
25
  end
26
26
  end
27
27
  end
28
-
28
+
29
29
  class Router
30
30
  class << self
31
31
  attr_accessor :rules
32
-
32
+
33
33
  def define(&block)
34
34
  returning new do |router|
35
35
  router.define(&block)
36
36
  rules.concat router.rules
37
37
  end
38
38
  end
39
-
39
+
40
40
  def calculate_route_for(end_point)
41
41
  if rule = rules[end_point.to_s]
42
42
  rule.providers
43
43
  end
44
44
  end
45
45
  end
46
-
46
+
47
47
  self.rules ||= RuleSet.new
48
-
48
+
49
49
  attr_reader :rules
50
50
  def initialize
51
51
  @rules = []
52
52
  end
53
-
53
+
54
54
  def define(&block)
55
55
  instance_eval(&block)
56
56
  end
57
-
57
+
58
58
  def route(*args, &block)
59
59
  rules << Rule.new(*args, &block)
60
60
  end
@@ -1,30 +1,30 @@
1
1
  # Adhearsion, open source collaboration framework
2
2
  # Copyright (C) 2006,2007,2008 Jay Phillips
3
- #
3
+ #
4
4
  # This library is free software; you can redistribute it and/or
5
5
  # modify it under the terms of the GNU Lesser General Public
6
6
  # License as published by the Free Software Foundation; either
7
7
  # version 2.1 of the License, or (at your option) any later version.
8
- #
8
+ #
9
9
  # This library is distributed in the hope that it will be useful,
10
10
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
12
  # Lesser General Public License for more details.
13
- #
13
+ #
14
14
  # You should have received a copy of the GNU Lesser General Public
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  module Adhearsion
19
19
  module VoIP
20
-
20
+
21
21
  # Please help adjust these if they may be inaccurate!
22
22
  module Constants
23
23
  US_LOCAL_NUMBER = /^[1-9]\d{6}$/
24
24
  US_NATIONAL_NUMBER = /^1?[1-9]\d{2}[1-9]\d{6}$/
25
25
  ISN = /^\d+\*\d+$/ # See http://freenum.org
26
26
  SIP_URI = /^sip:[\w\._%+-]+@[\w\.-]+\.[a-zA-Z]{2,4}$/
27
-
27
+
28
28
  # Type of Number definitions given over PRI. Taken from the Q.931-ITU spec, page 68.
29
29
  Q931_TYPE_OF_NUMBER = Hash.new(:unknown).merge 0b001 => :international,
30
30
  0b010 => :national,
@@ -32,8 +32,8 @@ module Adhearsion
32
32
  0b100 => :subscriber,
33
33
  0b110 => :abbreviated_number
34
34
  end
35
-
35
+
36
36
  include Constants
37
-
37
+
38
38
  end
39
39
  end
@@ -1,7 +1,7 @@
1
1
  module Adhearsion
2
2
  module VoIP
3
3
  module Conveniences
4
-
4
+
5
5
  # Compiles the provided Asterisk dialplan pattern into a Ruby regular
6
6
  # expression. For more usage of Asterisk's pattern syntax, see
7
7
  # http://www.voip-info.org/wiki/view/Asterisk+Dialplan+Patterns
@@ -8,30 +8,30 @@ module Adhearsion
8
8
  @loader = loader
9
9
  @entry_points = @loader.load_dialplans.contexts
10
10
  end
11
-
11
+
12
12
  ##
13
13
  # Lookup and return an entry point by context name
14
14
  #
15
15
  def lookup(context_name)
16
16
  entry_points[context_name]
17
17
  end
18
-
18
+
19
19
  ##
20
20
  # Executable environment for a dial plan in the scope of a call. This class has all the dialplan methods mixed into it.
21
21
  #
22
22
  class ExecutionEnvironment
23
-
23
+
24
24
  class << self
25
25
  def create(*args)
26
26
  returning(new(*args)) { |instance| instance.stage! }
27
27
  end
28
28
  end
29
-
29
+
30
30
  attr_reader :call
31
31
  def initialize(call, entry_point)
32
32
  @call, @entry_point = call, entry_point
33
33
  end
34
-
34
+
35
35
  ##
36
36
  # Adds the methods to this ExecutionEnvironment which make it useful. e.g. dialplan-related methods, call variables,
37
37
  # and component methods.
@@ -41,7 +41,7 @@ module Adhearsion
41
41
  extend_with_call_variables!
42
42
  extend_with_dialplan_component_methods!
43
43
  end
44
-
44
+
45
45
  def run
46
46
  raise "Cannot run ExecutionEnvironment without an entry point!" unless entry_point
47
47
  current_context = entry_point
@@ -53,59 +53,61 @@ module Adhearsion
53
53
  retry
54
54
  end
55
55
  end
56
-
56
+
57
57
  protected
58
58
 
59
59
  attr_reader :entry_point
60
+
61
+
60
62
  def extend_with_voip_commands!
61
63
  extend Adhearsion::VoIP::Conveniences
62
64
  extend Adhearsion::VoIP::Commands.for(call.originating_voip_platform)
63
65
  end
64
-
66
+
65
67
  def extend_with_call_variables!
66
68
  call.define_variable_accessors self
67
69
  end
68
-
69
- def extend_with_dialplan_component_methods!
70
+
71
+ def extend_with_dialplan_component_methods!
70
72
  Components.component_manager.extend_object_with(self, :dialplan) if Components.component_manager
71
73
  end
72
-
74
+
73
75
  end
74
-
76
+
75
77
  class Manager
76
-
78
+
77
79
  class NoContextError < Exception; end
78
-
80
+
79
81
  class << self
80
82
  def handle(call)
81
83
  new.handle(call)
82
84
  end
83
85
  end
84
-
86
+
85
87
  attr_accessor :dial_plan, :context
86
88
  def initialize
87
89
  @dial_plan = DialPlan.new
88
90
  end
89
-
91
+
90
92
  def handle(call)
91
93
  if call.failed_call?
92
94
  environment = ExecutionEnvironment.create(call, nil)
93
95
  call.extract_failed_reason_from environment
94
96
  raise FailedExtensionCallException.new(environment)
95
97
  end
96
-
98
+
97
99
  if call.hungup_call?
98
100
  raise HungupExtensionCallException.new(ExecutionEnvironment.new(call, nil))
99
101
  end
100
-
102
+
101
103
  starting_entry_point = entry_point_for call
102
104
  raise NoContextError, "No dialplan entry point for call context '#{call.context}' -- Ignoring call!" unless starting_entry_point
103
105
  @context = ExecutionEnvironment.create(call, starting_entry_point)
104
106
  inject_context_names_into_environment @context
105
107
  @context.run
106
108
  end
107
-
108
- # Find the dialplan by the context name from the call or from the
109
+
110
+ # Find the dialplan by the context name from the call or from the
109
111
  # first path entry in the AGI URL
110
112
  def entry_point_for(call)
111
113
  if entry_point = dial_plan.lookup(call.context.to_sym)
@@ -114,22 +116,22 @@ module Adhearsion
114
116
  dial_plan.lookup(m[1].to_sym)
115
117
  end
116
118
  end
117
-
119
+
118
120
  protected
119
-
121
+
120
122
  def inject_context_names_into_environment(environment)
121
123
  return unless dial_plan.entry_points
122
124
  dial_plan.entry_points.each do |name, context|
123
125
  environment.meta_def(name) { context }
124
126
  end
125
127
  end
126
-
128
+
127
129
  end
128
-
130
+
129
131
  class Loader
130
132
  class << self
131
133
  attr_accessor :default_dial_plan_file_name
132
-
134
+
133
135
  def load(dial_plan_as_string)
134
136
  string_io = StringIO.new dial_plan_as_string
135
137
  def string_io.path
@@ -137,7 +139,7 @@ module Adhearsion
137
139
  end
138
140
  load_dialplans string_io
139
141
  end
140
-
142
+
141
143
  def load_dialplans(*files)
142
144
  files = Adhearsion::AHN_CONFIG.files_from_setting("paths", "dialplan") if files.empty?
143
145
  files = Array files
@@ -157,27 +159,27 @@ module Adhearsion
157
159
  end
158
160
  end
159
161
  end
160
-
162
+
161
163
  end
162
-
164
+
163
165
  self.default_dial_plan_file_name ||= 'dialplan.rb'
164
166
 
165
167
  def initialize
166
168
  @context_collector = ContextNameCollector.new
167
169
  end
168
-
170
+
169
171
  def contexts
170
172
  @context_collector.contexts
171
173
  end
172
-
174
+
173
175
  def load(dialplan_file)
174
176
  dialplan_code = dialplan_file.read
175
177
  @context_collector.instance_eval(dialplan_code, dialplan_file.path)
176
178
  nil
177
179
  end
178
-
180
+
179
181
  class ContextNameCollector# < ::BlankSlate
180
-
182
+
181
183
  class << self
182
184
 
183
185
  def const_missing(name)
@@ -185,34 +187,34 @@ module Adhearsion
185
187
  rescue ArgumentError
186
188
  raise NameError, %(undefined constant "#{name}")
187
189
  end
188
-
190
+
189
191
  end
190
-
192
+
191
193
  attr_reader :contexts
192
194
  def initialize
193
195
  @contexts = {}
194
196
  end
195
-
197
+
196
198
  def method_missing(name, *args, &block)
197
199
  super if !block_given? || args.any?
198
200
  contexts[name] = DialplanContextProc.new(name, &block)
199
201
  end
200
-
202
+
201
203
  end
202
204
  end
203
205
  class DialplanContextProc < Proc
204
-
206
+
205
207
  attr_reader :name
206
-
208
+
207
209
  def initialize(name, &block)
208
210
  super(&block)
209
211
  @name = name
210
212
  end
211
-
213
+
212
214
  def +@
213
215
  raise Adhearsion::VoIP::DSL::Dialplan::ControlPassingException.new(self)
214
216
  end
215
-
217
+
216
218
  end
217
219
  end
218
220
  end
@@ -1,16 +1,16 @@
1
1
  # Adhearsion, open source collaboration framework
2
2
  # Copyright (C) 2006,2007,2008 Jay Phillips
3
- #
3
+ #
4
4
  # This library is free software; you can redistribute it and/or
5
5
  # modify it under the terms of the GNU Lesser General Public
6
6
  # License as published by the Free Software Foundation; either
7
7
  # version 2.1 of the License, or (at your option) any later version.
8
- #
8
+ #
9
9
  # This library is distributed in the hope that it will be useful,
10
10
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
12
  # Lesser General Public License for more details.
13
- #
13
+ #
14
14
  # You should have received a copy of the GNU Lesser General Public
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -24,14 +24,14 @@ module Adhearsion
24
24
  module VoIP
25
25
  module DSL
26
26
  class DialingDSL
27
-
27
+
28
28
  extend Conveniences
29
29
  include Constants
30
-
30
+
31
31
  Regexp.class_eval do
32
32
  include Adhearsion::VoIP::DSL::DialingDSL::MonkeyPatches::RegexpMonkeyPatch
33
33
  end
34
-
34
+
35
35
  def self.inherited(klass)
36
36
  klass.class_eval do
37
37
  [:@@providers, :@@routes].each do |var|
@@ -40,23 +40,23 @@ module Adhearsion
40
40
  end
41
41
  end
42
42
  end
43
-
43
+
44
44
  def self.calculate_routes_for(destination)
45
45
  destination = destination.to_s
46
46
  routes.select { |defined_route| defined_route === destination }.map &:providers
47
47
  end
48
-
48
+
49
49
  class ProviderDefinition < OpenStruct
50
-
50
+
51
51
  def initialize(name)
52
52
  super()
53
53
  self.name = name.to_s.to_sym
54
54
  end
55
-
55
+
56
56
  def >>(other)
57
57
  RouteRule.new :providers => [self, other]
58
58
  end
59
-
59
+
60
60
  def format_number_for_platform(number, platform=:asterisk)
61
61
  case platform
62
62
  when :asterisk
@@ -65,7 +65,7 @@ module Adhearsion
65
65
  raise "Unsupported platform #{platform}!"
66
66
  end
67
67
  end
68
-
68
+
69
69
  def format_number_for_platform(number, platform=:asterisk)
70
70
  case platform
71
71
  when :asterisk
@@ -74,50 +74,50 @@ module Adhearsion
74
74
  raise "Unsupported platform #{platform}!"
75
75
  end
76
76
  end
77
-
77
+
78
78
  def defined_properties_without_name
79
79
  returning @table.clone do |copy|
80
80
  copy.delete :name
81
81
  end
82
82
  end
83
-
83
+
84
84
  end
85
-
85
+
86
86
  protected
87
87
 
88
88
  def self.provider(name, &block)
89
89
  raise ArgumentError, "no block given" unless block_given?
90
-
90
+
91
91
  options = ProviderDefinition.new name
92
92
  yield options
93
-
93
+
94
94
  providers << options
95
95
  meta_def(name) { options }
96
96
  end
97
-
97
+
98
98
  def self.route(route)
99
99
  routes << route
100
100
  end
101
-
101
+
102
102
  class RouteRule
103
-
103
+
104
104
  attr_reader :patterns, :providers
105
105
 
106
106
  def initialize(hash={})
107
107
  @patterns = Array hash[:patterns]
108
108
  @providers = Array hash[:providers]
109
109
  end
110
-
110
+
111
111
  def merge!(other)
112
112
  providers.concat other.providers
113
113
  patterns.concat other.patterns
114
114
  self
115
115
  end
116
-
116
+
117
117
  def >>(other)
118
118
  case other
119
- when RouteRule: merge! other
120
- when ProviderDefinition: providers << other
119
+ when RouteRule then merge! other
120
+ when ProviderDefinition then providers << other
121
121
  else raise RouteException, "Unrecognized object in route definition: #{other.inspect}"
122
122
  end
123
123
  self
@@ -125,19 +125,19 @@ module Adhearsion
125
125
 
126
126
  def |(other)
127
127
  case other
128
- when RouteRule: merge! other
128
+ when RouteRule then merge! other
129
129
  when Regexp
130
130
  patterns << other
131
131
  self
132
132
  else raise other.inspect
133
133
  end
134
134
  end
135
-
135
+
136
136
  def ===(other)
137
137
  patterns.each { |pattern| return true if pattern === other }
138
138
  false
139
139
  end
140
-
140
+
141
141
  def unshift_pattern(pattern)
142
142
  patterns.unshift pattern
143
143
  end