Commit b44212384e33e91d358c60bb906cc259d8354ad7
Exists in
master
and in
1 other branch
Merge branch 'master' into fingerprint
Showing
24 changed files
with
184 additions
and
49 deletions
Show diff stats
Gemfile
| 1 | source 'http://rubygems.org' | 1 | source 'http://rubygems.org' |
| 2 | 2 | ||
| 3 | -gem 'rails', '3.2.6' | 3 | +gem 'rails', '3.2.8' |
| 4 | 4 | ||
| 5 | gem 'nokogiri' | 5 | gem 'nokogiri' |
| 6 | gem 'mongoid', '~> 2.4.10' | 6 | gem 'mongoid', '~> 2.4.10' |
| @@ -49,6 +49,7 @@ group :development, :test do | @@ -49,6 +49,7 @@ group :development, :test do | ||
| 49 | end | 49 | end |
| 50 | # gem 'rpm_contrib' | 50 | # gem 'rpm_contrib' |
| 51 | # gem 'newrelic_rpm' | 51 | # gem 'newrelic_rpm' |
| 52 | + gem 'capistrano' | ||
| 52 | end | 53 | end |
| 53 | 54 | ||
| 54 | group :test do | 55 | group :test do |
Gemfile.lock
| @@ -2,35 +2,35 @@ GEM | @@ -2,35 +2,35 @@ GEM | ||
| 2 | remote: http://rubygems.org/ | 2 | remote: http://rubygems.org/ |
| 3 | specs: | 3 | specs: |
| 4 | SystemTimer (1.2.3) | 4 | SystemTimer (1.2.3) |
| 5 | - actionmailer (3.2.6) | ||
| 6 | - actionpack (= 3.2.6) | 5 | + actionmailer (3.2.8) |
| 6 | + actionpack (= 3.2.8) | ||
| 7 | mail (~> 2.4.4) | 7 | mail (~> 2.4.4) |
| 8 | actionmailer_inline_css (1.3.1) | 8 | actionmailer_inline_css (1.3.1) |
| 9 | actionmailer (>= 3.0.0) | 9 | actionmailer (>= 3.0.0) |
| 10 | nokogiri (>= 1.4.4) | 10 | nokogiri (>= 1.4.4) |
| 11 | premailer (>= 1.7.1) | 11 | premailer (>= 1.7.1) |
| 12 | - actionpack (3.2.6) | ||
| 13 | - activemodel (= 3.2.6) | ||
| 14 | - activesupport (= 3.2.6) | 12 | + actionpack (3.2.8) |
| 13 | + activemodel (= 3.2.8) | ||
| 14 | + activesupport (= 3.2.8) | ||
| 15 | builder (~> 3.0.0) | 15 | builder (~> 3.0.0) |
| 16 | erubis (~> 2.7.0) | 16 | erubis (~> 2.7.0) |
| 17 | - journey (~> 1.0.1) | 17 | + journey (~> 1.0.4) |
| 18 | rack (~> 1.4.0) | 18 | rack (~> 1.4.0) |
| 19 | rack-cache (~> 1.2) | 19 | rack-cache (~> 1.2) |
| 20 | rack-test (~> 0.6.1) | 20 | rack-test (~> 0.6.1) |
| 21 | sprockets (~> 2.1.3) | 21 | sprockets (~> 2.1.3) |
| 22 | - activemodel (3.2.6) | ||
| 23 | - activesupport (= 3.2.6) | 22 | + activemodel (3.2.8) |
| 23 | + activesupport (= 3.2.8) | ||
| 24 | builder (~> 3.0.0) | 24 | builder (~> 3.0.0) |
| 25 | - activerecord (3.2.6) | ||
| 26 | - activemodel (= 3.2.6) | ||
| 27 | - activesupport (= 3.2.6) | 25 | + activerecord (3.2.8) |
| 26 | + activemodel (= 3.2.8) | ||
| 27 | + activesupport (= 3.2.8) | ||
| 28 | arel (~> 3.0.2) | 28 | arel (~> 3.0.2) |
| 29 | tzinfo (~> 0.3.29) | 29 | tzinfo (~> 0.3.29) |
| 30 | - activeresource (3.2.6) | ||
| 31 | - activemodel (= 3.2.6) | ||
| 32 | - activesupport (= 3.2.6) | ||
| 33 | - activesupport (3.2.6) | 30 | + activeresource (3.2.8) |
| 31 | + activemodel (= 3.2.8) | ||
| 32 | + activesupport (= 3.2.8) | ||
| 33 | + activesupport (3.2.8) | ||
| 34 | i18n (~> 0.6) | 34 | i18n (~> 0.6) |
| 35 | multi_json (~> 1.0) | 35 | multi_json (~> 1.0) |
| 36 | addressable (2.3.2) | 36 | addressable (2.3.2) |
| @@ -39,7 +39,13 @@ GEM | @@ -39,7 +39,13 @@ GEM | ||
| 39 | bson (1.6.2) | 39 | bson (1.6.2) |
| 40 | bson_ext (1.6.2) | 40 | bson_ext (1.6.2) |
| 41 | bson (~> 1.6.2) | 41 | bson (~> 1.6.2) |
| 42 | - builder (3.0.0) | 42 | + builder (3.0.3) |
| 43 | + capistrano (2.13.3) | ||
| 44 | + highline | ||
| 45 | + net-scp (>= 1.0.0) | ||
| 46 | + net-sftp (>= 2.0.0) | ||
| 47 | + net-ssh (>= 2.0.14) | ||
| 48 | + net-ssh-gateway (>= 1.1.0) | ||
| 43 | capybara (1.1.2) | 49 | capybara (1.1.2) |
| 44 | mime-types (>= 1.16) | 50 | mime-types (>= 1.16) |
| 45 | nokogiri (>= 1.3.3) | 51 | nokogiri (>= 1.3.3) |
| @@ -86,18 +92,19 @@ GEM | @@ -86,18 +92,19 @@ GEM | ||
| 86 | libxml-ruby (~> 2.0) | 92 | libxml-ruby (~> 2.0) |
| 87 | has_scope (0.5.1) | 93 | has_scope (0.5.1) |
| 88 | hashie (1.2.0) | 94 | hashie (1.2.0) |
| 95 | + highline (1.6.13) | ||
| 89 | hike (1.2.1) | 96 | hike (1.2.1) |
| 90 | hoptoad_notifier (2.4.11) | 97 | hoptoad_notifier (2.4.11) |
| 91 | activesupport | 98 | activesupport |
| 92 | builder | 99 | builder |
| 93 | htmlentities (4.3.1) | 100 | htmlentities (4.3.1) |
| 94 | httpauth (0.1) | 101 | httpauth (0.1) |
| 95 | - i18n (0.6.0) | 102 | + i18n (0.6.1) |
| 96 | inherited_resources (1.3.1) | 103 | inherited_resources (1.3.1) |
| 97 | has_scope (~> 0.5.0) | 104 | has_scope (~> 0.5.0) |
| 98 | responders (~> 0.6) | 105 | responders (~> 0.6) |
| 99 | journey (1.0.4) | 106 | journey (1.0.4) |
| 100 | - json (1.7.4) | 107 | + json (1.7.5) |
| 101 | jwt (0.1.5) | 108 | jwt (0.1.5) |
| 102 | multi_json (>= 1.0) | 109 | multi_json (>= 1.0) |
| 103 | kaminari (0.13.0) | 110 | kaminari (0.13.0) |
| @@ -134,6 +141,13 @@ GEM | @@ -134,6 +141,13 @@ GEM | ||
| 134 | railties (>= 3.0.0) | 141 | railties (>= 3.0.0) |
| 135 | multi_json (1.3.6) | 142 | multi_json (1.3.6) |
| 136 | multipart-post (1.1.5) | 143 | multipart-post (1.1.5) |
| 144 | + net-scp (1.0.4) | ||
| 145 | + net-ssh (>= 1.99.1) | ||
| 146 | + net-sftp (2.0.5) | ||
| 147 | + net-ssh (>= 2.0.9) | ||
| 148 | + net-ssh (2.5.2) | ||
| 149 | + net-ssh-gateway (1.1.0) | ||
| 150 | + net-ssh (>= 1.99.1) | ||
| 137 | nokogiri (1.5.5) | 151 | nokogiri (1.5.5) |
| 138 | oa-core (0.3.2) | 152 | oa-core (0.3.2) |
| 139 | oauth2 (0.8.0) | 153 | oauth2 (0.8.0) |
| @@ -181,19 +195,19 @@ GEM | @@ -181,19 +195,19 @@ GEM | ||
| 181 | rack-ssl-enforcer (0.2.4) | 195 | rack-ssl-enforcer (0.2.4) |
| 182 | rack-test (0.6.1) | 196 | rack-test (0.6.1) |
| 183 | rack (>= 1.0) | 197 | rack (>= 1.0) |
| 184 | - rails (3.2.6) | ||
| 185 | - actionmailer (= 3.2.6) | ||
| 186 | - actionpack (= 3.2.6) | ||
| 187 | - activerecord (= 3.2.6) | ||
| 188 | - activeresource (= 3.2.6) | ||
| 189 | - activesupport (= 3.2.6) | 198 | + rails (3.2.8) |
| 199 | + actionmailer (= 3.2.8) | ||
| 200 | + actionpack (= 3.2.8) | ||
| 201 | + activerecord (= 3.2.8) | ||
| 202 | + activeresource (= 3.2.8) | ||
| 203 | + activesupport (= 3.2.8) | ||
| 190 | bundler (~> 1.0) | 204 | bundler (~> 1.0) |
| 191 | - railties (= 3.2.6) | 205 | + railties (= 3.2.8) |
| 192 | rails_autolink (1.0.9) | 206 | rails_autolink (1.0.9) |
| 193 | rails (~> 3.1) | 207 | rails (~> 3.1) |
| 194 | - railties (3.2.6) | ||
| 195 | - actionpack (= 3.2.6) | ||
| 196 | - activesupport (= 3.2.6) | 208 | + railties (3.2.8) |
| 209 | + actionpack (= 3.2.8) | ||
| 210 | + activesupport (= 3.2.8) | ||
| 197 | rack-ssl (~> 1.3.2) | 211 | rack-ssl (~> 1.3.2) |
| 198 | rake (>= 0.8.7) | 212 | rake (>= 0.8.7) |
| 199 | rdoc (~> 3.4) | 213 | rdoc (~> 3.4) |
| @@ -244,7 +258,7 @@ GEM | @@ -244,7 +258,7 @@ GEM | ||
| 244 | daemons (>= 1.0.9) | 258 | daemons (>= 1.0.9) |
| 245 | eventmachine (>= 0.12.6) | 259 | eventmachine (>= 0.12.6) |
| 246 | rack (>= 1.0.0) | 260 | rack (>= 1.0.0) |
| 247 | - thor (0.15.4) | 261 | + thor (0.16.0) |
| 248 | tilt (1.3.3) | 262 | tilt (1.3.3) |
| 249 | treetop (1.4.10) | 263 | treetop (1.4.10) |
| 250 | polyglot | 264 | polyglot |
| @@ -275,6 +289,7 @@ DEPENDENCIES | @@ -275,6 +289,7 @@ DEPENDENCIES | ||
| 275 | actionmailer_inline_css (~> 1.3.0) | 289 | actionmailer_inline_css (~> 1.3.0) |
| 276 | bson (= 1.6.2) | 290 | bson (= 1.6.2) |
| 277 | bson_ext (= 1.6.2) | 291 | bson_ext (= 1.6.2) |
| 292 | + capistrano | ||
| 278 | capybara | 293 | capybara |
| 279 | database_cleaner (~> 0.6.0) | 294 | database_cleaner (~> 0.6.0) |
| 280 | debugger | 295 | debugger |
| @@ -299,7 +314,7 @@ DEPENDENCIES | @@ -299,7 +314,7 @@ DEPENDENCIES | ||
| 299 | oruen_redmine_client | 314 | oruen_redmine_client |
| 300 | pivotal-tracker | 315 | pivotal-tracker |
| 301 | rack-ssl-enforcer | 316 | rack-ssl-enforcer |
| 302 | - rails (= 3.2.6) | 317 | + rails (= 3.2.8) |
| 303 | rails_autolink (~> 1.0.9) | 318 | rails_autolink (~> 1.0.9) |
| 304 | ri_cal | 319 | ri_cal |
| 305 | rspec (~> 2.6) | 320 | rspec (~> 2.6) |
app/assets/stylesheets/errbit.css
| @@ -841,15 +841,30 @@ table.comment tbody th { | @@ -841,15 +841,30 @@ table.comment tbody th { | ||
| 841 | height: 20px; | 841 | height: 20px; |
| 842 | line-height: 0.5em; | 842 | line-height: 0.5em; |
| 843 | } | 843 | } |
| 844 | +table.comment th span, table.comment th img { | ||
| 845 | + vertical-align: middle; | ||
| 846 | +} | ||
| 847 | +table.comment th span.comment-info { | ||
| 848 | + line-height: 21px; | ||
| 849 | +} | ||
| 850 | +table.comment img.gravatar { | ||
| 851 | + margin-right: 7px; | ||
| 852 | +} | ||
| 853 | + | ||
| 844 | table.comment tbody td { | 854 | table.comment tbody td { |
| 845 | background-color: #F9F9F9; | 855 | background-color: #F9F9F9; |
| 846 | } | 856 | } |
| 847 | #content-comments a.destroy-comment { | 857 | #content-comments a.destroy-comment { |
| 848 | color: #EE0000; | 858 | color: #EE0000; |
| 849 | margin-right: 5px; | 859 | margin-right: 5px; |
| 860 | + margin-top: 2px; | ||
| 861 | + font-size: 21px; | ||
| 862 | + line-height: 1; | ||
| 863 | + float: right; | ||
| 850 | } | 864 | } |
| 851 | #content-comments a.destroy-comment:hover { | 865 | #content-comments a.destroy-comment:hover { |
| 852 | text-decoration: none; | 866 | text-decoration: none; |
| 867 | + color: #AA0000; | ||
| 853 | } | 868 | } |
| 854 | #content-comments #comment_submit { | 869 | #content-comments #comment_submit { |
| 855 | margin-top: 15px; | 870 | margin-top: 15px; |
| @@ -878,3 +893,12 @@ table.errs tr td.message .inline_comment em.commenter { | @@ -878,3 +893,12 @@ table.errs tr td.message .inline_comment em.commenter { | ||
| 878 | 893 | ||
| 879 | .current.asc:after { content: ' ↑'; } | 894 | .current.asc:after { content: ' ↑'; } |
| 880 | .current.desc:after { content: ' ↓'; } | 895 | .current.desc:after { content: ' ↓'; } |
| 896 | + | ||
| 897 | + | ||
| 898 | +table.users td { | ||
| 899 | + vertical-align: middle; | ||
| 900 | +} | ||
| 901 | +table.users td img.gravatar { | ||
| 902 | + vertical-align: middle; | ||
| 903 | + margin-left: 3px; | ||
| 904 | +} |
app/helpers/errs_helper.rb
| @@ -13,5 +13,19 @@ module ErrsHelper | @@ -13,5 +13,19 @@ module ErrsHelper | ||
| 13 | truncate(msg, :length => 300).scan(/.{1,5}/).map { |s| h(s) }.join("​").html_safe | 13 | truncate(msg, :length => 300).scan(/.{1,5}/).map { |s| h(s) }.join("​").html_safe |
| 14 | end | 14 | end |
| 15 | end | 15 | end |
| 16 | + | ||
| 17 | + def gravatar_tag(email, options = {}) | ||
| 18 | + image_tag gravatar_url(email, options), :alt => email, :class => 'gravatar' | ||
| 19 | + end | ||
| 20 | + | ||
| 21 | + def gravatar_url(email, options = {}) | ||
| 22 | + default_options = { | ||
| 23 | + :d => Errbit::Config.gravatar_default, | ||
| 24 | + } | ||
| 25 | + options.reverse_merge! default_options | ||
| 26 | + params = options.extract!(:s, :d).delete_if { |k, v| v.blank? } | ||
| 27 | + email_hash = Digest::MD5.hexdigest(email) | ||
| 28 | + "http://www.gravatar.com/avatar/#{email_hash}?#{params.to_query}" | ||
| 29 | + end | ||
| 16 | end | 30 | end |
| 17 | 31 |
app/models/error_report.rb
| @@ -2,7 +2,7 @@ require 'digest/sha1' | @@ -2,7 +2,7 @@ require 'digest/sha1' | ||
| 2 | require 'hoptoad_notifier' | 2 | require 'hoptoad_notifier' |
| 3 | 3 | ||
| 4 | class ErrorReport | 4 | class ErrorReport |
| 5 | - attr_reader :error_class, :message, :backtrace, :request, :server_environment, :api_key, :notifier, :user_attributes | 5 | + attr_reader :error_class, :message, :backtrace, :request, :server_environment, :api_key, :notifier, :user_attributes, :current_user |
| 6 | 6 | ||
| 7 | def initialize(xml_or_attributes) | 7 | def initialize(xml_or_attributes) |
| 8 | @attributes = (xml_or_attributes.is_a?(String) ? Hoptoad.parse_xml!(xml_or_attributes) : xml_or_attributes).with_indifferent_access | 8 | @attributes = (xml_or_attributes.is_a?(String) ? Hoptoad.parse_xml!(xml_or_attributes) : xml_or_attributes).with_indifferent_access |
| @@ -37,7 +37,9 @@ class ErrorReport | @@ -37,7 +37,9 @@ class ErrorReport | ||
| 37 | :request => request, | 37 | :request => request, |
| 38 | :server_environment => server_environment, | 38 | :server_environment => server_environment, |
| 39 | :notifier => notifier, | 39 | :notifier => notifier, |
| 40 | - :user_attributes => user_attributes) | 40 | + :user_attributes => user_attributes, |
| 41 | + :current_user => current_user | ||
| 42 | + ) | ||
| 41 | 43 | ||
| 42 | err = app.find_or_create_err!( | 44 | err = app.find_or_create_err!( |
| 43 | :error_class => error_class, | 45 | :error_class => error_class, |
app/models/notice.rb
| @@ -11,6 +11,7 @@ class Notice | @@ -11,6 +11,7 @@ class Notice | ||
| 11 | field :request, :type => Hash | 11 | field :request, :type => Hash |
| 12 | field :notifier, :type => Hash | 12 | field :notifier, :type => Hash |
| 13 | field :user_attributes, :type => Hash | 13 | field :user_attributes, :type => Hash |
| 14 | + field :current_user, :type => Hash | ||
| 14 | field :error_class | 15 | field :error_class |
| 15 | 16 | ||
| 16 | belongs_to :err | 17 | belongs_to :err |
app/views/errs/show.html.haml
| @@ -28,9 +28,12 @@ | @@ -28,9 +28,12 @@ | ||
| 28 | %table.comment | 28 | %table.comment |
| 29 | %tr | 29 | %tr |
| 30 | %th | 30 | %th |
| 31 | - %span= link_to '✘'.html_safe, app_err_comment_path(@app, @problem, comment), :method => :delete, :data => { :confirm => "Are sure you don't need this comment?" }, :class => "destroy-comment" | ||
| 32 | - = time_ago_in_words(comment.created_at, true) << " ago by " | ||
| 33 | - = link_to comment.user.email, user_path(comment.user) | 31 | + - if Errbit::Config.use_gravatar |
| 32 | + = gravatar_tag comment.user.email, :s => 24 | ||
| 33 | + %span.comment-info | ||
| 34 | + = time_ago_in_words(comment.created_at, true) << " ago by " | ||
| 35 | + = link_to comment.user.email, user_path(comment.user) | ||
| 36 | + %span.delete= link_to '✘'.html_safe, app_err_comment_path(@app, @problem, comment), :method => :delete, :data => { :confirm => "Are sure you don't need this comment?" }, :class => "destroy-comment" | ||
| 34 | %tr | 37 | %tr |
| 35 | %td= comment.body.gsub("\n", "<br>").html_safe | 38 | %td= comment.body.gsub("\n", "<br>").html_safe |
| 36 | - if Errbit::Config.allow_comments_with_issue_tracker || !@app.issue_tracker_configured? | 39 | - if Errbit::Config.allow_comments_with_issue_tracker || !@app.issue_tracker_configured? |
app/views/layouts/application.html.haml
| @@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
| 18 | = render 'shared/navigation' if current_user | 18 | = render 'shared/navigation' if current_user |
| 19 | = render 'shared/session' | 19 | = render 'shared/session' |
| 20 | #content-wrapper | 20 | #content-wrapper |
| 21 | - #content-title{ :class => (yield :title_css_class).to_s } | 21 | + #content-title{ :class => (yield :title_css_class).to_s, :style => (yield :title_style) } |
| 22 | %h1= yield :title | 22 | %h1= yield :title |
| 23 | %span.meta= yield :meta | 23 | %span.meta= yield :meta |
| 24 | - if (action_bar = yield(:action_bar)).present? | 24 | - if (action_bar = yield(:action_bar)).present? |
| @@ -33,3 +33,4 @@ | @@ -33,3 +33,4 @@ | ||
| 33 | #footer= "Powered by #{link_to 'Errbit', 'http://github.com/errbit/errbit', :target => '_blank'}: the open source error catcher.".html_safe | 33 | #footer= "Powered by #{link_to 'Errbit', 'http://github.com/errbit/errbit', :target => '_blank'}: the open source error catcher.".html_safe |
| 34 | = yield :scripts | 34 | = yield :scripts |
| 35 | 35 | ||
| 36 | += yield :before_title | ||
| 36 | \ No newline at end of file | 37 | \ No newline at end of file |
app/views/users/index.html.haml
| @@ -2,9 +2,11 @@ | @@ -2,9 +2,11 @@ | ||
| 2 | - content_for :action_bar do | 2 | - content_for :action_bar do |
| 3 | %span= link_to('Add a New User', new_user_path, :class => 'add') | 3 | %span= link_to('Add a New User', new_user_path, :class => 'add') |
| 4 | 4 | ||
| 5 | -%table | 5 | +%table.users |
| 6 | %thead | 6 | %thead |
| 7 | %tr | 7 | %tr |
| 8 | + - if Errbit::Config.use_gravatar | ||
| 9 | + %th | ||
| 8 | %th Name | 10 | %th Name |
| 9 | - if Errbit::Config.user_has_username | 11 | - if Errbit::Config.user_has_username |
| 10 | %th Username | 12 | %th Username |
| @@ -13,6 +15,8 @@ | @@ -13,6 +15,8 @@ | ||
| 13 | %tbody | 15 | %tbody |
| 14 | - @users.each do |user| | 16 | - @users.each do |user| |
| 15 | %tr | 17 | %tr |
| 18 | + - if Errbit::Config.use_gravatar | ||
| 19 | + %td= gravatar_tag user.email, :s => 24 | ||
| 16 | %td.nowrap= link_to user.name, user_path(user) | 20 | %td.nowrap= link_to user.name, user_path(user) |
| 17 | - if Errbit::Config.user_has_username | 21 | - if Errbit::Config.user_has_username |
| 18 | %td= user.username | 22 | %td= user.username |
app/views/users/show.html.haml
| 1 | - content_for :title, @user.name | 1 | - content_for :title, @user.name |
| 2 | +- if Errbit::Config.use_gravatar | ||
| 3 | + - content_for :title_style do | ||
| 4 | + background: url('#{gravatar_url @user.email, :s => 86}') no-repeat; | ||
| 5 | + padding-left: 106px; | ||
| 6 | + | ||
| 2 | - content_for :action_bar do | 7 | - content_for :action_bar do |
| 3 | = render 'shared/link_github_account', :user => @user | 8 | = render 'shared/link_github_account', :user => @user |
| 4 | %span= link_to('Add a New User', new_user_path, :class => 'add') | 9 | %span= link_to('Add a New User', new_user_path, :class => 'add') |
| 5 | = link_to 'edit', edit_user_path(@user), :class => 'button' | 10 | = link_to 'edit', edit_user_path(@user), :class => 'button' |
| 6 | = link_to 'destroy', user_path(@user), :method => :delete, :data => { :confirm => 'Seriously?' }, :class => 'button' | 11 | = link_to 'destroy', user_path(@user), :method => :delete, :data => { :confirm => 'Seriously?' }, :class => 'button' |
| 7 | 12 | ||
| 8 | - | ||
| 9 | %table.single_user | 13 | %table.single_user |
| 10 | %tr | 14 | %tr |
| 11 | %th Email | 15 | %th Email |
config/config.example.yml
| @@ -39,6 +39,11 @@ user_has_username: false | @@ -39,6 +39,11 @@ user_has_username: false | ||
| 39 | # but you want to leave a short comment. | 39 | # but you want to leave a short comment. |
| 40 | allow_comments_with_issue_tracker: true | 40 | allow_comments_with_issue_tracker: true |
| 41 | 41 | ||
| 42 | +# Enable Gravatar. | ||
| 43 | +use_gravatar: true | ||
| 44 | +# Default Gravatar image, can be: mm, identicon, monsterid, wavatar, retro. | ||
| 45 | +gravatar_default: identicon | ||
| 46 | + | ||
| 42 | # Setup your deploy options for capistrano. | 47 | # Setup your deploy options for capistrano. |
| 43 | deployment: | 48 | deployment: |
| 44 | hosts: | 49 | hosts: |
config/initializers/_load_config.rb
| @@ -13,6 +13,10 @@ unless defined?(Errbit::Config) | @@ -13,6 +13,10 @@ unless defined?(Errbit::Config) | ||
| 13 | Errbit::Config.confirm_resolve_err = ENV['ERRBIT_CONFIRM_RESOLVE_ERR'] | 13 | Errbit::Config.confirm_resolve_err = ENV['ERRBIT_CONFIRM_RESOLVE_ERR'] |
| 14 | Errbit::Config.user_has_username = ENV['ERRBIT_USER_HAS_USERNAME'] | 14 | Errbit::Config.user_has_username = ENV['ERRBIT_USER_HAS_USERNAME'] |
| 15 | Errbit::Config.allow_comments_with_issue_tracker = ENV['ERRBIT_ALLOW_COMMENTS_WITH_ISSUE_TRACKER'] | 15 | Errbit::Config.allow_comments_with_issue_tracker = ENV['ERRBIT_ALLOW_COMMENTS_WITH_ISSUE_TRACKER'] |
| 16 | + Errbit::Config.enforce_ssl = ENV['ERRBIT_ENFORCE_SSL'] | ||
| 17 | + | ||
| 18 | + Errbit::Config.use_gravatar = ENV['ERRBIT_USE_GRAVATAR'] | ||
| 19 | + Errbit::Config.gravatar_default = ENV['ERRBIT_GRAVATAR_DEFAULT'] | ||
| 16 | 20 | ||
| 17 | Errbit::Config.github_authentication = ENV['GITHUB_AUTHENTICATION'] | 21 | Errbit::Config.github_authentication = ENV['GITHUB_AUTHENTICATION'] |
| 18 | Errbit::Config.github_client_id = ENV['GITHUB_CLIENT_ID'] | 22 | Errbit::Config.github_client_id = ENV['GITHUB_CLIENT_ID'] |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +OmniAuth.config.logger = Rails.logger |
db/migrate/20110422152027_move_notices_to_separate_collection.rb
| @@ -5,6 +5,10 @@ class MoveNoticesToSeparateCollection < Mongoid::Migration | @@ -5,6 +5,10 @@ class MoveNoticesToSeparateCollection < Mongoid::Migration | ||
| 5 | errs = mongo_db.collection("errs").find({ }, :fields => ["notices"]) | 5 | errs = mongo_db.collection("errs").find({ }, :fields => ["notices"]) |
| 6 | errs.each do |err| | 6 | errs.each do |err| |
| 7 | next unless err['notices'] | 7 | next unless err['notices'] |
| 8 | + | ||
| 9 | + # This Err was created after the Problem->Err->Notice redesign | ||
| 10 | + next if err['app_id'].nil? or err['problem_id'] | ||
| 11 | + | ||
| 8 | e = Err.find(err['_id']) | 12 | e = Err.find(err['_id']) |
| 9 | # disable email notifications | 13 | # disable email notifications |
| 10 | old_notify = e.app.notify_on_errs? | 14 | old_notify = e.app.notify_on_errs? |
db/migrate/20120530005915_rename_klass_to_error_class.rb
| 1 | class RenameKlassToErrorClass < Mongoid::Migration | 1 | class RenameKlassToErrorClass < Mongoid::Migration |
| 2 | def self.up | 2 | def self.up |
| 3 | [Problem, Err, Notice].each do |model| | 3 | [Problem, Err, Notice].each do |model| |
| 4 | - model.collection.update({}, {'$rename' => {'klass' => 'error_class'}}, multi: true, safe: true) | 4 | + model.collection.update({}, {'$rename' => {'klass' => 'error_class'}}, :multi => true, :safe => true) |
| 5 | end | 5 | end |
| 6 | end | 6 | end |
| 7 | 7 | ||
| 8 | def self.down | 8 | def self.down |
| 9 | [Problem, Err, Notice].each do |model| | 9 | [Problem, Err, Notice].each do |model| |
| 10 | - model.collection.update({}, {'$rename' => {'error_class' => 'klass'}}, multi: true, safe: true) | 10 | + model.collection.update({}, {'$rename' => {'error_class' => 'klass'}}, :multi => true, :safe => true) |
| 11 | end | 11 | end |
| 12 | end | 12 | end |
| 13 | end | 13 | end |
db/migrate/20120603112130_change_github_url_to_github_repo.rb
| 1 | class ChangeGithubUrlToGithubRepo < Mongoid::Migration | 1 | class ChangeGithubUrlToGithubRepo < Mongoid::Migration |
| 2 | def self.up | 2 | def self.up |
| 3 | - App.collection.update({}, {'$rename' => {'github_url' => 'github_repo'}}, multi: true, safe: true) | 3 | + App.collection.update({}, {'$rename' => {'github_url' => 'github_repo'}}, :multi => true, :safe => true) |
| 4 | App.all.each do |app| | 4 | App.all.each do |app| |
| 5 | app.send :normalize_github_repo | 5 | app.send :normalize_github_repo |
| 6 | app.save | 6 | app.save |
| @@ -8,7 +8,7 @@ class ChangeGithubUrlToGithubRepo < Mongoid::Migration | @@ -8,7 +8,7 @@ class ChangeGithubUrlToGithubRepo < Mongoid::Migration | ||
| 8 | end | 8 | end |
| 9 | 9 | ||
| 10 | def self.down | 10 | def self.down |
| 11 | - App.collection.update({}, {'$rename' => {'github_repo' => 'github_url'}}, multi: true, safe: true) | 11 | + App.collection.update({}, {'$rename' => {'github_repo' => 'github_url'}}, :multi => true, :safe => true) |
| 12 | App.all.each do |app| | 12 | App.all.each do |app| |
| 13 | unless app.github_repo.include?("github.com") | 13 | unless app.github_repo.include?("github.com") |
| 14 | app.update_attribute :github_url, "https://github.com/" << app.github_url | 14 | app.update_attribute :github_url, "https://github.com/" << app.github_url |
lib/hoptoad.rb
| @@ -3,7 +3,7 @@ require 'hoptoad/v2' | @@ -3,7 +3,7 @@ require 'hoptoad/v2' | ||
| 3 | module Hoptoad | 3 | module Hoptoad |
| 4 | class ApiVersionError < StandardError | 4 | class ApiVersionError < StandardError |
| 5 | def initialize | 5 | def initialize |
| 6 | - super "Wrong API Version: Expecting 2.0, 2.1, or 2.2" | 6 | + super "Wrong API Version: Expecting 2.0, 2.1, 2.2 or 2.3" |
| 7 | end | 7 | end |
| 8 | end | 8 | end |
| 9 | 9 | ||
| @@ -16,7 +16,7 @@ module Hoptoad | @@ -16,7 +16,7 @@ module Hoptoad | ||
| 16 | private | 16 | private |
| 17 | def self.get_version_processor(version) | 17 | def self.get_version_processor(version) |
| 18 | case version | 18 | case version |
| 19 | - when /2\.[012]/; Hoptoad::V2 | 19 | + when /2\.[0123]/; Hoptoad::V2 |
| 20 | else; raise ApiVersionError | 20 | else; raise ApiVersionError |
| 21 | end | 21 | end |
| 22 | end | 22 | end |
lib/hoptoad/v2.rb
| @@ -59,7 +59,8 @@ module Hoptoad | @@ -59,7 +59,8 @@ module Hoptoad | ||
| 59 | 59 | ||
| 60 | :api_key => notice['api-key'], | 60 | :api_key => notice['api-key'], |
| 61 | :notifier => notice['notifier'], | 61 | :notifier => notice['notifier'], |
| 62 | - :user_attributes => notice['user-attributes'] || {} | 62 | + :user_attributes => notice['user-attributes'] || {}, |
| 63 | + :current_user => notice['current-user'] || {} | ||
| 63 | } | 64 | } |
| 64 | end | 65 | end |
| 65 | end | 66 | end |
spec/controllers/notices_controller_spec.rb
| @@ -13,7 +13,7 @@ describe NoticesController do | @@ -13,7 +13,7 @@ describe NoticesController do | ||
| 13 | @notice = App.report_error!(@xml) | 13 | @notice = App.report_error!(@xml) |
| 14 | end | 14 | end |
| 15 | 15 | ||
| 16 | - it "generates a notice from xml [POST]" do | 16 | + it "generates a notice from raw xml [POST]" do |
| 17 | App.should_receive(:report_error!).with(@xml).and_return(@notice) | 17 | App.should_receive(:report_error!).with(@xml).and_return(@notice) |
| 18 | request.should_receive(:raw_post).and_return(@xml) | 18 | request.should_receive(:raw_post).and_return(@xml) |
| 19 | post :create, :format => :xml | 19 | post :create, :format => :xml |
| @@ -24,6 +24,16 @@ describe NoticesController do | @@ -24,6 +24,16 @@ describe NoticesController do | ||
| 24 | response.body.should match(%r{<url[^>]*>(.+)#{locate_path(@notice.id)}</url>}) | 24 | response.body.should match(%r{<url[^>]*>(.+)#{locate_path(@notice.id)}</url>}) |
| 25 | end | 25 | end |
| 26 | 26 | ||
| 27 | + it "generates a notice from xml in a data param [POST]" do | ||
| 28 | + App.should_receive(:report_error!).with(@xml).and_return(@notice) | ||
| 29 | + post :create, :data => @xml, :format => :xml | ||
| 30 | + response.should be_success | ||
| 31 | + # Same RegExp from Airbrake::Sender#send_to_airbrake (https://github.com/airbrake/airbrake/blob/master/lib/airbrake/sender.rb#L53) | ||
| 32 | + # Inspired by https://github.com/airbrake/airbrake/blob/master/test/sender_test.rb | ||
| 33 | + response.body.should match(%r{<id[^>]*>#{@notice.id}</id>}) | ||
| 34 | + response.body.should match(%r{<url[^>]*>(.+)#{locate_path(@notice.id)}</url>}) | ||
| 35 | + end | ||
| 36 | + | ||
| 27 | it "generates a notice from xml [GET]" do | 37 | it "generates a notice from xml [GET]" do |
| 28 | App.should_receive(:report_error!).with(@xml).and_return(@notice) | 38 | App.should_receive(:report_error!).with(@xml).and_return(@notice) |
| 29 | get :create, :data => @xml, :format => :xml | 39 | get :create, :data => @xml, :format => :xml |
spec/fixtures/hoptoad_test_notice.xml
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | -<notice version="2.0"> | 2 | +<notice version="2.3"> |
| 3 | <api-key>APIKEY</api-key> | 3 | <api-key>APIKEY</api-key> |
| 4 | <notifier> | 4 | <notifier> |
| 5 | <name>Hoptoad Notifier</name> | 5 | <name>Hoptoad Notifier</name> |
| @@ -144,4 +144,10 @@ | @@ -144,4 +144,10 @@ | ||
| 144 | <project-root>/path/to/sample/project</project-root> | 144 | <project-root>/path/to/sample/project</project-root> |
| 145 | <environment-name>development</environment-name> | 145 | <environment-name>development</environment-name> |
| 146 | </server-environment> | 146 | </server-environment> |
| 147 | + <current-user> | ||
| 148 | + <id>123</id> | ||
| 149 | + <name>Mr. Bean</name> | ||
| 150 | + <email>mr.bean@example.com</email> | ||
| 151 | + <username>mrbean</username> | ||
| 152 | + </current-user> | ||
| 147 | </notice> | 153 | </notice> |
spec/helpers/errs_helper_spec.rb
| @@ -9,4 +9,27 @@ describe ErrsHelper do | @@ -9,4 +9,27 @@ describe ErrsHelper do | ||
| 9 | truncated.should_not include('<', '>') | 9 | truncated.should_not include('<', '>') |
| 10 | end | 10 | end |
| 11 | end | 11 | end |
| 12 | + | ||
| 13 | + describe "#gravatar_tag" do | ||
| 14 | + let(:email) { "gravatar@example.com" } | ||
| 15 | + let(:email_hash) { Digest::MD5.hexdigest email } | ||
| 16 | + let(:base_url) { "http://www.gravatar.com/avatar/#{email_hash}" } | ||
| 17 | + | ||
| 18 | + context "default config" do | ||
| 19 | + before do | ||
| 20 | + Errbit::Config.stub(:use_gravatar).and_return(true) | ||
| 21 | + Errbit::Config.stub(:gravatar_default).and_return('identicon') | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | + it "should render image_tag with correct alt and src" do | ||
| 25 | + expected = "<img alt=\"#{email}\" class=\"gravatar\" src=\"#{base_url}?d=identicon&s=48\" />" | ||
| 26 | + helper.gravatar_tag(email, :s => 48).should eq(expected) | ||
| 27 | + end | ||
| 28 | + | ||
| 29 | + it "should override :d" do | ||
| 30 | + expected = "<img alt=\"#{email}\" class=\"gravatar\" src=\"#{base_url}?d=retro&s=48\" />" | ||
| 31 | + helper.gravatar_tag(email, :d => 'retro', :s => 48).should eq(expected) | ||
| 32 | + end | ||
| 33 | + end | ||
| 34 | + end | ||
| 12 | end | 35 | end |
spec/models/app_spec.rb
| @@ -230,6 +230,15 @@ describe App do | @@ -230,6 +230,15 @@ describe App do | ||
| 230 | lambda { @notice = App.report_error!(xml) }.should_not raise_error | 230 | lambda { @notice = App.report_error!(xml) }.should_not raise_error |
| 231 | @notice.backtrace.length.should == 1 | 231 | @notice.backtrace.length.should == 1 |
| 232 | end | 232 | end |
| 233 | + | ||
| 234 | + it 'captures the current_user' do | ||
| 235 | + @notice = App.report_error!(@xml) | ||
| 236 | + @notice.current_user['id'].should == '123' | ||
| 237 | + @notice.current_user['name'].should == 'Mr. Bean' | ||
| 238 | + @notice.current_user['email'].should == 'mr.bean@example.com' | ||
| 239 | + @notice.current_user['username'].should == 'mrbean' | ||
| 240 | + end | ||
| 241 | + | ||
| 233 | end | 242 | end |
| 234 | 243 | ||
| 235 | 244 |
spec/views/errs/show.html.haml_spec.rb
| @@ -90,6 +90,7 @@ describe "errs/show.html.haml" do | @@ -90,6 +90,7 @@ describe "errs/show.html.haml" do | ||
| 90 | describe "content_for :comments with comments disabled for configured issue tracker" do | 90 | describe "content_for :comments with comments disabled for configured issue tracker" do |
| 91 | before do | 91 | before do |
| 92 | Errbit::Config.stub(:allow_comments_with_issue_tracker).and_return(false) | 92 | Errbit::Config.stub(:allow_comments_with_issue_tracker).and_return(false) |
| 93 | + Errbit::Config.stub(:use_gravatar).and_return(true) | ||
| 93 | end | 94 | end |
| 94 | 95 | ||
| 95 | it 'should display comments and new comment form when no issue tracker' do | 96 | it 'should display comments and new comment form when no issue tracker' do |
| @@ -99,6 +100,7 @@ describe "errs/show.html.haml" do | @@ -99,6 +100,7 @@ describe "errs/show.html.haml" do | ||
| 99 | render | 100 | render |
| 100 | 101 | ||
| 101 | view.content_for(:comments).should include('Test comment') | 102 | view.content_for(:comments).should include('Test comment') |
| 103 | + view.content_for(:comments).should have_selector('img[src^="http://www.gravatar.com/avatar"]') | ||
| 102 | view.content_for(:comments).should include('Add a comment') | 104 | view.content_for(:comments).should include('Add a comment') |
| 103 | end | 105 | end |
| 104 | 106 | ||
| @@ -117,6 +119,7 @@ describe "errs/show.html.haml" do | @@ -117,6 +119,7 @@ describe "errs/show.html.haml" do | ||
| 117 | render | 119 | render |
| 118 | 120 | ||
| 119 | view.content_for(:comments).should include('Test comment') | 121 | view.content_for(:comments).should include('Test comment') |
| 122 | + view.content_for(:comments).should have_selector('img[src^="http://www.gravatar.com/avatar"]') | ||
| 120 | view.content_for(:comments).should_not include('Add a comment') | 123 | view.content_for(:comments).should_not include('Add a comment') |
| 121 | end | 124 | end |
| 122 | end | 125 | end |
spec/views/users/show.html.haml_spec.rb
| @@ -2,7 +2,7 @@ require 'spec_helper' | @@ -2,7 +2,7 @@ require 'spec_helper' | ||
| 2 | 2 | ||
| 3 | describe 'users/show.html.haml' do | 3 | describe 'users/show.html.haml' do |
| 4 | let(:user) do | 4 | let(:user) do |
| 5 | - stub_model(User, :created_at => Time.now) | 5 | + stub_model(User, :created_at => Time.now, :email => "test@example.com") |
| 6 | end | 6 | end |
| 7 | 7 | ||
| 8 | before do | 8 | before do |