lilypad 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2009 Winton Welsh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,29 @@
1
+ Lilypad
2
+ =======
3
+
4
+ Hoptoad notifier for Rack-based frameworks.
5
+
6
+ Install
7
+ -------
8
+
9
+ <pre>
10
+ sudo gem install lilypad --source http://gemcutter.org
11
+ </pre>
12
+
13
+ Use it
14
+ ------
15
+
16
+ <pre>
17
+ require 'rubygems'
18
+ require 'rack/lilypad'
19
+
20
+ use Rack::Lilypad, 'fd48c7d26f724503a0280f808f44b339fc65fab8'
21
+ </pre>
22
+
23
+ To specify environment filters:
24
+
25
+ <pre>
26
+ use Rack::Lilypad, 'fd48c7d26f724503a0280f808f44b339fc65fab8' do |hoptoad|
27
+ hoptoad.filters << %w(AWS_ACCESS_KEY AWS_SECRET_ACCESS_KEY AWS_ACCOUNT SSH_AUTH_SOCK)
28
+ end
29
+ </pre>
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/gempackagetask'
4
+ require 'spec/rake/spectask'
5
+ require 'gemspec'
6
+
7
+ desc "Generate gemspec"
8
+ task :gemspec do
9
+ File.open("#{Dir.pwd}/#{GEM_NAME}.gemspec", 'w') do |f|
10
+ f.write(GEM_SPEC.to_ruby)
11
+ end
12
+ end
13
+
14
+ desc "Install gem"
15
+ task :install do
16
+ Rake::Task['gem'].invoke
17
+ `sudo gem uninstall #{GEM_NAME} -x`
18
+ `sudo gem install pkg/#{GEM_NAME}*.gem`
19
+ `rm -Rf pkg`
20
+ end
21
+
22
+ desc "Package gem"
23
+ Rake::GemPackageTask.new(GEM_SPEC) do |pkg|
24
+ pkg.gem_spec = GEM_SPEC
25
+ end
26
+
27
+ desc "Run specs"
28
+ Spec::Rake::SpecTask.new do |t|
29
+ t.spec_opts = ["--format", "specdoc", "--colour"]
30
+ t.spec_files = FileList["spec/**/*_spec.rb"]
31
+ end
data/gemspec.rb ADDED
@@ -0,0 +1,17 @@
1
+ GEM_NAME = 'lilypad'
2
+ GEM_FILES = FileList['**/*'] - FileList['coverage', 'coverage/**/*', 'pkg', 'pkg/**/*']
3
+ GEM_SPEC = Gem::Specification.new do |s|
4
+ # == CONFIGURE ==
5
+ s.author = "Winton Welsh"
6
+ s.email = "mail@wintoni.us"
7
+ s.homepage = "http://github.com/winton/#{GEM_NAME}"
8
+ s.summary = "Hoptoad notifier for rack-based frameworks"
9
+ # == CONFIGURE ==
10
+ s.extra_rdoc_files = [ "README.markdown" ]
11
+ s.files = GEM_FILES.to_a
12
+ s.has_rdoc = false
13
+ s.name = GEM_NAME
14
+ s.platform = Gem::Platform::RUBY
15
+ s.require_path = "lib"
16
+ s.version = "0.1.0"
17
+ end
@@ -0,0 +1,126 @@
1
+ require 'builder'
2
+ require 'net/http'
3
+ require 'rack'
4
+ require 'yaml'
5
+
6
+ module Rack
7
+ class Lilypad
8
+
9
+ attr_accessor :filters
10
+
11
+ def initialize(app, api_key = nil)
12
+ @app = app
13
+ @filters = []
14
+ yield self if block_given?
15
+ @hoptoad = Hoptoad.new(api_key, @filters)
16
+ end
17
+
18
+ def call(env)
19
+ status, headers, body =
20
+ begin
21
+ @app.call(env)
22
+ rescue Exception => e
23
+ @hoptoad.post(e, env)
24
+ raise
25
+ end
26
+ @hoptoad.post(env['rack.exception'], env) if env['rack.exception']
27
+ [ status, headers, body ]
28
+ end
29
+
30
+ class Hoptoad
31
+
32
+ def initialize(api_key = nil, filters = [])
33
+ @api_key = api_key
34
+ @filters = filters
35
+ end
36
+
37
+ def backtrace(exception)
38
+ regex = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}
39
+ exception.backtrace.map do |line|
40
+ _, file, number, method = line.match(regex).to_a
41
+ Backtrace.new(file, number, method)
42
+ end
43
+ end
44
+
45
+ def filter(hash)
46
+ hash.inject({}) do |acc, (key, val)|
47
+ acc[key] = @filters.any? { |f| key.to_s =~ Regexp.new(f) } ? "[FILTERED]" : val
48
+ acc
49
+ end
50
+ end
51
+
52
+ def post(exception, env)
53
+ return unless production?
54
+ uri = URI.parse("http://hoptoadapp.com/notices/")
55
+ Net::HTTP.start(uri.host, uri.port) do |http|
56
+ headers = {
57
+ 'Content-type' => 'text/xml',
58
+ 'Accept' => 'text/xml, application/xml'
59
+ }
60
+ http.read_timeout = 5 # seconds
61
+ http.open_timeout = 2 # seconds
62
+ begin
63
+ http.post uri.path, xml(exception, env), headers
64
+ env['hoptoad.notified'] = true
65
+ rescue TimeoutError => e
66
+ end
67
+ end
68
+ end
69
+
70
+ def production?
71
+ %w(staging production).include?(ENV['RACK_ENV'])
72
+ end
73
+
74
+ def xml(exception, env)
75
+ environment = filter(ENV.to_hash.merge(env))
76
+ request = Rack::Request.new(env)
77
+ request_path = request.script_name + request.path_info
78
+
79
+ xml = ::Builder::XmlMarkup.new
80
+ xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
81
+ xml.notice do |n|
82
+ n.notifier do |n|
83
+ n.name 'Lilypad'
84
+ n.url 'http://github.com/winton/lilypad'
85
+ n.version '0.1.0'
86
+ end
87
+ n.error do |e|
88
+ e.tag! 'class', exception.class.name
89
+ e.message exception.message
90
+ e.backtrace do |b|
91
+ backtrace(exception).each do |line|
92
+ b.line(:method => line.method, :file => line.file, :number => line.number)
93
+ end
94
+ end
95
+ end
96
+ n.request do |r|
97
+ r.component request_path
98
+ r.url request_path
99
+ if request.params.any?
100
+ r.params do |p|
101
+ request.params.each do |key, value|
102
+ p.var(:key => key, :value => value)
103
+ end
104
+ end
105
+ end
106
+ if environment.any?
107
+ r.tag!('cgi-data') do |c|
108
+ environment.each do |key, value|
109
+ c.var(:key => key, :value => value)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ n.tag!('server-environment') do |s|
115
+ s.tag! 'project-root', Dir.pwd
116
+ s.tag! 'environment-name', ENV['RACK_ENV'] || 'development'
117
+ end
118
+ end
119
+ xml.target!
120
+ end
121
+
122
+ class Backtrace < Struct.new(:file, :number, :method)
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,8 @@
1
+ class SinatraApp < Sinatra::Base
2
+
3
+ use Rack::Lilypad, 'xxx'
4
+
5
+ get "/raise" do
6
+ raise 'Test'
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ describe Rack::Lilypad do
4
+
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ SinatraApp.new
9
+ end
10
+
11
+ # it "should do something" do
12
+ # get "/raise"
13
+ # end
14
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,22 @@
1
+ $testing = true
2
+ SPEC = File.dirname(__FILE__)
3
+ $:.unshift File.expand_path("#{SPEC}/../lib")
4
+
5
+ require 'rack/lilypad'
6
+ require 'pp'
7
+
8
+ require 'rubygems'
9
+ require 'rack/test'
10
+ require 'sinatra/base'
11
+
12
+ require File.expand_path("#{SPEC}/fixtures/sinatra")
13
+
14
+ Spec::Runner.configure do |config|
15
+ end
16
+
17
+ # For use with rspec textmate bundle
18
+ def debug(object)
19
+ puts "<pre>"
20
+ puts object.pretty_inspect.gsub('<', '&lt;').gsub('>', '&gt;')
21
+ puts "</pre>"
22
+ end
Binary file
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lilypad
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Winton Welsh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-01 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: mail@wintoni.us
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - gemspec.rb
26
+ - lib/rack/lilypad.rb
27
+ - MIT-LICENSE
28
+ - Rakefile
29
+ - README.markdown
30
+ - spec/fixtures/sinatra.rb
31
+ - spec/rack/lilypad_spec.rb
32
+ - spec/spec.opts
33
+ - spec/spec_helper.rb
34
+ - tmp/toadhopper.git.tgz
35
+ has_rdoc: true
36
+ homepage: http://github.com/winton/lilypad
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Hoptoad notifier for rack-based frameworks
63
+ test_files: []
64
+