wrangler 0.1.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2009 Umamibud, Inc.
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,247 @@
1
+ = Wrangler
2
+
3
+ == NOTE/DISCLAIMER
4
+ This gem is almost completely inspired by/ripped off the exception_notification
5
+ plugin/gem, but had to hack too much to get things to work with delayed_job
6
+ that I just decided to start from scratch. You'll see that much has been
7
+ borrowed however, so I owe a huge debt to the originals (exception_notification
8
+ [http://github.com/rails/exception_notification] and
9
+ super_exception_notification [http://github.com/pboling/exception_notification])
10
+ to help me recreate the Rails hacking.
11
+
12
+ If you don't really care about using delayed_job for your emailing, consider
13
+ going back to the originals, as they're likely better maintained.... ;)
14
+
15
+ == Overview:
16
+ A gem for handling exceptions in a Rails application/environment.
17
+
18
+ Some highlights:
19
+ * Allows for rendering error pages and sending email notifications in case of
20
+ errors.
21
+ * Allows for lots of configuring of which pages to show, whether to email or not.
22
+ * Allows for asynchronous emailing through delayed_job if available, but works
23
+ fine even if delayed_job not installed (email will be synchronous however)
24
+ * Will honor filter_parameters set in the controller including the Wrangler
25
+ module (except if the parameters are in the URL for GETs) when logging and
26
+ emailing application state at the time of the exception
27
+ * Allows email notification on exceptions thrown totally outside Controller
28
+ context, e.g. in a script run (with rails environment) in a cronjob or
29
+ delayed_job
30
+
31
+ == Quickstart
32
+ === Bare Minimum
33
+ There are a lot of defaults set, so getting started should be pretty easy. In
34
+ fact, if you don't want any email notifications, you basically just need to
35
+ include the Wrangler module in your controller:
36
+ # application_controller.rb
37
+ class ApplicationController < ActionController::Base
38
+ include Wrangler
39
+
40
+ ...
41
+ end
42
+
43
+ === Enabling email notifications
44
+ Email notifications are configured to be sent with the default configuration,
45
+ but you'll need to specify from and to addresses for emails to actually be sent.
46
+ So that brings us to the configuration of Wrangler. Recommended: just create a
47
+ new initializer file (create a wrangler.rb (or whatever you want to name the file)
48
+ in RAILS_ROOT/config/initializers/wrangler.rb). In it, add the following:
49
+
50
+ Wrangler::ExceptionNotifier.configure do |notifier_config|
51
+ notifier_config.merge! :from_address => 'monitor@umamibud.com',
52
+ :recipient_addresses => ['u-ops-monitor@umamibud.com']
53
+ end
54
+
55
+ And, if you haven't already configured ActionMailer to send emails, you'll need
56
+ to do that (e.g. setting ActionMailer::Base.smtp_settings), and even after you
57
+ have, you may want to change some settings in order to send from a different
58
+ account from the one you may use to email your users (e.g. change the :user_name
59
+ for smtp_settings):
60
+
61
+ Wrangler::ExceptionNotifier.smtp_settings.merge! :user_name => 'notifier@mydomain.com'
62
+
63
+ (Recommend just putting that in the same wrangler.rb initializer you created above)
64
+
65
+ For more info on smtp_settings, see ActionMailer (http://am.rubyonrails.org/)
66
+
67
+ == Configuration
68
+ There are two different classes that receive configuration, ExceptionHandler and
69
+ ExceptionNotifier.
70
+
71
+ ExceptionHandler stores configurations about what to do about exceptions (whether to
72
+ handle them, email them, which error templates to render for each exception...).
73
+
74
+ ExceptionNotifier handles the sending of emails when exceptions occur, so
75
+ stores configurations about where to send the emails.
76
+
77
+ You override defaults on each using the same syntax (as seen above) by calling the
78
+ configure() method on the class and using the config hash that is yielded to
79
+ set your configurations. See the method documentation for the configure() methods
80
+ themselves, but here's the basic idea:
81
+
82
+ Wrangler::ExceptionHandler.configure do |handler_config|
83
+ handler_config[:key1] = value1
84
+ handler_config[:key2] = value2
85
+ handler_config[:key_for_a_hash].merge! :subkey => value
86
+ handler_config[:key_for_an_array] << another_value
87
+ end
88
+
89
+ OR
90
+
91
+ Wrangler::ExceptionHandler.configure do |handler_config|
92
+ handler_config.merge! :key1 => value1,
93
+ :key2 => value2,
94
+ handler_config[:key_for_a_hash].merge! :subkey => value
95
+ handler_config[:key_for_an_array] << another_value
96
+ end
97
+
98
+ (same with Wrangler::ExceptionNotifier, except different classname)
99
+
100
+ Most configurations are single values (e.g. nums or strings),
101
+ but some are hashes or arrays. You can either overwrite the hashes/arrays, or
102
+ selectively delete, or just append. Recommend just appending to the defaults
103
+ in most cases, but if you know what you're doing, you can do whatever you like!
104
+
105
+ Here is the full set of configuration values for both classes, as well as their
106
+ default values (pasted in from the classes, so you can check the code directly
107
+ to make sure you've got the latest! :) ):
108
+
109
+ ####################
110
+ # ExceptionHandler:
111
+ ####################
112
+
113
+ :app_name => '',
114
+ :handle_local_errors => false,
115
+ :handle_public_errors => true,
116
+ # send email for local reqeusts. ignored if :handle_local_errors false
117
+ :notify_on_local_error => false,
118
+ # send email for public requests. ignored if :handle_public_errors false
119
+ :notify_on_public_error => true,
120
+ # send email for exceptions caught outside of a controller context
121
+ :notify_on_background_error => true,
122
+ # configure whether to send emails synchronously or asynchronously
123
+ # using delayed_job (these can be true even if delayed job is not
124
+ # installed, in which case, will just send emails synchronously anyway)
125
+ :delayed_job_for_controller_errors => false,
126
+ :delayed_job_for_non_controller_errors => false,
127
+ # mappings from exception classes to http status codes (see above)
128
+ # add/remove from this list as desired in environment configuration
129
+ :error_class_status_codes => Wrangler::codes_for_exception_classes,
130
+ # explicitly indicate which exceptions to send email notifications for
131
+ :notify_exception_classes => %w(),
132
+ # indicate which http status codes should result in email notification
133
+ :notify_status_codes => %w( 405 500 503 ),
134
+ # where to look for app-specific error page templates (ones you create
135
+ # yourself, for example...there are some defaults in this gem you can
136
+ # use as well...and that are configured already by default)
137
+ :error_template_dir => File.join(RAILS_ROOT, 'app', 'views', 'error'),
138
+ # excplicit mappings from exception class to arbitrary error page
139
+ # templates, different set for html and js responses (Wrangler determines
140
+ # which to use automatically, so you can have an entry in both
141
+ # hashes for the same error class)
142
+ :error_class_html_templates => {},
143
+ :error_class_js_templates => {},
144
+ # you can specify a fallback failsafe error template to render if
145
+ # no appropriate template is found in the usual places (you shouldn't
146
+ # rely on this, and error messages will be logged if this template is
147
+ # used). note: there's an even more failsafe template included in the
148
+ # gem (absolute_last_resort...) below, but DON'T CHANGE IT!!!
149
+ :default_error_template => '',
150
+ # these filter out any HTTP params that are undesired
151
+ :request_env_to_skip => [ /^rack\./,
152
+ "action_controller.rescue.request",
153
+ "action_controller.rescue.response" ],
154
+ # mapping from exception classes to templates (if desired), express
155
+ # in absolute paths. use wildcards like on cmd line (glob-like), NOT
156
+ # regexp-style
157
+
158
+ # just DON'T change this! this is the error template of last resort!
159
+ :absolute_last_resort_default_error_template =>
160
+ File.join(WRANGLER_ROOT,'rails','app','views','wrangler','500.html')
161
+
162
+ #####################
163
+ # ExceptionNotifier:
164
+ #####################
165
+
166
+ # who the emails will be coming from. if nil or missing or empty string,
167
+ # effectively disables email notification
168
+ :from_address => '',
169
+ # array of addresses that the emails will be sent to. if nil or missing
170
+ # or empty array, effectively disables email notification.
171
+ :recipient_addresses => [],
172
+ # what will show up at the beginning of the subject line for each email
173
+ # sent note: will be preceded by "[<app_name (if any)>...", where app_name
174
+ # is the :app_name config value from ExceptionHandler (or explicit
175
+ # proc_name given to notify_on_error() method)
176
+ :subject_prefix => "#{(defined?(Rails) ? Rails.env : RAILS_ENV).capitalize} ERROR",
177
+ # can use this to define app-specific mail views using the same data
178
+ # made available in exception_notification()
179
+ :mailer_template_root => File.join(WRANGLER_ROOT, 'views')
180
+
181
+ == Search algorithm for error templates (given an exception and a status_code):
182
+ When trying to find an appropriate error page template to render, Wrangler
183
+ goes through several different attempts to locate an appropriate template,
184
+ beginning with templates you've explicitly associated with the exception class
185
+ or status code that has arisen...and on through to assuming default file naming
186
+ conventions and finally failsafe default templates.
187
+
188
+ # if there is an explicit mapping from the exception to an error page in
189
+ :error_class_xxx_templates, use that
190
+ # if there is a mapping in :error_class_templates for which the exception
191
+ returns true to an is_a? call, use that
192
+ # if there is a file/template corresponding to the exception name
193
+ (underscorified) in one of the following locations, use that:
194
+ ** config[:error_template_dir]/
195
+ ** RAILS_ROOT/public/
196
+ ** WRANGLER_ROOT/rails/app/views/wrangler/
197
+ # if there is a file/template corresponding to the status code
198
+ (e.g. named ###.html.erb where ### is the status code) in one of the following
199
+ locations, use that:
200
+ ** config[:error_template_dir]/
201
+ ** RAILS_ROOT/public/
202
+ ** WRANGLER_ROOT/rails/app/views/wrangler/
203
+ # if there is a file/template corresponding to a parent class name of the
204
+ exception (underscorified) one of the following locations, use that:
205
+ ** config[:error_template_dir]/
206
+ ** RAILS_ROOT/public/
207
+ ** WRANGLER_ROOT/rails/app/views/wrangler/
208
+ # :default_error_template
209
+ # :absolute_last_resort_default_error_template
210
+
211
+ == Using outside a Controller:
212
+ You can still use Wrangler outside the context of a Controller class. If you'll
213
+ be running within the context of an object instance, you can just include Wrangler
214
+ in the object's class. If you'll be running 'static' code, you can refer to
215
+ relevant methods via the Wrangler module. Note that in both cases, you'll be
216
+ calling the notify_on_error() method. Also note that the notify_on_error()
217
+ method will re-raise the exception that occurred in the block, so you may want
218
+ to begin/rescue/end around the notify_on_error() method call
219
+
220
+ using in an object instance:
221
+
222
+ class MyClass
223
+ include Wrangler
224
+
225
+ def my_error_method; raise "error!"; end
226
+
227
+ def call_a_method
228
+ notify_on_error { my_error_method }
229
+ rescue => e
230
+ exit
231
+ end
232
+ end
233
+
234
+ using 'statically':
235
+
236
+ Wrangler::notify_on_error { run_some_method_that_might_raise_exceptions }
237
+
238
+ == Maintaining the Wrangler gem
239
+ Should be pretty straightforward. Note that we're using jeweler, so the .gemspec
240
+ isn't included in the git repos; it gets generated dynamically from the settings
241
+ in Rakefile.
242
+
243
+ To build:
244
+
245
+ cd .../wrangler
246
+ rake gemspec
247
+ rake build
@@ -0,0 +1,280 @@
1
+ module Wrangler
2
+
3
+ # a utility method that should only be used internally. don't call this; it
4
+ # should only be called once by the Config class and you can get/set it there.
5
+ # returns a mapping from exception classes to http status codes
6
+ #-----------------------------------------------------------------------------
7
+ def self.codes_for_exception_classes
8
+ classes = {
9
+ # These are standard errors in rails / ruby
10
+ NameError => "503",
11
+ TypeError => "503",
12
+ RuntimeError => "500",
13
+ ArgumentError => "500",
14
+ # the default mapping for an unrecognized exception class
15
+ :default => "500"
16
+ }
17
+
18
+ # from exception_notification gem:
19
+ # Highly dependent on the verison of rails, so we're very protective about these'
20
+ classes.merge!({ ActionView::TemplateError => "500"}) if defined?(ActionView) && ActionView.const_defined?(:TemplateError)
21
+ classes.merge!({ ActiveRecord::RecordNotFound => "400" }) if defined?(ActiveRecord) && ActiveRecord.const_defined?(:RecordNotFound)
22
+ classes.merge!({ ActiveResource::ResourceNotFound => "404" }) if defined?(ActiveResource) && ActiveResource.const_defined?(:ResourceNotFound)
23
+
24
+ # from exception_notification gem:
25
+ if defined?(ActionController)
26
+ classes.merge!({ ActionController::UnknownController => "404" }) if ActionController.const_defined?(:UnknownController)
27
+ classes.merge!({ ActionController::MissingTemplate => "404" }) if ActionController.const_defined?(:MissingTemplate)
28
+ classes.merge!({ ActionController::MethodNotAllowed => "405" }) if ActionController.const_defined?(:MethodNotAllowed)
29
+ classes.merge!({ ActionController::UnknownAction => "501" }) if ActionController.const_defined?(:UnknownAction)
30
+ classes.merge!({ ActionController::RoutingError => "404" }) if ActionController.const_defined?(:RoutingError)
31
+ classes.merge!({ ActionController::InvalidAuthenticityToken => "405" }) if ActionController.const_defined?(:InvalidAuthenticityToken)
32
+ end
33
+
34
+ return classes
35
+ end
36
+
37
+ # class that holds configuration for the exception handling logic. may also
38
+ # include a helper method or two, but the main interaction with
39
+ # ExceptionHandler is setting and getting config, e.g.
40
+ #
41
+ # Wrangler::ExceptionHandler.configure do |handler_config|
42
+ # handler_config.merge! :key => value
43
+ # end
44
+ #-----------------------------------------------------------------------------
45
+ class ExceptionHandler
46
+
47
+ # the default configuration
48
+ @@config ||= {
49
+ :app_name => '',
50
+ :handle_local_errors => false,
51
+ :handle_public_errors => true,
52
+ # send email for local reqeusts. ignored if :handle_local_errors false
53
+ :notify_on_local_error => false,
54
+ # send email for public requests. ignored if :handle_public_errors false
55
+ :notify_on_public_error => true,
56
+ # send email for exceptions caught outside of a controller context
57
+ :notify_on_background_error => true,
58
+ # configure whether to send emails synchronously or asynchronously
59
+ # using delayed_job (these can be true even if delayed job is not
60
+ # installed, in which case, will just send emails synchronously anyway)
61
+ :delayed_job_for_controller_errors => false,
62
+ :delayed_job_for_non_controller_errors => false,
63
+ # mappings from exception classes to http status codes (see above)
64
+ # add/remove from this list as desired in environment configuration
65
+ :error_class_status_codes => Wrangler::codes_for_exception_classes,
66
+ # explicitly indicate which exceptions to send email notifications for
67
+ :notify_exception_classes => %w(),
68
+ # indicate which http status codes should result in email notification
69
+ :notify_status_codes => %w( 405 500 503 ),
70
+ # where to look for app-specific error page templates (ones you create
71
+ # yourself, for example...there are some defaults in this gem you can
72
+ # use as well...and that are configured already by default)
73
+ :error_template_dir => File.join(RAILS_ROOT, 'app', 'views', 'error'),
74
+ # excplicit mappings from exception class to arbitrary error page
75
+ # templates, different set for html and js responses (Wrangler determines
76
+ # which to use automatically, so you can have an entry in both
77
+ # hashes for the same error class)
78
+ :error_class_html_templates => {},
79
+ :error_class_js_templates => {},
80
+ # you can specify a fallback failsafe error template to render if
81
+ # no appropriate template is found in the usual places (you shouldn't
82
+ # rely on this, and error messages will be logged if this template is
83
+ # used). note: there's an even more failsafe template included in the
84
+ # gem (absolute_last_resort...) below, but DON'T CHANGE IT!!!
85
+ :default_error_template => '',
86
+ # these filter out any HTTP params that are undesired
87
+ :request_env_to_skip => [ /^rack\./,
88
+ "action_controller.rescue.request",
89
+ "action_controller.rescue.response" ],
90
+ # mapping from exception classes to templates (if desired), express
91
+ # in absolute paths. use wildcards like on cmd line (glob-like), NOT
92
+ # regexp-style
93
+
94
+ # just DON'T change this! this is the error template of last resort!
95
+ :absolute_last_resort_default_error_template =>
96
+ File.join(WRANGLER_ROOT,'rails','app','views','wrangler','500.html')
97
+ }
98
+
99
+ cattr_accessor :config
100
+
101
+ # allows for overriding default configuration settings.
102
+ # in your environment.rb or environments/<env name>.rb, use a block that
103
+ # accepts one argument
104
+ # * recommend against naming it 'config' as you will probably be calling it
105
+ # within the config block in env.rb...):
106
+ # * note that some of the config values are arrays or hashes; you can
107
+ # overwrite them completely, delete or insert/merge new entries into the
108
+ # default values as you see fit...but in most cases, recommend AGAINST
109
+ # overwriting the arrays/hashes completely unless you don't want to
110
+ # take advantage of lots of out-of-the-box config
111
+ #
112
+ # Wrangler::ExceptionHandler.configure do |handler_config|
113
+ # handler_config[:key1] = value1
114
+ # handler_config[:key2] = value2
115
+ # handler_config[:key_for_a_hash].merge! :subkey => value
116
+ # handler_config[:key_for_an_array] << another_value
117
+ # end
118
+ #
119
+ # OR
120
+ #
121
+ # Wrangler::ExceptionHandler.configure do |handler_config|
122
+ # handler_config.merge! :key1 => value1,
123
+ # :key2 => value2,
124
+ # handler_config[:key_for_a_hash].merge! :subkey => value
125
+ # handler_config[:key_for_an_array] << another_value
126
+ # end
127
+ #
128
+ # NOTE: sure, you can change this configuration on the fly in your app, but
129
+ # we don't recommend it. plus, if you do and you're using delayed_job, there
130
+ # may end up being configuration differences between the rails process and
131
+ # the delayed_job process, resulting in unexpected behavior. so recommend
132
+ # you just modify this in the environment config files...or if you're doing
133
+ # something sneaky, you're on your own.
134
+ #-----------------------------------------------------------------------------
135
+ def self.configure(&block)
136
+ yield @@config
137
+ end
138
+
139
+
140
+ # translate the exception class to an http status code, using default
141
+ # code (set in config) if the exception class isn't excplicitly mapped
142
+ # to a status code in config
143
+ #---------------------------------------------------------------------------
144
+ def self.status_code_for_exception(exception)
145
+ if exception.respond_to?(:status_code)
146
+ return exception.status_code
147
+ else
148
+ return config[:error_class_status_codes][exception.class] ||
149
+ config[:error_class_status_codes][:default]
150
+ end
151
+ end
152
+
153
+ end # end ExceptionHandler class
154
+
155
+ ##############################################################################
156
+ # actual exception handling code
157
+ ##############################################################################
158
+
159
+ # make all of these instance methods also module functions
160
+ module_function
161
+
162
+ # execute the code block passed as an argument, and follow notification
163
+ # rules if an exception bubbles out of the block.
164
+ #
165
+ # return value:
166
+ # * if an exception bubbles out of the block, the exception is re-raised to
167
+ # calling code.
168
+ # * otherwise, returns nil
169
+ #-----------------------------------------------------------------------------
170
+ def notify_on_error(proc_name = nil, &block)
171
+ begin
172
+ yield
173
+ rescue => exception
174
+ options = {}
175
+ options.merge! :proc_name => proc_name unless proc_name.nil?
176
+ handle_exception(exception, options)
177
+ end
178
+
179
+ return nil
180
+ end
181
+
182
+ # the main exception-handling method. decides whether to notify or not,
183
+ # whether to render an error page or not, and to make it happen.
184
+ #
185
+ # arguments:
186
+ # - exception: the exception that was caught
187
+ #
188
+ # options:
189
+ # :request: the request object (if any) that resulted in the exception
190
+ # :render_errors: boolean indicating if an error page should be rendered
191
+ # or not (Rails only)
192
+ # :proc_name: a string representation of the process/app that was running
193
+ # when the exception was raised. default value is
194
+ # Wrangler::ExceptionHandler.config[:app_name].
195
+ #-----------------------------------------------------------------------------
196
+ def handle_exception(exception, options = {})
197
+ request = options[:request]
198
+ render_errors = options[:render_errors] || false
199
+ proc_name = options[:proc_name] || config[:app_name]
200
+
201
+ status_code = Wrangler::ExceptionHandler.status_code_for_exception(exception)
202
+ request_data = request_data_from_request(request) unless request.nil?
203
+
204
+ if notify_on_exception?(exception, status_code)
205
+ if notify_with_delayed_job?
206
+ # don't pass in request as it contains not-easily-serializable stuff
207
+ Wrangler::ExceptionNotifier.send_later(:deliver_exception_notification,
208
+ exception,
209
+ proc_name,
210
+ exception.backtrace,
211
+ status_code,
212
+ request_data)
213
+ else
214
+ Wrangler::ExceptionNotifier.deliver_exception_notification(exception,
215
+ proc_name,
216
+ exception.backtrace,
217
+ status_code,
218
+ request_data,
219
+ request)
220
+ end
221
+ end
222
+
223
+ log_exception(exception, request_data, status_code)
224
+
225
+ if render_errors
226
+ render_error_template(exception, status_code)
227
+ end
228
+ end
229
+
230
+
231
+ # determine if the app is configured to notify for the given exception or
232
+ # status code
233
+ #-----------------------------------------------------------------------------
234
+ def notify_on_exception?(exception, status_code = nil)
235
+ # first determine if we're configured to notify given the context of the
236
+ # exception
237
+ if self.respond_to?(:local_request?)
238
+ if (local_request? && config[:notify_on_local_error]) ||
239
+ (!local_request? && config[:notify_on_public_error])
240
+ notify = true
241
+ else
242
+ notify = false
243
+ end
244
+ else
245
+ notify = config[:notify_on_background_error]
246
+ end
247
+
248
+ # now if config says notify in this case, check if we're configured to
249
+ # notify for this exception or this status code
250
+ return notify &&
251
+ (config[:notify_exception_classes].include?(exception.class) ||
252
+ config[:notify_status_codes].include?(status_code))
253
+ end
254
+
255
+ # determine if email should be sent with delayed job or not (delayed job
256
+ # must be installed and config set to use delayed job
257
+ #-----------------------------------------------------------------------------
258
+ def notify_with_delayed_job?
259
+ use_dj = false
260
+
261
+ if self.is_a?(ActionController::Base)
262
+ if config[:delayed_job_for_controller_errors] &&
263
+ ExceptionNotifier.respond_to?(:send_later)
264
+ use_dj = true
265
+ else
266
+ use_dj = false
267
+ end
268
+ else
269
+ if config[:delayed_job_for_non_controller_errors] &&
270
+ ExceptionNotifier.respond_to?(:send_later)
271
+ use_dj = true
272
+ else
273
+ use_dj = false
274
+ end
275
+ end
276
+
277
+ return use_dj
278
+ end
279
+
280
+ end