jordan-brough-hoptoad_notifier 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CHANGELOG +161 -0
  2. data/INSTALL +25 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.rdoc +384 -0
  5. data/Rakefile +217 -0
  6. data/SUPPORTED_RAILS_VERSIONS +9 -0
  7. data/TESTING.rdoc +8 -0
  8. data/generators/hoptoad/hoptoad_generator.rb +63 -0
  9. data/generators/hoptoad/lib/insert_commands.rb +34 -0
  10. data/generators/hoptoad/lib/rake_commands.rb +24 -0
  11. data/generators/hoptoad/templates/capistrano_hook.rb +6 -0
  12. data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +25 -0
  13. data/generators/hoptoad/templates/initializer.rb +6 -0
  14. data/lib/hoptoad_notifier.rb +148 -0
  15. data/lib/hoptoad_notifier/backtrace.rb +99 -0
  16. data/lib/hoptoad_notifier/capistrano.rb +20 -0
  17. data/lib/hoptoad_notifier/configuration.rb +232 -0
  18. data/lib/hoptoad_notifier/notice.rb +318 -0
  19. data/lib/hoptoad_notifier/rack.rb +40 -0
  20. data/lib/hoptoad_notifier/rails.rb +37 -0
  21. data/lib/hoptoad_notifier/rails/action_controller_catcher.rb +29 -0
  22. data/lib/hoptoad_notifier/rails/controller_methods.rb +63 -0
  23. data/lib/hoptoad_notifier/rails/error_lookup.rb +33 -0
  24. data/lib/hoptoad_notifier/rails3_tasks.rb +90 -0
  25. data/lib/hoptoad_notifier/railtie.rb +23 -0
  26. data/lib/hoptoad_notifier/sender.rb +63 -0
  27. data/lib/hoptoad_notifier/tasks.rb +97 -0
  28. data/lib/hoptoad_notifier/version.rb +3 -0
  29. data/lib/hoptoad_tasks.rb +44 -0
  30. data/lib/rails/generators/hoptoad/hoptoad_generator.rb +69 -0
  31. data/lib/templates/rescue.erb +91 -0
  32. data/rails/init.rb +1 -0
  33. data/script/integration_test.rb +38 -0
  34. data/test/backtrace_test.rb +118 -0
  35. data/test/catcher_test.rb +324 -0
  36. data/test/configuration_test.rb +208 -0
  37. data/test/helper.rb +239 -0
  38. data/test/hoptoad_tasks_test.rb +152 -0
  39. data/test/logger_test.rb +85 -0
  40. data/test/notice_test.rb +443 -0
  41. data/test/notifier_test.rb +222 -0
  42. data/test/rack_test.rb +58 -0
  43. data/test/rails_initializer_test.rb +36 -0
  44. data/test/sender_test.rb +123 -0
  45. metadata +205 -0
@@ -0,0 +1,99 @@
1
+ module HoptoadNotifier
2
+ # Front end to parsing the backtrace for each notice
3
+ class Backtrace
4
+
5
+ # Handles backtrace parsing line by line
6
+ class Line
7
+
8
+ INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
9
+
10
+ # The file portion of the line (such as app/models/user.rb)
11
+ attr_reader :file
12
+
13
+ # The line number portion of the line
14
+ attr_reader :number
15
+
16
+ # The method of the line (such as index)
17
+ attr_reader :method
18
+
19
+ # Parses a single line of a given backtrace
20
+ # @param [String] unparsed_line The raw line from +caller+ or some backtrace
21
+ # @return [Line] The parsed backtrace line
22
+ def self.parse(unparsed_line)
23
+ _, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
24
+ new(file, number, method)
25
+ end
26
+
27
+ def initialize(file, number, method)
28
+ self.file = file
29
+ self.number = number
30
+ self.method = method
31
+ end
32
+
33
+ # Reconstructs the line in a readable fashion
34
+ def to_s
35
+ "#{file}:#{number}:in `#{method}'"
36
+ end
37
+
38
+ def ==(other)
39
+ to_s == other.to_s
40
+ end
41
+
42
+ def inspect
43
+ "<Line:#{to_s}>"
44
+ end
45
+
46
+ private
47
+
48
+ attr_writer :file, :number, :method
49
+ end
50
+
51
+ # holder for an Array of Backtrace::Line instances
52
+ attr_reader :lines
53
+
54
+ def self.parse(ruby_backtrace, opts = {})
55
+ ruby_lines = split_multiline_backtrace(ruby_backtrace)
56
+
57
+ filters = opts[:filters] || []
58
+ filtered_lines = ruby_lines.to_a.map do |line|
59
+ filters.inject(line) do |line, proc|
60
+ proc.call(line)
61
+ end
62
+ end.compact
63
+
64
+ lines = filtered_lines.collect do |unparsed_line|
65
+ Line.parse(unparsed_line)
66
+ end
67
+
68
+ instance = new(lines)
69
+ end
70
+
71
+ def initialize(lines)
72
+ self.lines = lines
73
+ end
74
+
75
+ def inspect
76
+ "<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
77
+ end
78
+
79
+ def ==(other)
80
+ if other.respond_to?(:lines)
81
+ lines == other.lines
82
+ else
83
+ false
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ attr_writer :lines
90
+
91
+ def self.split_multiline_backtrace(backtrace)
92
+ if backtrace.to_a.size == 1
93
+ backtrace.to_a.first.split(/\n\s*/)
94
+ else
95
+ backtrace
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,20 @@
1
+ # Defines deploy:notify_hoptoad which will send information about the deploy to Hoptoad.
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+ after "deploy", "deploy:notify_hoptoad"
5
+ after "deploy:migrations", "deploy:notify_hoptoad"
6
+
7
+ namespace :deploy do
8
+ desc "Notify Hoptoad of the deployment"
9
+ task :notify_hoptoad, :except => { :no_release => true } do
10
+ rails_env = fetch(:hoptoad_env, fetch(:rails_env, "production"))
11
+ local_user = ENV['USER'] || ENV['USERNAME']
12
+ executable = RUBY_PLATFORM.downcase.include?('mswin') ? 'rake.bat' : 'rake'
13
+ notify_command = "#{executable} hoptoad:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
14
+ notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
15
+ puts "Notifying Hoptoad of Deploy (#{notify_command})"
16
+ `#{notify_command}`
17
+ puts "Hoptoad Notification Complete."
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,232 @@
1
+ module HoptoadNotifier
2
+ # Used to set up and modify settings for the notifier.
3
+ class Configuration
4
+
5
+ OPTIONS = [:api_key, :backtrace_filters, :development_environments,
6
+ :development_lookup, :environment_name, :host,
7
+ :http_open_timeout, :http_read_timeout, :ignore, :ignore_by_filters,
8
+ :ignore_user_agent, :notifier_name, :notifier_url, :notifier_version,
9
+ :params_filters, :project_root, :port, :protocol, :proxy_host,
10
+ :proxy_pass, :proxy_port, :proxy_user, :secure, :framework].freeze
11
+
12
+ # The API key for your project, found on the project edit form.
13
+ attr_accessor :api_key
14
+
15
+ # The host to connect to (defaults to hoptoadapp.com).
16
+ attr_accessor :host
17
+
18
+ # The port on which your Hoptoad server runs (defaults to 443 for secure
19
+ # connections, 80 for insecure connections).
20
+ attr_accessor :port
21
+
22
+ # +true+ for https connections, +false+ for http connections.
23
+ attr_accessor :secure
24
+
25
+ # The HTTP open timeout in seconds (defaults to 2).
26
+ attr_accessor :http_open_timeout
27
+
28
+ # The HTTP read timeout in seconds (defaults to 5).
29
+ attr_accessor :http_read_timeout
30
+
31
+ # The hostname of your proxy server (if using a proxy)
32
+ attr_accessor :proxy_host
33
+
34
+ # The port of your proxy server (if using a proxy)
35
+ attr_accessor :proxy_port
36
+
37
+ # The username to use when logging into your proxy server (if using a proxy)
38
+ attr_accessor :proxy_user
39
+
40
+ # The password to use when logging into your proxy server (if using a proxy)
41
+ attr_accessor :proxy_pass
42
+
43
+ # A list of parameters that should be filtered out of what is sent to Hoptoad.
44
+ # By default, all "password" attributes will have their contents replaced.
45
+ attr_reader :params_filters
46
+
47
+ # A list of filters for cleaning and pruning the backtrace. See #filter_backtrace.
48
+ attr_reader :backtrace_filters
49
+
50
+ # A list of filters for ignoring exceptions. See #ignore_by_filter.
51
+ attr_reader :ignore_by_filters
52
+
53
+ # A list of exception classes to ignore. The array can be appended to.
54
+ attr_reader :ignore
55
+
56
+ # A list of user agents that are being ignored. The array can be appended to.
57
+ attr_reader :ignore_user_agent
58
+
59
+ # A list of environments in which notifications should not be sent.
60
+ attr_accessor :development_environments
61
+
62
+ # +true+ if you want to check for production errors matching development errors, +false+ otherwise.
63
+ attr_accessor :development_lookup
64
+
65
+ # The name of the environment the application is running in
66
+ attr_accessor :environment_name
67
+
68
+ # The path to the project in which the error occurred, such as the RAILS_ROOT
69
+ attr_accessor :project_root
70
+
71
+ # The name of the notifier library being used to send notifications (such as "Hoptoad Notifier")
72
+ attr_accessor :notifier_name
73
+
74
+ # The version of the notifier library being used to send notifications (such as "1.0.2")
75
+ attr_accessor :notifier_version
76
+
77
+ # The url of the notifier library being used to send notifications
78
+ attr_accessor :notifier_url
79
+
80
+ # The logger used by HoptoadNotifier
81
+ attr_accessor :logger
82
+
83
+ # The framework HoptoadNotifier is configured to use
84
+ attr_accessor :framework
85
+
86
+ DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
87
+
88
+ DEFAULT_BACKTRACE_FILTERS = [
89
+ lambda { |line|
90
+ if defined?(HoptoadNotifier.configuration.project_root) && HoptoadNotifier.configuration.project_root.to_s != ''
91
+ line.gsub(/#{HoptoadNotifier.configuration.project_root}/, "[PROJECT_ROOT]")
92
+ else
93
+ line
94
+ end
95
+ },
96
+ lambda { |line| line.gsub(/^\.\//, "") },
97
+ lambda { |line|
98
+ if defined?(Gem)
99
+ Gem.path.inject(line) do |line, path|
100
+ line.gsub(/#{path}/, "[GEM_ROOT]")
101
+ end
102
+ end
103
+ },
104
+ lambda { |line| line if line !~ %r{lib/hoptoad_notifier} }
105
+ ].freeze
106
+
107
+ IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
108
+ 'ActionController::RoutingError',
109
+ 'ActionController::InvalidAuthenticityToken',
110
+ 'CGI::Session::CookieStore::TamperedWithCookie',
111
+ 'ActionController::UnknownAction']
112
+
113
+ alias_method :secure?, :secure
114
+
115
+ def initialize
116
+ @secure = false
117
+ @host = 'hoptoadapp.com'
118
+ @http_open_timeout = 2
119
+ @http_read_timeout = 5
120
+ @params_filters = DEFAULT_PARAMS_FILTERS.dup
121
+ @backtrace_filters = DEFAULT_BACKTRACE_FILTERS.dup
122
+ @ignore_by_filters = []
123
+ @ignore = IGNORE_DEFAULT.dup
124
+ @ignore_user_agent = []
125
+ @development_environments = %w(development test cucumber)
126
+ @development_lookup = true
127
+ @notifier_name = 'Hoptoad Notifier'
128
+ @notifier_version = VERSION
129
+ @notifier_url = 'http://hoptoadapp.com'
130
+ @framework = 'Standalone'
131
+ end
132
+
133
+ # Takes a block and adds it to the list of backtrace filters. When the filters
134
+ # run, the block will be handed each line of the backtrace and can modify
135
+ # it as necessary.
136
+ #
137
+ # @example
138
+ # config.filter_bracktrace do |line|
139
+ # line.gsub(/^#{Rails.root}/, "[RAILS_ROOT]")
140
+ # end
141
+ #
142
+ # @param [Proc] block The new backtrace filter.
143
+ # @yieldparam [String] line A line in the backtrace.
144
+ def filter_backtrace(&block)
145
+ self.backtrace_filters << block
146
+ end
147
+
148
+ # Takes a block and adds it to the list of ignore filters.
149
+ # When the filters run, the block will be handed the exception.
150
+ # @example
151
+ # config.ignore_by_filter do |exception_data|
152
+ # true if exception_data[:error_class] == "RuntimeError"
153
+ # end
154
+ #
155
+ # @param [Proc] block The new ignore filter
156
+ # @yieldparam [Hash] data The exception data given to +HoptoadNotifier.notify+
157
+ # @yieldreturn [Boolean] If the block returns true the exception will be ignored, otherwise it will be processed by hoptoad.
158
+ def ignore_by_filter(&block)
159
+ self.ignore_by_filters << block
160
+ end
161
+
162
+ # Overrides the list of default ignored errors.
163
+ #
164
+ # @param [Array<Exception>] names A list of exceptions to ignore.
165
+ def ignore_only=(names)
166
+ @ignore = [names].flatten
167
+ end
168
+
169
+ # Overrides the list of default ignored user agents
170
+ #
171
+ # @param [Array<String>] A list of user agents to ignore
172
+ def ignore_user_agent_only=(names)
173
+ @ignore_user_agent = [names].flatten
174
+ end
175
+
176
+ # Allows config options to be read like a hash
177
+ #
178
+ # @param [Symbol] option Key for a given attribute
179
+ def [](option)
180
+ send(option)
181
+ end
182
+
183
+ # Returns a hash of all configurable options
184
+ def to_hash
185
+ OPTIONS.inject({}) do |hash, option|
186
+ hash.merge(option.to_sym => send(option))
187
+ end
188
+ end
189
+
190
+ # Returns a hash of all configurable options merged with +hash+
191
+ #
192
+ # @param [Hash] hash A set of configuration options that will take precedence over the defaults
193
+ def merge(hash)
194
+ to_hash.merge(hash)
195
+ end
196
+
197
+ # Determines if the notifier will send notices.
198
+ # @return [Boolean] Returns +false+ if in a development environment, +true+ otherwise.
199
+ def public?
200
+ !development_environments.include?(environment_name)
201
+ end
202
+
203
+ def port
204
+ @port || default_port
205
+ end
206
+
207
+ def protocol
208
+ if secure?
209
+ 'https'
210
+ else
211
+ 'http'
212
+ end
213
+ end
214
+
215
+ def environment_filters
216
+ warn 'config.environment_filters has been deprecated and has no effect.'
217
+ []
218
+ end
219
+
220
+ private
221
+
222
+ def default_port
223
+ if secure?
224
+ 443
225
+ else
226
+ 80
227
+ end
228
+ end
229
+
230
+ end
231
+
232
+ end
@@ -0,0 +1,318 @@
1
+ require 'builder'
2
+
3
+ module HoptoadNotifier
4
+ class Notice
5
+
6
+ # The exception that caused this notice, if any
7
+ attr_reader :exception
8
+
9
+ # The API key for the project to which this notice should be sent
10
+ attr_reader :api_key
11
+
12
+ # The backtrace from the given exception or hash.
13
+ attr_reader :backtrace
14
+
15
+ # The name of the class of error (such as RuntimeError)
16
+ attr_reader :error_class
17
+
18
+ # The name of the server environment (such as "production")
19
+ attr_reader :environment_name
20
+
21
+ # CGI variables such as HTTP_METHOD
22
+ attr_reader :cgi_data
23
+
24
+ # The message from the exception, or a general description of the error
25
+ attr_reader :error_message
26
+
27
+ # See Configuration#backtrace_filters
28
+ attr_reader :backtrace_filters
29
+
30
+ # See Configuration#params_filters
31
+ attr_reader :params_filters
32
+
33
+ # A hash of parameters from the query string or post body.
34
+ attr_reader :parameters
35
+ alias_method :params, :parameters
36
+
37
+ # The component (if any) which was used in this request (usually the controller)
38
+ attr_reader :component
39
+ alias_method :controller, :component
40
+
41
+ # The action (if any) that was called in this request
42
+ attr_reader :action
43
+
44
+ # A hash of session data from the request
45
+ attr_reader :session_data
46
+
47
+ # The path to the project that caused the error (usually RAILS_ROOT)
48
+ attr_reader :project_root
49
+
50
+ # The URL at which the error occurred (if any)
51
+ attr_reader :url
52
+
53
+ # See Configuration#ignore
54
+ attr_reader :ignore
55
+
56
+ # See Configuration#ignore_by_filters
57
+ attr_reader :ignore_by_filters
58
+
59
+ # The name of the notifier library sending this notice, such as "Hoptoad Notifier"
60
+ attr_reader :notifier_name
61
+
62
+ # The version number of the notifier library sending this notice, such as "2.1.3"
63
+ attr_reader :notifier_version
64
+
65
+ # A URL for more information about the notifier library sending this notice
66
+ attr_reader :notifier_url
67
+
68
+ def initialize(args)
69
+ self.args = args
70
+ self.exception = args[:exception]
71
+ self.api_key = args[:api_key]
72
+ self.project_root = args[:project_root]
73
+ self.url = args[:url] || rack_env(:url)
74
+
75
+ self.notifier_name = args[:notifier_name]
76
+ self.notifier_version = args[:notifier_version]
77
+ self.notifier_url = args[:notifier_url]
78
+
79
+ self.ignore = args[:ignore] || []
80
+ self.ignore_by_filters = args[:ignore_by_filters] || []
81
+ self.backtrace_filters = args[:backtrace_filters] || []
82
+ self.params_filters = args[:params_filters] || []
83
+ self.parameters = args[:parameters] ||
84
+ action_dispatch_params ||
85
+ rack_env(:params) ||
86
+ {}
87
+ self.component = args[:component] || args[:controller] || parameters['controller']
88
+ self.action = args[:action] || parameters['action']
89
+
90
+ self.environment_name = args[:environment_name]
91
+ self.cgi_data = args[:cgi_data] || args[:rack_env]
92
+ self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller), :filters => self.backtrace_filters)
93
+ self.error_class = exception_attribute(:error_class) {|exception| exception.class.name }
94
+ self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
95
+ "#{exception.class.name}: #{exception.message}"
96
+ end
97
+
98
+ find_session_data
99
+ clean_params
100
+ end
101
+
102
+ # Converts the given notice to XML
103
+ def to_xml
104
+ builder = Builder::XmlMarkup.new
105
+ builder.instruct!
106
+ xml = builder.notice(:version => HoptoadNotifier::API_VERSION) do |notice|
107
+ notice.tag!("api-key", api_key)
108
+ notice.notifier do |notifier|
109
+ notifier.name(notifier_name)
110
+ notifier.version(notifier_version)
111
+ notifier.url(notifier_url)
112
+ end
113
+ notice.error do |error|
114
+ error.tag!('class', error_class)
115
+ error.message(error_message)
116
+ error.backtrace do |backtrace|
117
+ self.backtrace.lines.each do |line|
118
+ backtrace.line(:number => line.number,
119
+ :file => line.file,
120
+ :method => line.method)
121
+ end
122
+ end
123
+ end
124
+ if url ||
125
+ controller ||
126
+ action ||
127
+ !parameters.blank? ||
128
+ !cgi_data.blank? ||
129
+ !session_data.blank?
130
+ notice.request do |request|
131
+ request.url(url)
132
+ request.component(controller)
133
+ request.action(action)
134
+ unless parameters.nil? || parameters.empty?
135
+ request.params do |params|
136
+ xml_vars_for(params, parameters)
137
+ end
138
+ end
139
+ unless session_data.nil? || session_data.empty?
140
+ request.session do |session|
141
+ xml_vars_for(session, session_data)
142
+ end
143
+ end
144
+ unless cgi_data.nil? || cgi_data.empty?
145
+ request.tag!("cgi-data") do |cgi_datum|
146
+ xml_vars_for(cgi_datum, cgi_data)
147
+ end
148
+ end
149
+ end
150
+ end
151
+ notice.tag!("server-environment") do |env|
152
+ env.tag!("project-root", project_root)
153
+ env.tag!("environment-name", environment_name)
154
+ end
155
+ end
156
+ xml.to_s
157
+ end
158
+
159
+ # Determines if this notice should be ignored
160
+ def ignore?
161
+ ignored_class_names.include?(error_class) ||
162
+ ignore_by_filters.any? {|filter| filter.call(self) }
163
+ end
164
+
165
+ # Allows properties to be accessed using a hash-like syntax
166
+ #
167
+ # @example
168
+ # notice[:error_message]
169
+ # @param [String] method The given key for an attribute
170
+ # @return The attribute value, or self if given +:request+
171
+ def [](method)
172
+ case method
173
+ when :request
174
+ self
175
+ else
176
+ send(method)
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ attr_writer :exception, :api_key, :backtrace, :error_class, :error_message,
183
+ :backtrace_filters, :parameters, :params_filters,
184
+ :environment_filters, :session_data, :project_root, :url, :ignore,
185
+ :ignore_by_filters, :notifier_name, :notifier_url, :notifier_version,
186
+ :component, :action, :cgi_data, :environment_name
187
+
188
+ # Arguments given in the initializer
189
+ attr_accessor :args
190
+
191
+ # Gets a property named +attribute+ of an exception, either from an actual
192
+ # exception or a hash.
193
+ #
194
+ # If an exception is available, #from_exception will be used. Otherwise,
195
+ # a key named +attribute+ will be used from the #args.
196
+ #
197
+ # If no exception or hash key is available, +default+ will be used.
198
+ def exception_attribute(attribute, default = nil, &block)
199
+ (exception && from_exception(attribute, &block)) || args[attribute] || default
200
+ end
201
+
202
+ # Gets a property named +attribute+ from an exception.
203
+ #
204
+ # If a block is given, it will be used when getting the property from an
205
+ # exception. The block should accept and exception and return the value for
206
+ # the property.
207
+ #
208
+ # If no block is given, a method with the same name as +attribute+ will be
209
+ # invoked for the value.
210
+ def from_exception(attribute)
211
+ if block_given?
212
+ yield(exception)
213
+ else
214
+ exception.send(attribute)
215
+ end
216
+ end
217
+
218
+ # Removes non-serializable data from the given attribute.
219
+ # See #clean_unserializable_data
220
+ def clean_unserializable_data_from(attribute)
221
+ self.send(:"#{attribute}=", clean_unserializable_data(send(attribute)))
222
+ end
223
+
224
+ # Removes non-serializable data. Allowed data types are strings, arrays,
225
+ # and hashes. All other types are converted to strings.
226
+ # TODO: move this onto Hash
227
+ def clean_unserializable_data(data)
228
+ if data.respond_to?(:to_hash)
229
+ data.to_hash.inject({}) do |result, (key, value)|
230
+ result.merge(key => clean_unserializable_data(value))
231
+ end
232
+ elsif data.respond_to?(:to_ary)
233
+ data.collect do |value|
234
+ clean_unserializable_data(value)
235
+ end
236
+ else
237
+ data.to_s
238
+ end
239
+ end
240
+
241
+ # Replaces the contents of params that match params_filters.
242
+ # TODO: extract this to a different class
243
+ def clean_params
244
+ clean_unserializable_data_from(:parameters)
245
+ filter(parameters)
246
+ if cgi_data
247
+ clean_unserializable_data_from(:cgi_data)
248
+ filter(cgi_data)
249
+ end
250
+ if session_data
251
+ clean_unserializable_data_from(:session_data)
252
+ end
253
+ end
254
+
255
+ def filter(hash)
256
+ if params_filters
257
+ hash.each do |key, value|
258
+ if filter_key?(key)
259
+ hash[key] = "[FILTERED]"
260
+ elsif value.respond_to?(:to_hash)
261
+ filter(hash[key])
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+ def filter_key?(key)
268
+ params_filters.any? do |filter|
269
+ key.to_s.include?(filter)
270
+ end
271
+ end
272
+
273
+ def find_session_data
274
+ self.session_data = args[:session_data] || args[:session] || rack_session || {}
275
+ self.session_data = session_data[:data] if session_data[:data]
276
+ end
277
+
278
+ # Converts the mixed class instances and class names into just names
279
+ # TODO: move this into Configuration or another class
280
+ def ignored_class_names
281
+ ignore.collect do |string_or_class|
282
+ if string_or_class.respond_to?(:name)
283
+ string_or_class.name
284
+ else
285
+ string_or_class
286
+ end
287
+ end
288
+ end
289
+
290
+ def xml_vars_for(builder, hash)
291
+ hash.each do |key, value|
292
+ if value.respond_to?(:to_hash)
293
+ builder.var(:key => key){|b| xml_vars_for(b, value.to_hash) }
294
+ else
295
+ builder.var(value.to_s, :key => key)
296
+ end
297
+ end
298
+ end
299
+
300
+ def rack_env(method)
301
+ rack_request.send(method) if rack_request
302
+ end
303
+
304
+ def rack_request
305
+ @rack_request ||= if args[:rack_env]
306
+ ::Rack::Request.new(args[:rack_env])
307
+ end
308
+ end
309
+
310
+ def action_dispatch_params
311
+ args[:rack_env]['action_dispatch.request.parameters'] if args[:rack_env]
312
+ end
313
+
314
+ def rack_session
315
+ args[:rack_env]['rack.session'] if args[:rack_env]
316
+ end
317
+ end
318
+ end