jordan-brough-hoptoad_notifier 2.3.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.
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