sant0sk1-adhearsion 0.7.999

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/LICENSE +456 -0
  2. data/README.txt +5 -0
  3. data/Rakefile +75 -0
  4. data/adhearsion.gemspec +136 -0
  5. data/app_generators/ahn/USAGE +5 -0
  6. data/app_generators/ahn/ahn_generator.rb +77 -0
  7. data/app_generators/ahn/templates/.ahnrc +36 -0
  8. data/app_generators/ahn/templates/README +8 -0
  9. data/app_generators/ahn/templates/Rakefile +18 -0
  10. data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
  11. data/app_generators/ahn/templates/components/simon_game/lib/simon_game.rb +61 -0
  12. data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +14 -0
  13. data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +31 -0
  14. data/app_generators/ahn/templates/config/startup.rb +53 -0
  15. data/app_generators/ahn/templates/dialplan.rb +4 -0
  16. data/bin/ahn +28 -0
  17. data/bin/ahnctl +68 -0
  18. data/bin/jahn +32 -0
  19. data/lib/adhearsion.rb +32 -0
  20. data/lib/adhearsion/blank_slate.rb +5 -0
  21. data/lib/adhearsion/cli.rb +106 -0
  22. data/lib/adhearsion/component_manager.rb +277 -0
  23. data/lib/adhearsion/core_extensions/all.rb +9 -0
  24. data/lib/adhearsion/core_extensions/array.rb +0 -0
  25. data/lib/adhearsion/core_extensions/custom_daemonizer.rb +45 -0
  26. data/lib/adhearsion/core_extensions/global.rb +1 -0
  27. data/lib/adhearsion/core_extensions/hash.rb +0 -0
  28. data/lib/adhearsion/core_extensions/metaprogramming.rb +17 -0
  29. data/lib/adhearsion/core_extensions/numeric.rb +4 -0
  30. data/lib/adhearsion/core_extensions/proc.rb +0 -0
  31. data/lib/adhearsion/core_extensions/publishable.rb +73 -0
  32. data/lib/adhearsion/core_extensions/relationship_properties.rb +40 -0
  33. data/lib/adhearsion/core_extensions/string.rb +26 -0
  34. data/lib/adhearsion/core_extensions/thread.rb +13 -0
  35. data/lib/adhearsion/core_extensions/thread_safety.rb +7 -0
  36. data/lib/adhearsion/core_extensions/time.rb +0 -0
  37. data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
  38. data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
  39. data/lib/adhearsion/distributed/gateways/rest_gateway.rb +9 -0
  40. data/lib/adhearsion/distributed/gateways/soap_gateway.rb +9 -0
  41. data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +9 -0
  42. data/lib/adhearsion/distributed/peer_finder.rb +0 -0
  43. data/lib/adhearsion/distributed/remote_cli.rb +0 -0
  44. data/lib/adhearsion/events_support.rb +26 -0
  45. data/lib/adhearsion/hooks.rb +57 -0
  46. data/lib/adhearsion/host_definitions.rb +63 -0
  47. data/lib/adhearsion/initializer.rb +246 -0
  48. data/lib/adhearsion/initializer/asterisk.rb +59 -0
  49. data/lib/adhearsion/initializer/configuration.rb +236 -0
  50. data/lib/adhearsion/initializer/database.rb +49 -0
  51. data/lib/adhearsion/initializer/drb.rb +25 -0
  52. data/lib/adhearsion/initializer/freeswitch.rb +22 -0
  53. data/lib/adhearsion/initializer/rails.rb +40 -0
  54. data/lib/adhearsion/logging.rb +92 -0
  55. data/lib/adhearsion/tasks.rb +15 -0
  56. data/lib/adhearsion/tasks/database.rb +5 -0
  57. data/lib/adhearsion/tasks/generating.rb +20 -0
  58. data/lib/adhearsion/tasks/lint.rb +4 -0
  59. data/lib/adhearsion/tasks/testing.rb +37 -0
  60. data/lib/adhearsion/version.rb +9 -0
  61. data/lib/adhearsion/voip/asterisk.rb +10 -0
  62. data/lib/adhearsion/voip/asterisk/agi_server.rb +81 -0
  63. data/lib/adhearsion/voip/asterisk/ami.rb +147 -0
  64. data/lib/adhearsion/voip/asterisk/ami/actions.rb +238 -0
  65. data/lib/adhearsion/voip/asterisk/ami/machine.rb +871 -0
  66. data/lib/adhearsion/voip/asterisk/ami/machine.rl +109 -0
  67. data/lib/adhearsion/voip/asterisk/ami/parser.rb +262 -0
  68. data/lib/adhearsion/voip/asterisk/commands.rb +1284 -0
  69. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
  70. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
  71. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
  72. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
  73. data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
  74. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
  75. data/lib/adhearsion/voip/call.rb +436 -0
  76. data/lib/adhearsion/voip/call_routing.rb +64 -0
  77. data/lib/adhearsion/voip/commands.rb +9 -0
  78. data/lib/adhearsion/voip/constants.rb +39 -0
  79. data/lib/adhearsion/voip/conveniences.rb +18 -0
  80. data/lib/adhearsion/voip/dial_plan.rb +207 -0
  81. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
  82. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
  83. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
  84. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
  85. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +71 -0
  86. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
  87. data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -0
  88. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
  89. data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
  90. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
  91. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
  92. data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
  93. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
  94. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
  95. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
  96. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
  97. metadata +167 -0
@@ -0,0 +1,246 @@
1
+ module Adhearsion
2
+
3
+ class PathString < String
4
+ attr_accessor :component_path, :dialplan_path, :log_path
5
+
6
+ def initialize(path)
7
+ super
8
+ defaults
9
+ end
10
+
11
+ def defaults
12
+ @component_path = build_path_for "components"
13
+ @dialplan_path = dup
14
+ @log_path = build_path_for "logs"
15
+ end
16
+
17
+ def base_path=(value)
18
+ replace(value)
19
+ defaults
20
+ end
21
+
22
+ def using_base_path(temporary_base_path, &block)
23
+ original_path = dup
24
+ self.base_path = temporary_base_path
25
+ block.call
26
+ ensure
27
+ self.base_path = original_path
28
+ end
29
+
30
+ def dial_plan_named(name)
31
+ File.join(dialplan_path, name)
32
+ end
33
+
34
+ private
35
+ def build_path_for(path)
36
+ File.join(to_s, path)
37
+ end
38
+ end
39
+
40
+ class Initializer
41
+
42
+ class << self
43
+ def get_rules_from(location)
44
+ location = File.join location, ".ahnrc" if File.directory? location
45
+ File.exists?(location) ? YAML.load_file(location) : nil
46
+ end
47
+
48
+ def ahn_root=(path)
49
+ if Object.constants.include?("AHN_ROOT")
50
+ Object.const_get(:AHN_ROOT).base_path = File.expand_path(path)
51
+ else
52
+ Object.const_set(:AHN_ROOT, PathString.new(File.expand_path(path)))
53
+ end
54
+ end
55
+
56
+ def start(*args, &block)
57
+ new(*args, &block).start
58
+ end
59
+
60
+ def start_from_init_file(file, ahn_app_path)
61
+ return if defined?(@@started) && @@started
62
+ start ahn_app_path, :loaded_init_files => file
63
+ end
64
+
65
+ end
66
+
67
+ attr_reader :path, :daemon, :pid_file, :log_file, :ahn_app_log_directory
68
+
69
+ DEFAULT_FRAMEWORK_EVENT_NAMESPACES = %w[
70
+ /framework/after_initialized
71
+ /framework/shutdown
72
+ ]
73
+
74
+ # Creation of pid_files
75
+ #
76
+ # - You may want to have Adhearsion create a process identification
77
+ # file when it boots so that a crash monitoring program such as
78
+ # Monit can reboot if necessary or so the init script can kill it
79
+ # for system shutdowns.
80
+ # - To have Adhearsion create a pid file in the default location (i.e.
81
+ # AHN_INSTALL_DIR/adhearsion.pid), supply :pid_file with 'true'. Otherwise
82
+ # one is not created UNLESS it is running in daemon mode, in which
83
+ # case one is created. You can force Adhearsion to not create one
84
+ # even in daemon mode by supplying "false".
85
+ def initialize(path=nil, options={})
86
+ @@started = true
87
+ @path = path
88
+ @daemon = options[:daemon]
89
+ @pid_file = options[:pid_file].nil? ? ENV['PID_FILE'] : options[:pid_file]
90
+ @loaded_init_files = options[:loaded_init_files]
91
+ end
92
+
93
+ def start
94
+ self.class.ahn_root = path
95
+ resolve_pid_file_path
96
+ resolve_log_file_path
97
+ switch_to_root_directory
98
+ catch_termination_signal
99
+ bootstrap_rc
100
+ load_all_init_files
101
+ init_modules
102
+ daemonize! if should_daemonize?
103
+ initialize_log_file
104
+ create_pid_file if pid_file
105
+ load_components
106
+ init_events
107
+ ahn_log "Adhearsion initialized!"
108
+
109
+ trigger_after_initialized_hooks
110
+ join_framework_threads
111
+
112
+ self
113
+ end
114
+
115
+ def init_events
116
+ #
117
+ # framework =
118
+ # DEFAULT_FRAMEWORK_EVENT_NAMESPACES.each do |namespace|
119
+ # .register_callback_name framework_event_callback_name
120
+ # end
121
+ ############
122
+ # else #...
123
+ # ahn_log.events.warn 'No "events" section in .ahnrc. Skipping its initialization.'
124
+ end
125
+
126
+ def initialize_log_file
127
+ Dir.mkdir(ahn_app_log_directory) unless File.directory? ahn_app_log_directory
128
+ file_logger = Log4r::FileOutputter.new("Main Adhearsion log file", :filename => log_file, :trunc => false)
129
+
130
+ if should_daemonize?
131
+ Logging::AdhearsionLogger.outputters = file_logger
132
+ else
133
+ Logging::AdhearsionLogger.outputters << file_logger
134
+ end
135
+ Logging::DefaultAdhearsionLogger.redefine_outputters
136
+ end
137
+
138
+ def resolve_log_file_path
139
+ @ahn_app_log_directory = AHN_ROOT + '/log'
140
+ @log_file = File.expand_path(ahn_app_log_directory + "/adhearsion.log")
141
+ end
142
+
143
+ def create_pid_file(file = pid_file)
144
+ if file
145
+ File.open pid_file, 'w' do |file|
146
+ file.puts Process.pid
147
+ end
148
+
149
+ Hooks::TearDown.create_hook do
150
+ File.delete(pid_file) if File.exists?(pid_file)
151
+ end
152
+ end
153
+ end
154
+
155
+ def init_modules
156
+ require 'adhearsion/initializer/database.rb'
157
+ require 'adhearsion/initializer/asterisk.rb'
158
+ require 'adhearsion/initializer/drb.rb'
159
+ require 'adhearsion/initializer/rails.rb'
160
+ # require 'adhearsion/initializer/freeswitch.rb'
161
+
162
+ DatabaseInitializer.start if AHN_CONFIG.database_enabled?
163
+ AsteriskInitializer.start if AHN_CONFIG.asterisk_enabled?
164
+ DrbInitializer.start if AHN_CONFIG.drb_enabled?
165
+ RailsInitializer.start if AHN_CONFIG.rails_enabled?
166
+ # FreeswitchInitializer.start if AHN_CONFIG.freeswitch_enabled?
167
+ end
168
+
169
+ def resolve_pid_file_path
170
+ @pid_file = if pid_file.equal?(true) then default_pid_path
171
+ elsif pid_file then pid_file
172
+ elsif pid_file.equal?(false) then nil
173
+ # FIXME @pid_file = @daemon? Assignment or equality? I'm assuming equality.
174
+ else @pid_file = @daemon ? default_pid_path : nil
175
+ end
176
+ end
177
+
178
+ def switch_to_root_directory
179
+ Dir.chdir AHN_ROOT
180
+ end
181
+
182
+ def catch_termination_signal
183
+ Hooks::TearDown.catch_termination_signals
184
+ end
185
+
186
+ def load_all_init_files
187
+ init_files_from_rc = AHN_CONFIG.files_from_setting("paths", "init").map { |file| File.expand_path(file) }
188
+ already_loaded_init_files = Array(@loaded_init_files).map { |file| File.expand_path(file) }
189
+ (init_files_from_rc - already_loaded_init_files).each { |init| load init }
190
+ end
191
+
192
+ def should_daemonize?
193
+ @daemon || ENV['DAEMON']
194
+ end
195
+
196
+ def daemonize!
197
+ ahn_log "Daemonizing now! Creating #{pid_file}."
198
+ extend Adhearsion::CustomDaemonizer
199
+ daemonize log_file
200
+ end
201
+
202
+ def load_components
203
+ ComponentManager.load
204
+ ComponentManager.start
205
+ end
206
+
207
+ def trigger_after_initialized_hooks
208
+ Hooks::AfterInitialized.trigger_hooks
209
+ end
210
+
211
+ def join_framework_threads
212
+ Hooks::ThreadsJoinedAfterInitialized.trigger_hooks
213
+ end
214
+
215
+ def bootstrap_rc
216
+ rules = self.class.get_rules_from AHN_ROOT
217
+
218
+ AHN_CONFIG.ahnrc = rules
219
+
220
+ gems = rules['gems']
221
+ if gems.kind_of?(Hash) && gems.any? && respond_to?(:gem)
222
+ gems.each_pair do |gem_name,properties_hash|
223
+ if properties_hash && properties_hash["version"]
224
+ gem gem_name, properties_hash["version"]
225
+ else
226
+ gem gem_name
227
+ end
228
+ if properties_hash
229
+ case properties_hash["require"]
230
+ when Array
231
+ properties_hash["require"].each { |lib| require lib }
232
+ when String
233
+ require properties_hash["require"]
234
+ end
235
+ end
236
+ end
237
+ end
238
+ end
239
+
240
+ def default_pid_path
241
+ File.join AHN_ROOT, 'adhearsion.pid'
242
+ end
243
+
244
+ class InitializationFailedError < Exception; end
245
+ end
246
+ end
@@ -0,0 +1,59 @@
1
+ require 'adhearsion/voip/asterisk'
2
+ module Adhearsion
3
+ class Initializer
4
+
5
+ class AsteriskInitializer
6
+
7
+ cattr_accessor :config, :agi_server, :ami_client
8
+ class << self
9
+
10
+ def start
11
+ self.config = Adhearsion::AHN_CONFIG.asterisk
12
+ self.agi_server = initialize_agi
13
+ self.ami_client = initialize_ami if config.ami_enabled?
14
+ join_server_thread_after_initialized
15
+ end
16
+
17
+ def stop
18
+ agi_server.stop
19
+ ami_client.disconnect! if ami_client
20
+ end
21
+
22
+ private
23
+
24
+ def initialize_agi
25
+ Adhearsion::VoIP::Asterisk::AGI::Server.new :host => config.listening_host,
26
+ :port => config.listening_port
27
+ end
28
+
29
+ def initialize_ami
30
+ options = ami_options
31
+ start_ami_after_initialized
32
+ Adhearsion::VoIP::Asterisk::AMI.new options[:username], options[:password],
33
+ options[:host], :port => options[:port],
34
+ :events => options[:events]
35
+ end
36
+
37
+ def ami_options
38
+ %w(host port username password events).inject({}) do |options, property|
39
+ options[property.to_sym] = config.ami.send property
40
+ options
41
+ end
42
+ end
43
+
44
+ def join_server_thread_after_initialized
45
+ Adhearsion::Hooks::AfterInitialized.create_hook { agi_server.start }
46
+ Adhearsion::Hooks::ThreadsJoinedAfterInitialized.create_hook { agi_server.join }
47
+ end
48
+
49
+ def start_ami_after_initialized
50
+ Adhearsion::Hooks::AfterInitialized.create_hook do
51
+ ami_client.connect!
52
+ end
53
+ end
54
+
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,236 @@
1
+ module Adhearsion
2
+ class Configuration
3
+ module ConfigurationEntryPoint
4
+ def add_configuration_for(name)
5
+ configuration_class_name = "#{name}Configuration"
6
+ lowercased_name = name.to_s.underscore
7
+
8
+ class_eval(<<-EVAL, __FILE__, __LINE__)
9
+ def enable_#{lowercased_name}(configuration_options = {})
10
+ @#{lowercased_name}_configuration = #{configuration_class_name}.new(configuration_options)
11
+ end
12
+
13
+ def #{lowercased_name}
14
+ @#{lowercased_name}_configuration
15
+ end
16
+
17
+ def #{lowercased_name}_enabled?
18
+ !#{lowercased_name}.nil?
19
+ end
20
+ EVAL
21
+ end
22
+ end
23
+ extend ConfigurationEntryPoint
24
+
25
+ class << self
26
+ def configure(&block)
27
+ Adhearsion.module_eval { remove_const(:AHN_CONFIG) } if Adhearsion.const_defined?(:AHN_CONFIG)
28
+ Adhearsion.const_set(:AHN_CONFIG, new(&block))
29
+ end
30
+ end
31
+
32
+ attr_accessor :automatically_answer_incoming_calls
33
+ attr_accessor :end_call_on_hangup
34
+ attr_accessor :end_call_on_error
35
+
36
+ def ahnrc
37
+ @ahnrc
38
+ end
39
+
40
+ def ahnrc=(new_ahnrc)
41
+ case new_ahnrc
42
+ when Hash
43
+ @raw_ahnrc = new_ahnrc.to_yaml.freeze
44
+ @ahnrc = new_ahnrc.clone.freeze
45
+ when String
46
+ @raw_ahnrc = new_ahnrc.clone.freeze
47
+ @ahnrc = YAML.load(new_ahnrc).freeze
48
+ end
49
+ end
50
+
51
+ def logging(options)
52
+ Adhearsion::Logging.logging_level = options[:level]
53
+ end
54
+
55
+ def files_from_setting(*path_through_config)
56
+ queried_nested_setting = path_through_config.flatten.inject(@ahnrc) do |hash,key_name|
57
+ if hash.kind_of?(Hash) && hash.has_key?(key_name)
58
+ hash[key_name]
59
+ else
60
+ raise NameError, "Paths #{path_through_config.inspect} not found in .ahnrc!"
61
+ end
62
+ end
63
+ raise NameError, "Paths #{path_through_config.inspect} not found in .ahnrc!" unless queried_nested_setting
64
+ queried_nested_setting = Array queried_nested_setting
65
+ queried_nested_setting.map { |filename| files_from_glob(filename) }.flatten.uniq
66
+ end
67
+
68
+ def initialize
69
+ @automatically_answer_incoming_calls = true
70
+ @end_call_on_hangup = true
71
+ @end_call_on_error = true
72
+ yield self if block_given?
73
+ end
74
+
75
+ private
76
+
77
+ def files_from_glob(glob)
78
+ Dir.glob "#{AHN_ROOT}/#{glob}"
79
+ end
80
+
81
+ class AbstractConfiguration
82
+ extend ConfigurationEntryPoint
83
+
84
+ class << self
85
+ private
86
+ def abstract_method!
87
+ raise "Must be implemented in subclasses"
88
+ end
89
+ end
90
+
91
+ def initialize(overrides = {})
92
+ overrides.each_pair do |attribute, value|
93
+ send("#{attribute}=", value)
94
+ end
95
+ end
96
+ end
97
+
98
+ # Abstract superclass for AsteriskConfiguration and FreeSwitchConfiguration.
99
+ class TelephonyPlatformConfiguration < AbstractConfiguration
100
+ attr_accessor :listening_port
101
+ attr_accessor :listening_host
102
+
103
+ class << self
104
+ def default_listening_port
105
+ abstract_method!
106
+ end
107
+
108
+ def default_listening_host
109
+ '0.0.0.0'
110
+ end
111
+ end
112
+
113
+ def initialize(overrides = {})
114
+ @listening_port = self.class.default_listening_port
115
+ @listening_host = self.class.default_listening_host
116
+ super
117
+ end
118
+ end
119
+
120
+ class AsteriskConfiguration < TelephonyPlatformConfiguration
121
+ class << self
122
+ attr_accessor :speech_engine
123
+
124
+ def default_listening_port
125
+ 4573
126
+ end
127
+ end
128
+
129
+ class AMIConfiguration < AbstractConfiguration
130
+ attr_accessor :port, :username, :password, :events, :host
131
+
132
+ class << self
133
+ def default_port
134
+ 5038
135
+ end
136
+
137
+ def default_events
138
+ false
139
+ end
140
+
141
+ def default_host
142
+ 'localhost'
143
+ end
144
+ end
145
+
146
+ def initialize(overrides = {})
147
+ self.host = self.class.default_host
148
+ self.port = self.class.default_port
149
+ self.events = self.class.default_events
150
+ super
151
+ end
152
+ end
153
+ add_configuration_for :AMI
154
+ end
155
+ add_configuration_for :Asterisk
156
+
157
+ class FreeswitchConfiguration < TelephonyPlatformConfiguration
158
+ class << self
159
+ def default_listening_port
160
+ 4572
161
+ end
162
+ end
163
+ end
164
+ add_configuration_for :Freeswitch
165
+
166
+ class DatabaseConfiguration < AbstractConfiguration
167
+ attr_accessor :connection_options, :orm
168
+ def initialize(options)
169
+ @orm = options.delete(:orm) || :active_record # TODO: ORM is a misnomer
170
+ @connection_options = options
171
+ end
172
+ end
173
+ add_configuration_for :Database
174
+
175
+ class DrbConfiguration < AbstractConfiguration
176
+ attr_accessor :port
177
+ attr_accessor :host
178
+ attr_accessor :acl
179
+
180
+ # ACL = Access Control List
181
+
182
+ class << self
183
+ def default_port
184
+ 9050
185
+ end
186
+
187
+ def default_host
188
+ 'localhost'
189
+ end
190
+ end
191
+
192
+ def initialize(overrides = {})
193
+ self.port = overrides[:port] || self.class.default_port
194
+ self.host = overrides[:host] || self.class.default_host
195
+ self.acl = overrides[:raw_acl]
196
+
197
+ unless acl
198
+ self.acl = []
199
+ overrides[ :deny].to_a.each { |ip| acl << 'deny' << ip }
200
+ overrides[:allow].to_a.each { |ip| acl << 'allow' << ip }
201
+ acl.concat %w[allow 127.0.0.1] if acl.empty?
202
+ end
203
+ end
204
+ end
205
+ add_configuration_for :Drb
206
+
207
+ class RailsConfiguration < AbstractConfiguration
208
+
209
+ SUPPORTED_RAILS_ENVIRONMENTS = [:development, :test, :production]
210
+
211
+ attr_accessor :rails_root, :environment
212
+ def initialize(options)
213
+ path_to_rails, environment = check_options options
214
+ @rails_root = File.expand_path(path_to_rails)
215
+ @environment = environment.to_sym
216
+ raise ArgumentError, "Unrecognized environment type #@environment. Supported: " +
217
+ SUPPORTED_RAILS_ENVIRONMENTS.to_sentence unless SUPPORTED_RAILS_ENVIRONMENTS.include?(@environment)
218
+ end
219
+
220
+ private
221
+
222
+ def check_options(options)
223
+ options = options.clone
224
+ path = options.delete :path
225
+ env = options.delete :env
226
+ raise ArgumentError, "Unrecognied argument(s) #{options.keys.to_sentence} in Rails initializer!" unless options.size.zero?
227
+ raise ArgumentError, "Must supply an :env argument to the Rails initializer!" unless env
228
+ raise ArgumentError, "Must supply an :path argument to the Rails initializer!" unless path
229
+ [path, env]
230
+ end
231
+
232
+ end
233
+ add_configuration_for :Rails
234
+
235
+ end
236
+ end