errornot_notifier 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/INSTALL +25 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.rdoc +289 -0
  4. data/Rakefile +124 -0
  5. data/SUPPORTED_RAILS_VERSIONS +8 -0
  6. data/TESTING.rdoc +8 -0
  7. data/generators/hoptoad/hoptoad_generator.rb +55 -0
  8. data/generators/hoptoad/lib/insert_commands.rb +34 -0
  9. data/generators/hoptoad/lib/rake_commands.rb +24 -0
  10. data/generators/hoptoad/templates/capistrano_hook.rb +6 -0
  11. data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +5 -0
  12. data/generators/hoptoad/templates/initializer.rb +7 -0
  13. data/lib/hoptoad_notifier/backtrace.rb +99 -0
  14. data/lib/hoptoad_notifier/capistrano.rb +20 -0
  15. data/lib/hoptoad_notifier/configuration.rb +232 -0
  16. data/lib/hoptoad_notifier/notice.rb +287 -0
  17. data/lib/hoptoad_notifier/rack.rb +40 -0
  18. data/lib/hoptoad_notifier/rails/action_controller_catcher.rb +29 -0
  19. data/lib/hoptoad_notifier/rails/controller_methods.rb +59 -0
  20. data/lib/hoptoad_notifier/rails/error_lookup.rb +33 -0
  21. data/lib/hoptoad_notifier/rails.rb +37 -0
  22. data/lib/hoptoad_notifier/sender.rb +85 -0
  23. data/lib/hoptoad_notifier/tasks.rb +97 -0
  24. data/lib/hoptoad_notifier/version.rb +3 -0
  25. data/lib/hoptoad_notifier.rb +146 -0
  26. data/lib/hoptoad_tasks.rb +37 -0
  27. data/lib/templates/rescue.erb +91 -0
  28. data/rails/init.rb +1 -0
  29. data/script/integration_test.rb +38 -0
  30. data/test/backtrace_test.rb +118 -0
  31. data/test/catcher_test.rb +300 -0
  32. data/test/configuration_test.rb +208 -0
  33. data/test/helper.rb +232 -0
  34. data/test/hoptoad_tasks_test.rb +138 -0
  35. data/test/logger_test.rb +85 -0
  36. data/test/notice_test.rb +395 -0
  37. data/test/notifier_test.rb +222 -0
  38. data/test/rack_test.rb +58 -0
  39. data/test/rails_initializer_test.rb +36 -0
  40. data/test/sender_test.rb +123 -0
  41. metadata +164 -0
@@ -0,0 +1,59 @@
1
+ module HoptoadNotifier
2
+ module Rails
3
+ module ControllerMethods
4
+ private
5
+
6
+ # This method should be used for sending manual notifications while you are still
7
+ # inside the controller. Otherwise it works like HoptoadNotifier.notify.
8
+ def notify_hoptoad(hash_or_exception)
9
+ unless consider_all_requests_local || local_request?
10
+ HoptoadNotifier.notify(hash_or_exception, hoptoad_request_data)
11
+ end
12
+ end
13
+
14
+ def hoptoad_ignore_user_agent? #:nodoc:
15
+ # Rails 1.2.6 doesn't have request.user_agent, so check for it here
16
+ user_agent = request.respond_to?(:user_agent) ? request.user_agent : request.env["HTTP_USER_AGENT"]
17
+ HoptoadNotifier.configuration.ignore_user_agent.flatten.any? { |ua| ua === user_agent }
18
+ end
19
+
20
+ def hoptoad_request_data
21
+ { :parameters => hoptoad_filter_if_filtering(params.to_hash),
22
+ :session_data => hoptoad_session_data,
23
+ :controller => params[:controller],
24
+ :action => params[:action],
25
+ :url => hoptoad_request_url,
26
+ :cgi_data => hoptoad_filter_if_filtering(request.env),
27
+ :environment_vars => hoptoad_filter_if_filtering(ENV) }
28
+ end
29
+
30
+ def hoptoad_filter_if_filtering(hash)
31
+ if respond_to?(:filter_parameters)
32
+ filter_parameters(hash) rescue hash
33
+ else
34
+ hash
35
+ end
36
+ end
37
+
38
+ def hoptoad_session_data
39
+ if session.respond_to?(:to_hash)
40
+ session.to_hash
41
+ else
42
+ session.data
43
+ end
44
+ end
45
+
46
+ def hoptoad_request_url
47
+ url = "#{request.protocol}#{request.host}"
48
+
49
+ unless [80, 443].include?(request.port)
50
+ url << ":#{request.port}"
51
+ end
52
+
53
+ url << request.request_uri
54
+ url
55
+ end
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,33 @@
1
+ module HoptoadNotifier
2
+ module Rails
3
+ module ErrorLookup
4
+
5
+ # Sets up an alias chain to catch exceptions when Rails does
6
+ def self.included(base) #:nodoc:
7
+ base.send(:alias_method, :rescue_action_locally_without_hoptoad, :rescue_action_locally)
8
+ base.send(:alias_method, :rescue_action_locally, :rescue_action_locally_with_hoptoad)
9
+ end
10
+
11
+ private
12
+
13
+ def rescue_action_locally_with_hoptoad(exception)
14
+ result = rescue_action_locally_without_hoptoad(exception)
15
+
16
+ if HoptoadNotifier.configuration.development_lookup
17
+ path = File.join(File.dirname(__FILE__), '..', '..', 'templates', 'rescue.erb')
18
+ notice = HoptoadNotifier.build_lookup_hash_for(exception, hoptoad_request_data)
19
+
20
+ result << @template.render(
21
+ :file => path,
22
+ :use_full_path => false,
23
+ :locals => { :host => HoptoadNotifier.configuration.host,
24
+ :api_key => HoptoadNotifier.configuration.api_key,
25
+ :notice => notice })
26
+ end
27
+
28
+ result
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,37 @@
1
+ require 'hoptoad_notifier'
2
+ require 'hoptoad_notifier/rails/controller_methods'
3
+ require 'hoptoad_notifier/rails/action_controller_catcher'
4
+ require 'hoptoad_notifier/rails/error_lookup'
5
+
6
+ module HoptoadNotifier
7
+ module Rails
8
+ def self.initialize
9
+ if defined?(ActionController::Base)
10
+ ActionController::Base.send(:include, HoptoadNotifier::Rails::ActionControllerCatcher)
11
+ ActionController::Base.send(:include, HoptoadNotifier::Rails::ErrorLookup)
12
+ ActionController::Base.send(:include, HoptoadNotifier::Rails::ControllerMethods)
13
+ end
14
+
15
+ rails_logger = if defined?(::Rails.logger)
16
+ ::Rails.logger
17
+ elsif defined?(RAILS_DEFAULT_LOGGER)
18
+ RAILS_DEFAULT_LOGGER
19
+ end
20
+
21
+ if defined?(::Rails.configuration) && ::Rails.configuration.respond_to?(:middleware)
22
+ ::Rails.configuration.middleware.insert_after 'ActionController::Failsafe',
23
+ HoptoadNotifier::Rack
24
+ end
25
+
26
+ HoptoadNotifier.configure(true) do |config|
27
+ config.logger = rails_logger
28
+ config.environment_name = RAILS_ENV if defined?(RAILS_ENV)
29
+ config.project_root = RAILS_ROOT if defined?(RAILS_ROOT)
30
+ config.framework = "Rails: #{::Rails::VERSION::STRING}" if defined?(::Rails::VERSION)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ HoptoadNotifier::Rails.initialize
37
+
@@ -0,0 +1,85 @@
1
+ module HoptoadNotifier
2
+ # Sends out the notice to Hoptoad
3
+ class Sender
4
+
5
+ NOTICES_URI = '/errors'.freeze
6
+
7
+ def initialize(options = {})
8
+ [:proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
9
+ :host, :port, :secure, :http_open_timeout, :http_read_timeout].each do |option|
10
+ instance_variable_set("@#{option}", options[option])
11
+ end
12
+ end
13
+
14
+ # Methode extract from RestClient
15
+ # maybe need some test
16
+ def process_payload(p=nil, parent_key=nil)
17
+ unless p.is_a?(Hash)
18
+ p
19
+ else
20
+ p.keys.map do |k|
21
+ key = parent_key ? "#{parent_key}[#{k}]" : k
22
+ if p[k].is_a? Hash
23
+ process_payload(p[k], key)
24
+ else
25
+ value = URI.escape(p[k].to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
26
+ "#{key}=#{value}"
27
+ end
28
+ end.join("&")
29
+ end
30
+ end
31
+
32
+
33
+ # Sends the notice data off to Hoptoad for processing.
34
+ #
35
+ # @param [String] data The XML notice to be sent off
36
+ def send_to_hoptoad(data)
37
+ logger.debug { "Sending request to #{url.to_s}:\n#{data}" } if logger
38
+
39
+ http =
40
+ Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).
41
+ new(url.host, url.port)
42
+
43
+ http.read_timeout = http_read_timeout
44
+ http.open_timeout = http_open_timeout
45
+ http.use_ssl = secure
46
+
47
+ response = begin
48
+ # TODO see how use http.post or convert all to restclient
49
+ #RestClient.post(url.to_s, data)
50
+ data = process_payload(data)
51
+ http.post(url.path, data, HEADERS)
52
+ rescue TimeoutError => e
53
+ log :error, "Timeout while contacting the Hoptoad server."
54
+ nil
55
+ end
56
+
57
+ case response
58
+ when Net::HTTPSuccess then
59
+ log :info, "Success: #{response.class}", response
60
+ else
61
+ log :error, "Failure: #{response.class}", response
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ attr_reader :proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
68
+ :host, :port, :secure, :http_open_timeout, :http_read_timeout
69
+
70
+ def url
71
+ URI.parse("#{protocol}://#{host}:#{port}").merge(NOTICES_URI)
72
+ end
73
+
74
+ def log(level, message, response = nil)
75
+ logger.send level, LOG_PREFIX + message if logger
76
+ HoptoadNotifier.report_environment_info
77
+ HoptoadNotifier.report_response_body(response.body) if response && response.respond_to?(:body)
78
+ end
79
+
80
+ def logger
81
+ HoptoadNotifier.logger
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,97 @@
1
+ require 'hoptoad_notifier'
2
+
3
+ namespace :hoptoad do
4
+ desc "Notify Hoptoad of a new deploy."
5
+ task :deploy => :environment do
6
+ require 'hoptoad_tasks'
7
+ HoptoadTasks.deploy(:rails_env => ENV['TO'],
8
+ :scm_revision => ENV['REVISION'],
9
+ :scm_repository => ENV['REPO'],
10
+ :local_username => ENV['USER'],
11
+ :api_key => ENV['API_KEY'])
12
+ end
13
+
14
+ task :log_stdout do
15
+ require 'logger'
16
+ RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
17
+ end
18
+
19
+ desc "Verify your gem installation by sending a test exception to the hoptoad service"
20
+ task :test => ['hoptoad:log_stdout', :environment] do
21
+ RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
22
+
23
+ require 'action_controller/test_process'
24
+
25
+ Dir["app/controllers/application*.rb"].each { |file| require(file) }
26
+
27
+ class HoptoadTestingException < RuntimeError; end
28
+
29
+ unless HoptoadNotifier.configuration.api_key
30
+ puts "Hoptoad needs an API key configured! Check the README to see how to add it."
31
+ exit
32
+ end
33
+
34
+ HoptoadNotifier.configuration.development_environments = []
35
+
36
+ catcher = HoptoadNotifier::Rails::ActionControllerCatcher
37
+ in_controller = ApplicationController.included_modules.include?(catcher)
38
+ in_base = ActionController::Base.included_modules.include?(catcher)
39
+ if !in_controller || !in_base
40
+ puts "Rails initialization did not occur"
41
+ exit
42
+ end
43
+
44
+ puts "Configuration:"
45
+ HoptoadNotifier.configuration.to_hash.each do |key, value|
46
+ puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
47
+ end
48
+
49
+ unless defined?(ApplicationController)
50
+ puts "No ApplicationController found"
51
+ exit
52
+ end
53
+
54
+ puts 'Setting up the Controller.'
55
+ class ApplicationController
56
+ # This is to bypass any filters that may prevent access to the action.
57
+ prepend_before_filter :test_hoptoad
58
+ def test_hoptoad
59
+ puts "Raising '#{exception_class.name}' to simulate application failure."
60
+ raise exception_class.new, 'Testing hoptoad via "rake hoptoad:test". If you can see this, it works.'
61
+ end
62
+
63
+ def rescue_action(exception)
64
+ rescue_action_in_public exception
65
+ end
66
+
67
+ # Ensure we actually have an action to go to.
68
+ def verify; end
69
+
70
+ def consider_all_requests_local
71
+ false
72
+ end
73
+
74
+ def local_request?
75
+ false
76
+ end
77
+
78
+ def exception_class
79
+ exception_name = ENV['EXCEPTION'] || "HoptoadTestingException"
80
+ Object.const_get(exception_name)
81
+ rescue
82
+ Object.const_set(exception_name, Class.new(Exception))
83
+ end
84
+
85
+ def logger
86
+ nil
87
+ end
88
+ end
89
+ class HoptoadVerificationController < ApplicationController; end
90
+
91
+ puts 'Processing request.'
92
+ request = ActionController::TestRequest.new
93
+ response = ActionController::TestResponse.new
94
+ HoptoadVerificationController.new.process(request, response)
95
+ end
96
+ end
97
+
@@ -0,0 +1,3 @@
1
+ module HoptoadNotifier
2
+ VERSION = "0.1.0".freeze
3
+ end
@@ -0,0 +1,146 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'rubygems'
4
+ require 'active_support'
5
+ require 'hoptoad_notifier/version'
6
+ require 'hoptoad_notifier/configuration'
7
+ require 'hoptoad_notifier/notice'
8
+ require 'hoptoad_notifier/sender'
9
+ require 'hoptoad_notifier/backtrace'
10
+ require 'hoptoad_notifier/rack'
11
+
12
+ # Gem for applications to automatically post errors to the Hoptoad of their choice.
13
+ module HoptoadNotifier
14
+
15
+ API_VERSION = "1.0"
16
+ LOG_PREFIX = "** [ErrorNot Logger] "
17
+
18
+ HEADERS = {
19
+ 'Content-type' => 'application/x-www-form-urlencoded',
20
+ 'Accept' => 'text/json'
21
+ }
22
+
23
+ class << self
24
+ # The sender object is responsible for delivering formatted data to the Hoptoad server.
25
+ # Must respond to #send_to_hoptoad. See HoptoadNotifier::Sender.
26
+ attr_accessor :sender
27
+
28
+ # A Hoptoad configuration object. Must act like a hash and return sensible
29
+ # values for all Hoptoad configuration options. See HoptoadNotifier::Configuration.
30
+ attr_accessor :configuration
31
+
32
+ # Tell the log that the Notifier is good to go
33
+ def report_ready
34
+ write_verbose_log("Notifier #{VERSION} ready to catch errors")
35
+ end
36
+
37
+ # Prints out the environment info to the log for debugging help
38
+ def report_environment_info
39
+ write_verbose_log("Environment Info: #{environment_info}")
40
+ end
41
+
42
+ # Prints out the response body from Hoptoad for debugging help
43
+ def report_response_body(response)
44
+ write_verbose_log("Response from Hoptoad: \n#{response}")
45
+ end
46
+
47
+ # Returns the Ruby version, Rails version, and current Rails environment
48
+ def environment_info
49
+ info = "[Ruby: #{RUBY_VERSION}]"
50
+ info << " [#{configuration.framework}]"
51
+ info << " [Env: #{configuration.environment_name}]"
52
+ end
53
+
54
+ # Writes out the given message to the #logger
55
+ def write_verbose_log(message)
56
+ logger.info LOG_PREFIX + message if logger
57
+ end
58
+
59
+ # Look for the Rails logger currently defined
60
+ def logger
61
+ self.configuration.logger
62
+ end
63
+
64
+ # Call this method to modify defaults in your initializers.
65
+ #
66
+ # @example
67
+ # HoptoadNotifier.configure do |config|
68
+ # config.api_key = '1234567890abcdef'
69
+ # config.secure = false
70
+ # end
71
+ def configure(silent = false)
72
+ self.configuration ||= Configuration.new
73
+ yield(configuration)
74
+ self.sender = Sender.new(configuration)
75
+ report_ready unless silent
76
+ end
77
+
78
+ # Sends an exception manually using this method, even when you are not in a controller.
79
+ #
80
+ # @param [Exception] exception The exception you want to notify Hoptoad about.
81
+ # @param [Hash] opts Data that will be sent to Hoptoad.
82
+ #
83
+ # @option opts [String] :api_key The API key for this project. The API key is a unique identifier that Hoptoad uses for identification.
84
+ # @option opts [String] :error_message The error returned by the exception (or the message you want to log).
85
+ # @option opts [String] :backtrace A backtrace, usually obtained with +caller+.
86
+ # @option opts [String] :request The controller's request object.
87
+ # @option opts [String] :session The contents of the user's session.
88
+ # @option opts [String] :environment ENV merged with the contents of the request's environment.
89
+ def notify(exception, opts = {})
90
+ send_notice(build_notice_for(exception, opts))
91
+ end
92
+
93
+ # Sends the notice unless it is one of the default ignored exceptions
94
+ # @see HoptoadNotifier.notify
95
+ def notify_or_ignore(exception, opts = {})
96
+ notice = build_notice_for(exception, opts)
97
+ send_notice(notice) unless notice.ignore?
98
+ end
99
+
100
+ def build_lookup_hash_for(exception, options = {})
101
+ notice = build_notice_for(exception, options)
102
+
103
+ result = {}
104
+ result[:action] = notice.action rescue nil
105
+ result[:component] = notice.component rescue nil
106
+ result[:error_class] = notice.error_class if notice.error_class
107
+ result[:environment_name] = 'production'
108
+
109
+ unless notice.backtrace.lines.empty?
110
+ result[:file] = notice.backtrace.lines.first.file
111
+ result[:line_number] = notice.backtrace.lines.first.number
112
+ end
113
+
114
+ result
115
+ end
116
+
117
+ private
118
+
119
+ def send_notice(notice)
120
+ if configuration.public?
121
+ sender.send_to_hoptoad(notice.to_xml)
122
+ end
123
+ end
124
+
125
+ def build_notice_for(exception, opts = {})
126
+ exception = unwrap_exception(exception)
127
+ if exception.respond_to?(:to_hash)
128
+ opts = opts.merge(exception)
129
+ else
130
+ opts = opts.merge(:exception => exception)
131
+ end
132
+ Notice.new(configuration.merge(opts))
133
+ end
134
+
135
+ def unwrap_exception(exception)
136
+ if exception.respond_to?(:original_exception)
137
+ exception.original_exception
138
+ elsif exception.respond_to?(:continued_exception)
139
+ exception.continued_exception
140
+ else
141
+ exception
142
+ end
143
+ end
144
+ end
145
+ end
146
+
@@ -0,0 +1,37 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'active_support'
4
+
5
+ # Capistrano tasks for notifying Hoptoad of deploys
6
+ module HoptoadTasks
7
+
8
+ # Alerts Hoptoad of a deploy.
9
+ #
10
+ # @param [Hash] opts Data about the deploy that is set to Hoptoad
11
+ #
12
+ # @option opts [String] :rails_env Environment of the deploy (production, staging)
13
+ # @option opts [String] :scm_revision The given revision/sha that is being deployed
14
+ # @option opts [String] :scm_repository Address of your repository to help with code lookups
15
+ # @option opts [String] :local_username Who is deploying
16
+ def self.deploy(opts = {})
17
+ if HoptoadNotifier.configuration.api_key.blank?
18
+ puts "I don't seem to be configured with an API key. Please check your configuration."
19
+ return false
20
+ end
21
+
22
+ if opts[:rails_env].blank?
23
+ puts "I don't know to which Rails environment you are deploying (use the TO=production option)."
24
+ return false
25
+ end
26
+
27
+ params = {'api_key' => opts.delete(:api_key) ||
28
+ HoptoadNotifier.configuration.api_key}
29
+ opts.each {|k,v| params["deploy[#{k}]"] = v }
30
+
31
+ url = URI.parse("http://#{HoptoadNotifier.configuration.host || 'hoptoadapp.com'}/deploys.txt")
32
+ response = Net::HTTP.post_form(url, params)
33
+ puts response.body
34
+ return Net::HTTPSuccess === response
35
+ end
36
+ end
37
+
@@ -0,0 +1,91 @@
1
+ <script type="text/javascript">
2
+ var Hoptoad = {
3
+ host : <%= host.to_json %>,
4
+ api_key : <%= api_key.to_json %>,
5
+ notice : <%= notice.to_json %>,
6
+ message : 'This error exists in production!',
7
+
8
+ initialize: function() {
9
+ if (this.initialized) {
10
+ return;
11
+ } else {
12
+ this.initialized = true;
13
+ }
14
+
15
+ var data = [];
16
+
17
+ for (var key in this.notice) {
18
+ data[data.length] = 'notice[' + key + ']=' + this.notice[key];
19
+ }
20
+
21
+ data[data.length] = 'notice[api_key]=' + this.api_key;
22
+ data[data.length] = 'callback=Hoptoad.onSuccess';
23
+ data[data.length] = '_=' + (new Date()).getTime();
24
+
25
+ var head = document.getElementsByTagName('head')[0];
26
+ var done = false;
27
+
28
+ var
29
+ script = document.createElement('script');
30
+ script.src = 'http://' + this.host + '/notices_api/v1/notices/exist?' +
31
+ data.join('&');
32
+ script.type = 'text/javascript';
33
+ script.onload = script.onreadystatechange = function(){
34
+ if (!done && (!this.readyState ||
35
+ this.readyState == 'loaded' || this.readyState == 'complete')) {
36
+
37
+ done = true;
38
+
39
+ // Handle memory leak in IE. (via jQuery)
40
+ script.onload = script.onreadystatechange = null;
41
+ head.removeChild(script);
42
+ }
43
+ };
44
+
45
+ head.appendChild(script);
46
+ },
47
+
48
+ onSuccess: function(error) {
49
+ var body = document.getElementsByTagName('body')[0];
50
+ var text = document.createTextNode(this.message);
51
+ var element = document.createElement('a');
52
+
53
+ element.id = 'hoptoad';
54
+ element.href = 'http://' + error.subdomain + '.' + this.host +
55
+ '/projects/' + error.project_id + '/errors/' + error.id;
56
+ element.appendChild(text);
57
+
58
+ body.insertBefore(element, body.firstChild);
59
+
60
+ var h1 = document.getElementsByTagName('h1')[0];
61
+ var pre = document.getElementsByTagName('pre')[0];
62
+ var wrapper = document.createElement('div');
63
+
64
+ wrapper.id = 'wrapper';
65
+ wrapper.appendChild(h1);
66
+ wrapper.appendChild(pre);
67
+
68
+ body.insertBefore(wrapper, body.children[1]);
69
+ }
70
+ };
71
+
72
+ window.onload = function() {
73
+ Hoptoad.initialize.apply(Hoptoad);
74
+ };
75
+ </script>
76
+
77
+ <style type="text/css">
78
+ #hoptoad {
79
+ background: #FFF url(http://hoptoadapp.com/images/fell-off-the-toad.gif) no-repeat top right;
80
+ color: #F00;
81
+ padding: 45px 101px 45px 12px;
82
+ font-size: 14px;
83
+ font-weight: bold;
84
+ display: block;
85
+ float: right;
86
+ }
87
+
88
+ #wrapper {
89
+ padding-right: 360px;
90
+ }
91
+ </style>
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'hoptoad_notifier/rails'
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'logger'
4
+ require 'fileutils'
5
+
6
+ RAILS_ENV = "production"
7
+ RAILS_ROOT = FileUtils.pwd
8
+ RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
9
+
10
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+ require 'hoptoad_notifier'
12
+ require 'rails/init'
13
+
14
+ fail "Please supply an API Key as the first argument" if ARGV.empty?
15
+
16
+ host = ARGV[1]
17
+ host ||= "hoptoadapp.com"
18
+
19
+ secure = (ARGV[2] == "secure")
20
+
21
+ exception = begin
22
+ raise "Testing hoptoad notifier with secure = #{secure}. If you can see this, it works."
23
+ rescue => foo
24
+ foo
25
+ end
26
+
27
+ HoptoadNotifier.configure do |config|
28
+ config.secure = secure
29
+ config.host = host
30
+ config.api_key = ARGV.first
31
+ end
32
+ puts "Configuration:"
33
+ HoptoadNotifier.configuration.to_hash.each do |key, value|
34
+ puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
35
+ end
36
+ puts "Sending #{secure ? "" : "in"}secure notification to project with key #{ARGV.first}"
37
+ HoptoadNotifier.notify(exception)
38
+