Commit b9928817ff99dfe001059b2a55e05a604059e4d4
Exists in
master
and in
1 other branch
Merge branch 'master' of https://github.com/errbit/errbit into adding_support_for_bitbucket_issues
Conflicts: Gemfile
Showing
22 changed files
with
414 additions
and
299 deletions
Show diff stats
Gemfile
| 1 | source 'http://rubygems.org' | 1 | source 'http://rubygems.org' |
| 2 | 2 | ||
| 3 | gem 'rails', '3.2.8' | 3 | gem 'rails', '3.2.8' |
| 4 | - | ||
| 5 | -gem 'nokogiri' | ||
| 6 | gem 'mongoid', '~> 2.4.10' | 4 | gem 'mongoid', '~> 2.4.10' |
| 7 | - | ||
| 8 | -# force SSL | ||
| 9 | -gem 'rack-ssl', :require => 'rack/ssl' | ||
| 10 | - | 5 | +gem 'mongoid_rails_migrations' |
| 6 | +gem 'devise', '~> 1.5.3' | ||
| 7 | +gem 'nokogiri' | ||
| 11 | gem 'haml' | 8 | gem 'haml' |
| 12 | gem 'htmlentities', "~> 4.3.0" | 9 | gem 'htmlentities', "~> 4.3.0" |
| 10 | +gem 'rack-ssl', :require => 'rack/ssl' # force SSL | ||
| 13 | 11 | ||
| 14 | -gem 'devise', '~> 1.5.3' | 12 | +gem 'useragent', '~> 0.3.1' |
| 13 | +gem 'inherited_resources' | ||
| 14 | +gem 'SystemTimer', :platform => :ruby_18 | ||
| 15 | +gem 'actionmailer_inline_css', "~> 1.3.0" | ||
| 16 | +gem 'kaminari' | ||
| 17 | +gem 'rack-ssl-enforcer' | ||
| 18 | +gem 'fabrication', "~> 1.3.0" # Used for both tests and demo data | ||
| 19 | +gem 'rails_autolink', '~> 1.0.9' | ||
| 20 | +# Please don't update hoptoad_notifier to airbrake. | ||
| 21 | +# It's for internal use only, and we monkeypatch certain methods | ||
| 22 | +gem 'hoptoad_notifier', "~> 2.4" | ||
| 15 | 23 | ||
| 16 | -gem 'omniauth-github' | ||
| 17 | -gem 'oa-core' | ||
| 18 | 24 | ||
| 25 | +# Remove / comment out any of the gems below if you want to disable | ||
| 26 | +# a given issue tracker, notification service, or authentication. | ||
| 27 | + | ||
| 28 | +# Issue Trackers | ||
| 29 | +# --------------------------------------- | ||
| 30 | +# Lighthouse | ||
| 19 | gem 'lighthouse-api' | 31 | gem 'lighthouse-api' |
| 32 | +# Redmine | ||
| 20 | gem 'oruen_redmine_client', :require => 'redmine_client' | 33 | gem 'oruen_redmine_client', :require => 'redmine_client' |
| 21 | -gem 'mongoid_rails_migrations' | ||
| 22 | -gem 'useragent', '~> 0.3.1' | 34 | +# Pivotal Tracker |
| 23 | gem 'pivotal-tracker' | 35 | gem 'pivotal-tracker' |
| 36 | +# Fogbugz | ||
| 24 | gem 'ruby-fogbugz', :require => 'fogbugz' | 37 | gem 'ruby-fogbugz', :require => 'fogbugz' |
| 25 | - | 38 | +# Github Issues |
| 26 | gem 'octokit', '~> 1.0.0' | 39 | gem 'octokit', '~> 1.0.0' |
| 27 | 40 | ||
| 28 | -gem 'inherited_resources' | ||
| 29 | -gem 'SystemTimer', :platform => :ruby_18 | ||
| 30 | -gem 'actionmailer_inline_css', "~> 1.3.0" | ||
| 31 | -gem 'kaminari' | ||
| 32 | -gem 'rack-ssl-enforcer' | ||
| 33 | -gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data | ||
| 34 | -gem 'rails_autolink', '~> 1.0.9' | ||
| 35 | -gem 'campy' | ||
| 36 | -gem 'xmpp4r' | 41 | +# Bitbucket Issues |
| 37 | gem 'bitbucket_rest_api' | 42 | gem 'bitbucket_rest_api' |
| 43 | + | ||
| 44 | +# Notification services | ||
| 45 | +# --------------------------------------- | ||
| 46 | +# Campfire | ||
| 47 | +gem 'campy' | ||
| 48 | +# Hipchat | ||
| 38 | gem 'hipchat' | 49 | gem 'hipchat' |
| 50 | +# Hoiio (SMS) | ||
| 51 | +gem 'hoi' | ||
| 52 | + | ||
| 53 | +# Authentication | ||
| 54 | +# --------------------------------------- | ||
| 55 | +# GitHub OAuth | ||
| 56 | +gem 'omniauth-github' | ||
| 39 | 57 | ||
| 40 | -# Please don't update this to airbrake - We override the send_notice method | ||
| 41 | -# to handle internal errors. | ||
| 42 | -gem 'hoptoad_notifier', '~> 2.4' | ||
| 43 | 58 | ||
| 44 | platform :ruby do | 59 | platform :ruby do |
| 45 | gem 'mongo', '= 1.6.2' | 60 | gem 'mongo', '= 1.6.2' |
| @@ -47,6 +62,8 @@ platform :ruby do | @@ -47,6 +62,8 @@ platform :ruby do | ||
| 47 | gem 'bson_ext', '= 1.6.2' | 62 | gem 'bson_ext', '= 1.6.2' |
| 48 | end | 63 | end |
| 49 | 64 | ||
| 65 | +gem 'omniauth' | ||
| 66 | +gem 'oa-core' | ||
| 50 | gem 'ri_cal' | 67 | gem 'ri_cal' |
| 51 | gem 'yajl-ruby', :require => "yajl" | 68 | gem 'yajl-ruby', :require => "yajl" |
| 52 | 69 | ||
| @@ -57,10 +74,12 @@ group :development, :test do | @@ -57,10 +74,12 @@ group :development, :test do | ||
| 57 | gem 'ruby-debug', :platform => :mri_18 | 74 | gem 'ruby-debug', :platform => :mri_18 |
| 58 | gem 'debugger', :platform => :mri_19 | 75 | gem 'debugger', :platform => :mri_19 |
| 59 | gem 'pry' | 76 | gem 'pry' |
| 77 | + gem 'pry-rails' | ||
| 60 | end | 78 | end |
| 61 | # gem 'rpm_contrib' | 79 | # gem 'rpm_contrib' |
| 62 | # gem 'newrelic_rpm' | 80 | # gem 'newrelic_rpm' |
| 63 | gem 'capistrano' | 81 | gem 'capistrano' |
| 82 | + gem 'capistrano_colors' | ||
| 64 | end | 83 | end |
| 65 | 84 | ||
| 66 | group :test do | 85 | group :test do |
| @@ -86,3 +105,5 @@ group :assets do | @@ -86,3 +105,5 @@ group :assets do | ||
| 86 | gem 'therubyracer', :platform => :ruby # C Ruby (MRI) or Rubinius, but NOT Windows | 105 | gem 'therubyracer', :platform => :ruby # C Ruby (MRI) or Rubinius, but NOT Windows |
| 87 | gem 'uglifier', '>= 1.0.3' | 106 | gem 'uglifier', '>= 1.0.3' |
| 88 | end | 107 | end |
| 108 | + | ||
| 109 | +gem 'turbo-sprockets-rails3' |
Gemfile.lock
| @@ -55,6 +55,7 @@ GEM | @@ -55,6 +55,7 @@ GEM | ||
| 55 | net-sftp (>= 2.0.0) | 55 | net-sftp (>= 2.0.0) |
| 56 | net-ssh (>= 2.0.14) | 56 | net-ssh (>= 2.0.14) |
| 57 | net-ssh-gateway (>= 1.1.0) | 57 | net-ssh-gateway (>= 1.1.0) |
| 58 | + capistrano_colors (0.5.5) | ||
| 58 | capybara (1.1.2) | 59 | capybara (1.1.2) |
| 59 | mime-types (>= 1.16) | 60 | mime-types (>= 1.16) |
| 60 | nokogiri (>= 1.3.3) | 61 | nokogiri (>= 1.3.3) |
| @@ -92,7 +93,7 @@ GEM | @@ -92,7 +93,7 @@ GEM | ||
| 92 | execjs (1.4.0) | 93 | execjs (1.4.0) |
| 93 | multi_json (~> 1.0) | 94 | multi_json (~> 1.0) |
| 94 | fabrication (1.3.2) | 95 | fabrication (1.3.2) |
| 95 | - faraday (0.8.1) | 96 | + faraday (0.8.4) |
| 96 | multipart-post (~> 1.1) | 97 | multipart-post (~> 1.1) |
| 97 | faraday_middleware (0.8.8) | 98 | faraday_middleware (0.8.8) |
| 98 | faraday (>= 0.7.4, < 0.9) | 99 | faraday (>= 0.7.4, < 0.9) |
| @@ -106,6 +107,9 @@ GEM | @@ -106,6 +107,9 @@ GEM | ||
| 106 | hike (1.2.1) | 107 | hike (1.2.1) |
| 107 | hipchat (0.4.1) | 108 | hipchat (0.4.1) |
| 108 | httparty | 109 | httparty |
| 110 | + hoi (0.0.6) | ||
| 111 | + httparty (> 0.6.0) | ||
| 112 | + json (> 1.4.0) | ||
| 109 | hoptoad_notifier (2.4.11) | 113 | hoptoad_notifier (2.4.11) |
| 110 | activesupport | 114 | activesupport |
| 111 | builder | 115 | builder |
| @@ -179,13 +183,13 @@ GEM | @@ -179,13 +183,13 @@ GEM | ||
| 179 | faraday_middleware (~> 0.8) | 183 | faraday_middleware (~> 0.8) |
| 180 | hashie (~> 1.2) | 184 | hashie (~> 1.2) |
| 181 | multi_json (~> 1.3) | 185 | multi_json (~> 1.3) |
| 182 | - omniauth (1.1.0) | 186 | + omniauth (1.1.1) |
| 183 | hashie (~> 1.2) | 187 | hashie (~> 1.2) |
| 184 | rack | 188 | rack |
| 185 | omniauth-github (1.0.2) | 189 | omniauth-github (1.0.2) |
| 186 | omniauth (~> 1.0) | 190 | omniauth (~> 1.0) |
| 187 | omniauth-oauth2 (~> 1.1) | 191 | omniauth-oauth2 (~> 1.1) |
| 188 | - omniauth-oauth2 (1.1.0) | 192 | + omniauth-oauth2 (1.1.1) |
| 189 | oauth2 (~> 0.8.0) | 193 | oauth2 (~> 0.8.0) |
| 190 | omniauth (~> 1.0) | 194 | omniauth (~> 1.0) |
| 191 | orm_adapter (0.0.7) | 195 | orm_adapter (0.0.7) |
| @@ -208,6 +212,8 @@ GEM | @@ -208,6 +212,8 @@ GEM | ||
| 208 | coderay (~> 1.0.5) | 212 | coderay (~> 1.0.5) |
| 209 | method_source (~> 0.7.1) | 213 | method_source (~> 0.7.1) |
| 210 | slop (>= 2.4.4, < 3) | 214 | slop (>= 2.4.4, < 3) |
| 215 | + pry-rails (0.2.0) | ||
| 216 | + pry | ||
| 211 | rack (1.4.1) | 217 | rack (1.4.1) |
| 212 | rack-cache (1.2) | 218 | rack-cache (1.2) |
| 213 | rack (>= 0.4) | 219 | rack (>= 0.4) |
| @@ -287,6 +293,9 @@ GEM | @@ -287,6 +293,9 @@ GEM | ||
| 287 | treetop (1.4.10) | 293 | treetop (1.4.10) |
| 288 | polyglot | 294 | polyglot |
| 289 | polyglot (>= 0.3.1) | 295 | polyglot (>= 0.3.1) |
| 296 | + turbo-sprockets-rails3 (0.1.10) | ||
| 297 | + railties (>= 3.1.0) | ||
| 298 | + sprockets (>= 2.0.0) | ||
| 290 | tzinfo (0.3.33) | 299 | tzinfo (0.3.33) |
| 291 | uglifier (1.2.7) | 300 | uglifier (1.2.7) |
| 292 | execjs (>= 0.3.0) | 301 | execjs (>= 0.3.0) |
| @@ -317,6 +326,7 @@ DEPENDENCIES | @@ -317,6 +326,7 @@ DEPENDENCIES | ||
| 317 | bson_ext (= 1.6.2) | 326 | bson_ext (= 1.6.2) |
| 318 | campy | 327 | campy |
| 319 | capistrano | 328 | capistrano |
| 329 | + capistrano_colors | ||
| 320 | capybara | 330 | capybara |
| 321 | database_cleaner (~> 0.6.0) | 331 | database_cleaner (~> 0.6.0) |
| 322 | debugger | 332 | debugger |
| @@ -326,6 +336,7 @@ DEPENDENCIES | @@ -326,6 +336,7 @@ DEPENDENCIES | ||
| 326 | fabrication (~> 1.3.0) | 336 | fabrication (~> 1.3.0) |
| 327 | haml | 337 | haml |
| 328 | hipchat | 338 | hipchat |
| 339 | + hoi | ||
| 329 | hoptoad_notifier (~> 2.4) | 340 | hoptoad_notifier (~> 2.4) |
| 330 | htmlentities (~> 4.3.0) | 341 | htmlentities (~> 4.3.0) |
| 331 | inherited_resources | 342 | inherited_resources |
| @@ -338,10 +349,12 @@ DEPENDENCIES | @@ -338,10 +349,12 @@ DEPENDENCIES | ||
| 338 | nokogiri | 349 | nokogiri |
| 339 | oa-core | 350 | oa-core |
| 340 | octokit (~> 1.0.0) | 351 | octokit (~> 1.0.0) |
| 352 | + omniauth | ||
| 341 | omniauth-github | 353 | omniauth-github |
| 342 | oruen_redmine_client | 354 | oruen_redmine_client |
| 343 | pivotal-tracker | 355 | pivotal-tracker |
| 344 | pry | 356 | pry |
| 357 | + pry-rails | ||
| 345 | rack-ssl | 358 | rack-ssl |
| 346 | rack-ssl-enforcer | 359 | rack-ssl-enforcer |
| 347 | rails (= 3.2.8) | 360 | rails (= 3.2.8) |
| @@ -354,6 +367,7 @@ DEPENDENCIES | @@ -354,6 +367,7 @@ DEPENDENCIES | ||
| 354 | therubyracer | 367 | therubyracer |
| 355 | thin | 368 | thin |
| 356 | timecop | 369 | timecop |
| 370 | + turbo-sprockets-rails3 | ||
| 357 | uglifier (>= 1.0.3) | 371 | uglifier (>= 1.0.3) |
| 358 | unicorn | 372 | unicorn |
| 359 | useragent (~> 0.3.1) | 373 | useragent (~> 0.3.1) |
README.md
| @@ -406,6 +406,10 @@ Solutions known to work are listed below: | @@ -406,6 +406,10 @@ Solutions known to work are listed below: | ||
| 406 | <th>PHP (>= 5.3)</th> | 406 | <th>PHP (>= 5.3)</th> |
| 407 | <td>https://github.com/flippa/errbit-php</td> | 407 | <td>https://github.com/flippa/errbit-php</td> |
| 408 | </tr> | 408 | </tr> |
| 409 | + <tr> | ||
| 410 | + <th>Python</th> | ||
| 411 | + <td>https://github.com/mkorenkov/errbit.py , https://github.com/pulseenergy/airbrakepy</td> | ||
| 412 | + </tr> | ||
| 409 | </table> | 413 | </table> |
| 410 | 414 | ||
| 411 | TODO | 415 | TODO |
1.72 KB
1.72 KB
874 Bytes
app/models/issue_trackers/fogbugz_tracker.rb
| 1 | -class IssueTrackers::FogbugzTracker < IssueTracker | ||
| 2 | - Label = "fogbugz" | ||
| 3 | - Fields = [ | ||
| 4 | - [:project_id, { | ||
| 5 | - :label => "Area Name" | ||
| 6 | - }], | ||
| 7 | - [:account, { | ||
| 8 | - :label => "FogBugz URL", | ||
| 9 | - :placeholder => "abc from http://abc.fogbugz.com/" | ||
| 10 | - }], | ||
| 11 | - [:username, { | ||
| 12 | - :placeholder => "Username/Email for your account" | ||
| 13 | - }], | ||
| 14 | - [:password, { | ||
| 15 | - :placeholder => "Password for your account" | ||
| 16 | - }] | ||
| 17 | - ] | ||
| 18 | - | ||
| 19 | - def check_params | ||
| 20 | - if Fields.detect {|f| self[f[0]].blank? } | ||
| 21 | - errors.add :base, 'You must specify your FogBugz Area Name, FogBugz URL, Username, and Password' | 1 | +if defined? Fogbugz |
| 2 | + class IssueTrackers::FogbugzTracker < IssueTracker | ||
| 3 | + Label = "fogbugz" | ||
| 4 | + Fields = [ | ||
| 5 | + [:project_id, { | ||
| 6 | + :label => "Area Name" | ||
| 7 | + }], | ||
| 8 | + [:account, { | ||
| 9 | + :label => "FogBugz URL", | ||
| 10 | + :placeholder => "abc from http://abc.fogbugz.com/" | ||
| 11 | + }], | ||
| 12 | + [:username, { | ||
| 13 | + :placeholder => "Username/Email for your account" | ||
| 14 | + }], | ||
| 15 | + [:password, { | ||
| 16 | + :placeholder => "Password for your account" | ||
| 17 | + }] | ||
| 18 | + ] | ||
| 19 | + | ||
| 20 | + def check_params | ||
| 21 | + if Fields.detect {|f| self[f[0]].blank? } | ||
| 22 | + errors.add :base, 'You must specify your FogBugz Area Name, FogBugz URL, Username, and Password' | ||
| 23 | + end | ||
| 22 | end | 24 | end |
| 23 | - end | ||
| 24 | 25 | ||
| 25 | - def create_issue(problem, reported_by = nil) | ||
| 26 | - fogbugz = Fogbugz::Interface.new(:email => username, :password => password, :uri => "https://#{account}.fogbugz.com") | ||
| 27 | - fogbugz.authenticate | 26 | + def create_issue(problem, reported_by = nil) |
| 27 | + fogbugz = Fogbugz::Interface.new(:email => username, :password => password, :uri => "https://#{account}.fogbugz.com") | ||
| 28 | + fogbugz.authenticate | ||
| 28 | 29 | ||
| 29 | - issue = {} | ||
| 30 | - issue['sTitle'] = issue_title problem | ||
| 31 | - issue['sArea'] = project_id | ||
| 32 | - issue['sEvent'] = body_template.result(binding) | ||
| 33 | - issue['sTags'] = ['errbit'].join(',') | ||
| 34 | - issue['cols'] = ['ixBug'].join(',') | 30 | + issue = {} |
| 31 | + issue['sTitle'] = issue_title problem | ||
| 32 | + issue['sArea'] = project_id | ||
| 33 | + issue['sEvent'] = body_template.result(binding) | ||
| 34 | + issue['sTags'] = ['errbit'].join(',') | ||
| 35 | + issue['cols'] = ['ixBug'].join(',') | ||
| 35 | 36 | ||
| 36 | - fb_resp = fogbugz.command(:new, issue) | ||
| 37 | - problem.update_attributes( | ||
| 38 | - :issue_link => "https://#{account}.fogbugz.com/default.asp?#{fb_resp['case']['ixBug']}", | ||
| 39 | - :issue_type => Label | ||
| 40 | - ) | 37 | + fb_resp = fogbugz.command(:new, issue) |
| 38 | + problem.update_attributes( | ||
| 39 | + :issue_link => "https://#{account}.fogbugz.com/default.asp?#{fb_resp['case']['ixBug']}", | ||
| 40 | + :issue_type => Label | ||
| 41 | + ) | ||
| 41 | 42 | ||
| 42 | - end | 43 | + end |
| 43 | 44 | ||
| 44 | - def body_template | ||
| 45 | - @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/fogbugz_body.txt.erb")) | ||
| 46 | - end | 45 | + def body_template |
| 46 | + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/fogbugz_body.txt.erb")) | ||
| 47 | + end | ||
| 47 | 48 | ||
| 48 | - def url | ||
| 49 | - "http://#{account}.fogbugz.com/" | 49 | + def url |
| 50 | + "http://#{account}.fogbugz.com/" | ||
| 51 | + end | ||
| 50 | end | 52 | end |
| 51 | end | 53 | end |
| 52 | - |
app/models/issue_trackers/github_issues_tracker.rb
| 1 | -class IssueTrackers::GithubIssuesTracker < IssueTracker | ||
| 2 | - Label = "github" | ||
| 3 | - Note = 'Please configure your github repository in the <strong>GITHUB REPO</strong> field above.<br/>' << | ||
| 4 | - 'Instead of providing your username & password, you can link your Github account ' << | ||
| 5 | - 'to your user profile, and allow Errbit to create issues using your OAuth token.' | ||
| 6 | - | ||
| 7 | - Fields = [ | ||
| 8 | - [:username, { | ||
| 9 | - :placeholder => "Your username on GitHub" | ||
| 10 | - }], | ||
| 11 | - [:password, { | ||
| 12 | - :placeholder => "Password for your account" | ||
| 13 | - }] | ||
| 14 | - ] | ||
| 15 | - | ||
| 16 | - attr_accessor :oauth_token | ||
| 17 | - | ||
| 18 | - def project_id | ||
| 19 | - app.github_repo | ||
| 20 | - end | ||
| 21 | - | ||
| 22 | - def check_params | ||
| 23 | - if Fields.detect {|f| self[f[0]].blank? } | ||
| 24 | - errors.add :base, 'You must specify your GitHub username and password' | 1 | +if defined? Octokit |
| 2 | + class IssueTrackers::GithubIssuesTracker < IssueTracker | ||
| 3 | + Label = "github" | ||
| 4 | + Note = 'Please configure your github repository in the <strong>GITHUB REPO</strong> field above.<br/>' << | ||
| 5 | + 'Instead of providing your username & password, you can link your Github account ' << | ||
| 6 | + 'to your user profile, and allow Errbit to create issues using your OAuth token.' | ||
| 7 | + | ||
| 8 | + Fields = [ | ||
| 9 | + [:username, { | ||
| 10 | + :placeholder => "Your username on GitHub" | ||
| 11 | + }], | ||
| 12 | + [:password, { | ||
| 13 | + :placeholder => "Password for your account" | ||
| 14 | + }] | ||
| 15 | + ] | ||
| 16 | + | ||
| 17 | + attr_accessor :oauth_token | ||
| 18 | + | ||
| 19 | + def project_id | ||
| 20 | + app.github_repo | ||
| 25 | end | 21 | end |
| 26 | - end | ||
| 27 | 22 | ||
| 28 | - def create_issue(problem, reported_by = nil) | ||
| 29 | - # Login using OAuth token, if given. | ||
| 30 | - if oauth_token | ||
| 31 | - client = Octokit::Client.new(:login => username, :oauth_token => oauth_token) | ||
| 32 | - else | ||
| 33 | - client = Octokit::Client.new(:login => username, :password => password) | 23 | + def check_params |
| 24 | + if Fields.detect {|f| self[f[0]].blank? } | ||
| 25 | + errors.add :base, 'You must specify your GitHub username and password' | ||
| 26 | + end | ||
| 34 | end | 27 | end |
| 35 | 28 | ||
| 36 | - begin | ||
| 37 | - issue = client.create_issue(project_id, issue_title(problem), body_template.result(binding).unpack('C*').pack('U*'), options = {}) | ||
| 38 | - problem.update_attributes( | ||
| 39 | - :issue_link => issue.html_url, | ||
| 40 | - :issue_type => Label | ||
| 41 | - ) | ||
| 42 | - | ||
| 43 | - rescue Octokit::Unauthorized | ||
| 44 | - raise IssueTrackers::AuthenticationError, "Could not authenticate with GitHub. Please check your username and password." | 29 | + def create_issue(problem, reported_by = nil) |
| 30 | + # Login using OAuth token, if given. | ||
| 31 | + if oauth_token | ||
| 32 | + client = Octokit::Client.new(:login => username, :oauth_token => oauth_token) | ||
| 33 | + else | ||
| 34 | + client = Octokit::Client.new(:login => username, :password => password) | ||
| 35 | + end | ||
| 36 | + | ||
| 37 | + begin | ||
| 38 | + issue = client.create_issue(project_id, issue_title(problem), body_template.result(binding).unpack('C*').pack('U*'), options = {}) | ||
| 39 | + problem.update_attributes( | ||
| 40 | + :issue_link => issue.html_url, | ||
| 41 | + :issue_type => Label | ||
| 42 | + ) | ||
| 43 | + | ||
| 44 | + rescue Octokit::Unauthorized | ||
| 45 | + raise IssueTrackers::AuthenticationError, "Could not authenticate with GitHub. Please check your username and password." | ||
| 46 | + end | ||
| 45 | end | 47 | end |
| 46 | - end | ||
| 47 | 48 | ||
| 48 | - def body_template | ||
| 49 | - @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/github_issues_body.txt.erb").gsub(/^\s*/, '')) | ||
| 50 | - end | 49 | + def body_template |
| 50 | + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/github_issues_body.txt.erb").gsub(/^\s*/, '')) | ||
| 51 | + end | ||
| 51 | 52 | ||
| 52 | - def url | ||
| 53 | - "https://github.com/#{project_id}/issues" | 53 | + def url |
| 54 | + "https://github.com/#{project_id}/issues" | ||
| 55 | + end | ||
| 54 | end | 56 | end |
| 55 | -end | 57 | -end |
| 58 | +end | ||
| 56 | \ No newline at end of file | 59 | \ No newline at end of file |
app/models/issue_trackers/lighthouse_tracker.rb
| 1 | -class IssueTrackers::LighthouseTracker < IssueTracker | ||
| 2 | - Label = "lighthouseapp" | ||
| 3 | - Fields = [ | ||
| 4 | - [:account, { | ||
| 5 | - :placeholder => "abc from http://abc.lighthouseapp.com" | ||
| 6 | - }], | ||
| 7 | - [:api_token, { | ||
| 8 | - :placeholder => "API Token for your account" | ||
| 9 | - }], | ||
| 10 | - [:project_id, { | ||
| 11 | - :placeholder => "Lighthouse project" | ||
| 12 | - }] | ||
| 13 | - ] | ||
| 14 | - | ||
| 15 | - def check_params | ||
| 16 | - if Fields.detect {|f| self[f[0]].blank? } | ||
| 17 | - errors.add :base, 'You must specify your Lighthouseapp account, API token and Project ID' | 1 | +if defined? Lighthouse |
| 2 | + class IssueTrackers::LighthouseTracker < IssueTracker | ||
| 3 | + Label = "lighthouseapp" | ||
| 4 | + Fields = [ | ||
| 5 | + [:account, { | ||
| 6 | + :placeholder => "abc from http://abc.lighthouseapp.com" | ||
| 7 | + }], | ||
| 8 | + [:api_token, { | ||
| 9 | + :placeholder => "API Token for your account" | ||
| 10 | + }], | ||
| 11 | + [:project_id, { | ||
| 12 | + :placeholder => "Lighthouse project" | ||
| 13 | + }] | ||
| 14 | + ] | ||
| 15 | + | ||
| 16 | + def check_params | ||
| 17 | + if Fields.detect {|f| self[f[0]].blank? } | ||
| 18 | + errors.add :base, 'You must specify your Lighthouseapp account, API token and Project ID' | ||
| 19 | + end | ||
| 18 | end | 20 | end |
| 19 | - end | ||
| 20 | 21 | ||
| 21 | - def create_issue(problem, reported_by = nil) | ||
| 22 | - Lighthouse.account = account | ||
| 23 | - Lighthouse.token = api_token | ||
| 24 | - # updating lighthouse account | ||
| 25 | - Lighthouse::Ticket.site | ||
| 26 | - Lighthouse::Ticket.format = :xml | ||
| 27 | - ticket = Lighthouse::Ticket.new(:project_id => project_id) | ||
| 28 | - ticket.title = issue_title problem | 22 | + def create_issue(problem, reported_by = nil) |
| 23 | + Lighthouse.account = account | ||
| 24 | + Lighthouse.token = api_token | ||
| 25 | + # updating lighthouse account | ||
| 26 | + Lighthouse::Ticket.site | ||
| 27 | + Lighthouse::Ticket.format = :xml | ||
| 28 | + ticket = Lighthouse::Ticket.new(:project_id => project_id) | ||
| 29 | + ticket.title = issue_title problem | ||
| 29 | 30 | ||
| 30 | - ticket.body = body_template.result(binding) | 31 | + ticket.body = body_template.result(binding) |
| 31 | 32 | ||
| 32 | - ticket.tags << "errbit" | ||
| 33 | - ticket.save! | ||
| 34 | - problem.update_attributes( | ||
| 35 | - :issue_link => "#{Lighthouse::Ticket.site.to_s.sub(/#{Lighthouse::Ticket.site.path}$/, '')}#{Lighthouse::Ticket.element_path(ticket.id, :project_id => project_id)}".sub(/\.xml$/, ''), | ||
| 36 | - :issue_type => Label | ||
| 37 | - ) | 33 | + ticket.tags << "errbit" |
| 34 | + ticket.save! | ||
| 35 | + problem.update_attributes( | ||
| 36 | + :issue_link => "#{Lighthouse::Ticket.site.to_s.sub(/#{Lighthouse::Ticket.site.path}$/, '')}#{Lighthouse::Ticket.element_path(ticket.id, :project_id => project_id)}".sub(/\.xml$/, ''), | ||
| 37 | + :issue_type => Label | ||
| 38 | + ) | ||
| 38 | 39 | ||
| 39 | - end | 40 | + end |
| 40 | 41 | ||
| 41 | - def body_template | ||
| 42 | - @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/lighthouseapp_body.txt.erb").gsub(/^\s*/, '')) | ||
| 43 | - end | 42 | + def body_template |
| 43 | + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/lighthouseapp_body.txt.erb").gsub(/^\s*/, '')) | ||
| 44 | + end | ||
| 44 | 45 | ||
| 45 | - def url | ||
| 46 | - "http://#{account}.lighthouseapp.com" | 46 | + def url |
| 47 | + "http://#{account}.lighthouseapp.com" | ||
| 48 | + end | ||
| 47 | end | 49 | end |
| 48 | -end | ||
| 49 | - | 50 | +end |
| 50 | \ No newline at end of file | 51 | \ No newline at end of file |
app/models/issue_trackers/pivotal_labs_tracker.rb
| 1 | -class IssueTrackers::PivotalLabsTracker < IssueTracker | ||
| 2 | - Label = "pivotal" | ||
| 3 | - Fields = [ | ||
| 4 | - [:api_token, { | ||
| 5 | - :placeholder => "API Token for your account" | ||
| 6 | - }], | ||
| 7 | - [:project_id, {}] | ||
| 8 | - ] | 1 | +if defined? PivotalTracker |
| 2 | + class IssueTrackers::PivotalLabsTracker < IssueTracker | ||
| 3 | + Label = "pivotal" | ||
| 4 | + Fields = [ | ||
| 5 | + [:api_token, { | ||
| 6 | + :placeholder => "API Token for your account" | ||
| 7 | + }], | ||
| 8 | + [:project_id, {}] | ||
| 9 | + ] | ||
| 9 | 10 | ||
| 10 | - def check_params | ||
| 11 | - if Fields.detect {|f| self[f[0]].blank? } | ||
| 12 | - errors.add :base, 'You must specify your Pivotal Tracker API token and Project ID' | 11 | + def check_params |
| 12 | + if Fields.detect {|f| self[f[0]].blank? } | ||
| 13 | + errors.add :base, 'You must specify your Pivotal Tracker API token and Project ID' | ||
| 14 | + end | ||
| 13 | end | 15 | end |
| 14 | - end | ||
| 15 | 16 | ||
| 16 | - def create_issue(problem, reported_by = nil) | ||
| 17 | - PivotalTracker::Client.token = api_token | ||
| 18 | - PivotalTracker::Client.use_ssl = true | ||
| 19 | - project = PivotalTracker::Project.find project_id.to_i | ||
| 20 | - story = project.stories.create :name => issue_title(problem), | ||
| 21 | - :story_type => 'bug', :description => body_template.result(binding), | ||
| 22 | - :requested_by => reported_by.name | 17 | + def create_issue(problem, reported_by = nil) |
| 18 | + PivotalTracker::Client.token = api_token | ||
| 19 | + PivotalTracker::Client.use_ssl = true | ||
| 20 | + project = PivotalTracker::Project.find project_id.to_i | ||
| 21 | + story = project.stories.create :name => issue_title(problem), | ||
| 22 | + :story_type => 'bug', :description => body_template.result(binding), | ||
| 23 | + :requested_by => reported_by.name | ||
| 23 | 24 | ||
| 24 | - if story.errors.present? | ||
| 25 | - raise IssueTrackers::IssueTrackerError, story.errors.first | ||
| 26 | - else | ||
| 27 | - problem.update_attributes( | ||
| 28 | - :issue_link => "https://www.pivotaltracker.com/story/show/#{story.id}", | ||
| 29 | - :issue_type => Label | ||
| 30 | - ) | 25 | + if story.errors.present? |
| 26 | + raise IssueTrackers::IssueTrackerError, story.errors.first | ||
| 27 | + else | ||
| 28 | + problem.update_attributes( | ||
| 29 | + :issue_link => "https://www.pivotaltracker.com/story/show/#{story.id}", | ||
| 30 | + :issue_type => Label | ||
| 31 | + ) | ||
| 32 | + end | ||
| 31 | end | 33 | end |
| 32 | - end | ||
| 33 | 34 | ||
| 34 | - def body_template | ||
| 35 | - @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/pivotal_body.txt.erb")) | ||
| 36 | - end | 35 | + def body_template |
| 36 | + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/pivotal_body.txt.erb")) | ||
| 37 | + end | ||
| 37 | 38 | ||
| 38 | - def url | ||
| 39 | - "https://www.pivotaltracker.com/" | 39 | + def url |
| 40 | + "https://www.pivotaltracker.com/" | ||
| 41 | + end | ||
| 40 | end | 42 | end |
| 41 | -end | ||
| 42 | - | 43 | +end |
| 43 | \ No newline at end of file | 44 | \ No newline at end of file |
app/models/issue_trackers/redmine_tracker.rb
| 1 | -class IssueTrackers::RedmineTracker < IssueTracker | ||
| 2 | - Label = "redmine" | ||
| 3 | - Fields = [ | ||
| 4 | - [:account, { | ||
| 5 | - :label => "Redmine URL", | ||
| 6 | - :placeholder => "e.g. http://www.redmine.org/" | ||
| 7 | - }], | ||
| 8 | - [:api_token, { | ||
| 9 | - :placeholder => "API Token for your account" | ||
| 10 | - }], | ||
| 11 | - [:project_id, { | ||
| 12 | - :label => "Ticket Project", | ||
| 13 | - :placeholder => "Redmine Project where tickets will be created" | ||
| 14 | - }], | ||
| 15 | - [:alt_project_id, { | ||
| 16 | - :optional => true, | ||
| 17 | - :label => "App Project", | ||
| 18 | - :placeholder => "Where app's files & revisions can be viewed. (Leave blank to use the above project by default)" | ||
| 19 | - }] | ||
| 20 | - ] | 1 | +if defined? RedmineClient |
| 2 | + class IssueTrackers::RedmineTracker < IssueTracker | ||
| 3 | + Label = "redmine" | ||
| 4 | + Fields = [ | ||
| 5 | + [:account, { | ||
| 6 | + :label => "Redmine URL", | ||
| 7 | + :placeholder => "e.g. http://www.redmine.org/" | ||
| 8 | + }], | ||
| 9 | + [:api_token, { | ||
| 10 | + :placeholder => "API Token for your account" | ||
| 11 | + }], | ||
| 12 | + [:project_id, { | ||
| 13 | + :label => "Ticket Project", | ||
| 14 | + :placeholder => "Redmine Project where tickets will be created" | ||
| 15 | + }], | ||
| 16 | + [:alt_project_id, { | ||
| 17 | + :optional => true, | ||
| 18 | + :label => "App Project", | ||
| 19 | + :placeholder => "Where app's files & revisions can be viewed. (Leave blank to use the above project by default)" | ||
| 20 | + }] | ||
| 21 | + ] | ||
| 21 | 22 | ||
| 22 | - def check_params | ||
| 23 | - if Fields.detect {|f| self[f[0]].blank? && !f[1][:optional]} | ||
| 24 | - errors.add :base, 'You must specify your Redmine URL, API token and Project ID' | 23 | + def check_params |
| 24 | + if Fields.detect {|f| self[f[0]].blank? && !f[1][:optional]} | ||
| 25 | + errors.add :base, 'You must specify your Redmine URL, API token and Project ID' | ||
| 26 | + end | ||
| 25 | end | 27 | end |
| 26 | - end | ||
| 27 | 28 | ||
| 28 | - def create_issue(problem, reported_by = nil) | ||
| 29 | - token = api_token | ||
| 30 | - acc = account | ||
| 31 | - RedmineClient::Base.configure do | ||
| 32 | - self.token = token | ||
| 33 | - self.site = acc | ||
| 34 | - self.format = :xml | 29 | + def create_issue(problem, reported_by = nil) |
| 30 | + token = api_token | ||
| 31 | + acc = account | ||
| 32 | + RedmineClient::Base.configure do | ||
| 33 | + self.token = token | ||
| 34 | + self.site = acc | ||
| 35 | + self.format = :xml | ||
| 36 | + end | ||
| 37 | + issue = RedmineClient::Issue.new(:project_id => project_id) | ||
| 38 | + issue.subject = issue_title problem | ||
| 39 | + issue.description = body_template.result(binding) | ||
| 40 | + issue.save! | ||
| 41 | + problem.update_attributes( | ||
| 42 | + :issue_link => "#{RedmineClient::Issue.site.to_s.sub(/#{RedmineClient::Issue.site.path}$/, '')}#{RedmineClient::Issue.element_path(issue.id, :project_id => project_id)}".sub(/\.xml\?project_id=#{project_id}$/, "\?project_id=#{project_id}"), | ||
| 43 | + :issue_type => Label | ||
| 44 | + ) | ||
| 35 | end | 45 | end |
| 36 | - issue = RedmineClient::Issue.new(:project_id => project_id) | ||
| 37 | - issue.subject = issue_title problem | ||
| 38 | - issue.description = body_template.result(binding) | ||
| 39 | - issue.save! | ||
| 40 | - problem.update_attributes( | ||
| 41 | - :issue_link => "#{RedmineClient::Issue.site.to_s.sub(/#{RedmineClient::Issue.site.path}$/, '')}#{RedmineClient::Issue.element_path(issue.id, :project_id => project_id)}".sub(/\.xml\?project_id=#{project_id}$/, "\?project_id=#{project_id}"), | ||
| 42 | - :issue_type => Label | ||
| 43 | - ) | ||
| 44 | - end | ||
| 45 | 46 | ||
| 46 | - def url_to_file(file_path, line_number = nil) | ||
| 47 | - # alt_project_id let's users specify a different project for tickets / app files. | ||
| 48 | - project = self.alt_project_id.present? ? self.alt_project_id : self.project_id | ||
| 49 | - url = "#{self.account}/projects/#{project}/repository/annotate/#{file_path.sub(/^\//,'')}" | ||
| 50 | - line_number ? url << "#L#{line_number}" : url | ||
| 51 | - end | 47 | + def url_to_file(file_path, line_number = nil) |
| 48 | + # alt_project_id let's users specify a different project for tickets / app files. | ||
| 49 | + project = self.alt_project_id.present? ? self.alt_project_id : self.project_id | ||
| 50 | + url = "#{self.account}/projects/#{project}/repository/annotate/#{file_path.sub(/^\//,'')}" | ||
| 51 | + line_number ? url << "#L#{line_number}" : url | ||
| 52 | + end | ||
| 52 | 53 | ||
| 53 | - def body_template | ||
| 54 | - @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/textile_body.txt.erb")) | ||
| 55 | - end | 54 | + def body_template |
| 55 | + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/textile_body.txt.erb")) | ||
| 56 | + end | ||
| 56 | 57 | ||
| 57 | - def url | ||
| 58 | - acc_url = account.start_with?('http') ? account : "http://#{account}" | ||
| 59 | - URI.parse("#{acc_url}?project_id=#{project_id}").to_s | ||
| 60 | - rescue URI::InvalidURIError | 58 | + def url |
| 59 | + acc_url = account.start_with?('http') ? account : "http://#{account}" | ||
| 60 | + URI.parse("#{acc_url}?project_id=#{project_id}").to_s | ||
| 61 | + rescue URI::InvalidURIError | ||
| 62 | + end | ||
| 61 | end | 63 | end |
| 62 | end | 64 | end |
| 63 | - |
app/models/notice.rb
| @@ -114,7 +114,7 @@ class Notice | @@ -114,7 +114,7 @@ class Notice | ||
| 114 | end | 114 | end |
| 115 | 115 | ||
| 116 | def remove_cached_attributes_from_problem | 116 | def remove_cached_attributes_from_problem |
| 117 | - problem.remove_cached_notice_attribures(self) if err | 117 | + problem.remove_cached_notice_attributes(self) if err |
| 118 | end | 118 | end |
| 119 | 119 | ||
| 120 | def unresolve_problem | 120 | def unresolve_problem |
app/models/notification_service.rb
| @@ -7,7 +7,8 @@ class NotificationService | @@ -7,7 +7,8 @@ class NotificationService | ||
| 7 | field :room_id, :type => String | 7 | field :room_id, :type => String |
| 8 | field :api_token, :type => String | 8 | field :api_token, :type => String |
| 9 | field :subdomain, :type => String | 9 | field :subdomain, :type => String |
| 10 | - | 10 | + field :sender_name, :type => String |
| 11 | + | ||
| 11 | embedded_in :app, :inverse_of => :notification_service | 12 | embedded_in :app, :inverse_of => :notification_service |
| 12 | 13 | ||
| 13 | validate :check_params | 14 | validate :check_params |
app/models/notification_services/campfire_service.rb
| 1 | -class NotificationServices::CampfireService < NotificationService | ||
| 2 | - Label = "campfire" | ||
| 3 | - Fields = [ | ||
| 4 | - [:subdomain, { | ||
| 5 | - :placeholder => "Campfire Subdomain" | ||
| 6 | - }], | ||
| 7 | - [:api_token, { | ||
| 8 | - :placeholder => "API Token" | ||
| 9 | - }], | ||
| 10 | - [:room_id, { | ||
| 11 | - :placeholder => "Room ID", | ||
| 12 | - :label => "Room ID" | ||
| 13 | - }], | ||
| 14 | - ] | 1 | +if defined? Campy |
| 2 | + class NotificationServices::CampfireService < NotificationService | ||
| 3 | + Label = "campfire" | ||
| 4 | + Fields = [ | ||
| 5 | + [:subdomain, { | ||
| 6 | + :placeholder => "Campfire Subdomain" | ||
| 7 | + }], | ||
| 8 | + [:api_token, { | ||
| 9 | + :placeholder => "API Token" | ||
| 10 | + }], | ||
| 11 | + [:room_id, { | ||
| 12 | + :placeholder => "Room ID", | ||
| 13 | + :label => "Room ID" | ||
| 14 | + }], | ||
| 15 | + ] | ||
| 15 | 16 | ||
| 16 | - def check_params | ||
| 17 | - if Fields.detect {|f| self[f[0]].blank? } | ||
| 18 | - errors.add :base, 'You must specify your Campfire Subdomain, API token and Room ID' | 17 | + def check_params |
| 18 | + if Fields.detect {|f| self[f[0]].blank? } | ||
| 19 | + errors.add :base, 'You must specify your Campfire Subdomain, API token and Room ID' | ||
| 20 | + end | ||
| 19 | end | 21 | end |
| 20 | - end | ||
| 21 | 22 | ||
| 22 | - def create_notification(problem) | ||
| 23 | - # build the campfire client | ||
| 24 | - campy = Campy::Room.new(:account => subdomain, :token => api_token, :room_id => room_id) | 23 | + def create_notification(problem) |
| 24 | + # build the campfire client | ||
| 25 | + campy = Campy::Room.new(:account => subdomain, :token => api_token, :room_id => room_id) | ||
| 25 | 26 | ||
| 26 | - # post the issue to the campfire room | ||
| 27 | - campy.speak "[errbit] http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} #{notification_description problem}" | 27 | + # post the issue to the campfire room |
| 28 | + campy.speak "[errbit] #{problem.app.name} #{notification_description problem} - http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}/problems/#{problem.id.to_s}" | ||
| 29 | + end | ||
| 28 | end | 30 | end |
| 29 | -end | ||
| 30 | \ No newline at end of file | 31 | \ No newline at end of file |
| 32 | +end |
app/models/notification_services/hipchat_service.rb
| 1 | -class NotificationServices::HipchatService < NotificationService | ||
| 2 | - Label = 'hipchat' | ||
| 3 | - Fields = [ | ||
| 4 | - [:api_token, { | ||
| 5 | - :placeholder => "API Token" | ||
| 6 | - }], | ||
| 7 | - [:room_id, { | ||
| 8 | - :placeholder => "Room ID", | ||
| 9 | - :label => "Room ID" | ||
| 10 | - }], | ||
| 11 | - ] | 1 | +if defined? HipChat |
| 2 | + class NotificationServices::HipchatService < NotificationService | ||
| 3 | + Label = 'hipchat' | ||
| 4 | + Fields = [ | ||
| 5 | + [:api_token, { | ||
| 6 | + :placeholder => "API Token" | ||
| 7 | + }], | ||
| 8 | + [:room_id, { | ||
| 9 | + :placeholder => "Room ID", | ||
| 10 | + :label => "Room ID" | ||
| 11 | + }], | ||
| 12 | + ] | ||
| 12 | 13 | ||
| 13 | - def check_params | ||
| 14 | - if Fields.any? { |f, _| self[f].blank? } | ||
| 15 | - errors.add :base, 'You must specify your Hipchat API token and Room ID' | 14 | + def check_params |
| 15 | + if Fields.any? { |f, _| self[f].blank? } | ||
| 16 | + errors.add :base, 'You must specify your Hipchat API token and Room ID' | ||
| 17 | + end | ||
| 16 | end | 18 | end |
| 17 | - end | ||
| 18 | 19 | ||
| 19 | - def create_notification(problem) | ||
| 20 | - url = app_problem_url problem.app, problem | ||
| 21 | - message = <<-MSG.strip_heredoc | ||
| 22 | - [#{ERB::Util.html_escape problem.app.name}]#{ERB::Util.html_escape notification_description(problem)}<br> | ||
| 23 | - <a href="#{url}">#{url}</a> | ||
| 24 | - MSG | 20 | + def create_notification(problem) |
| 21 | + url = app_problem_url problem.app, problem | ||
| 22 | + message = <<-MSG.strip_heredoc | ||
| 23 | + [#{ERB::Util.html_escape problem.app.name}]#{ERB::Util.html_escape notification_description(problem)}<br> | ||
| 24 | + <a href="#{url}">#{url}</a> | ||
| 25 | + MSG | ||
| 25 | 26 | ||
| 26 | - client = HipChat::Client.new(api_token) | ||
| 27 | - client[room_id].send('Errbit', message, :color => 'red') | 27 | + client = HipChat::Client.new(api_token) |
| 28 | + client[room_id].send('Errbit', message, :color => 'red') | ||
| 29 | + end | ||
| 28 | end | 30 | end |
| 29 | -end | 31 | -end |
| 32 | +end | ||
| 30 | \ No newline at end of file | 33 | \ No newline at end of file |
| @@ -0,0 +1,38 @@ | @@ -0,0 +1,38 @@ | ||
| 1 | +class NotificationServices::HoiioService < NotificationService | ||
| 2 | + Label = "hoiio" | ||
| 3 | + Fields = [ | ||
| 4 | + [:api_token, { | ||
| 5 | + :placeholder => "App ID", | ||
| 6 | + :label => "App ID" | ||
| 7 | + }], | ||
| 8 | + [:subdomain, { | ||
| 9 | + :placeholder => "Access Token", | ||
| 10 | + :label => "Access Token" | ||
| 11 | + }], | ||
| 12 | + [:room_id, { | ||
| 13 | + :placeholder => "+6511111111, +6511111111", | ||
| 14 | + :label => "Recipient's phone numbers seperated by comma. Phone numbers should start with a \"+\" and country code." | ||
| 15 | + }] | ||
| 16 | + ] | ||
| 17 | + | ||
| 18 | + def check_params | ||
| 19 | + if Fields.detect {|f| self[f[0]].blank? } | ||
| 20 | + errors.add :base, 'You must specify your App ID, Access Token and Recipient\'s phone numbers' | ||
| 21 | + end | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | + def notification_description(problem) | ||
| 25 | + "[#{ problem.environment }]#{problem.message.to_s.truncate(50)}" | ||
| 26 | + end | ||
| 27 | + | ||
| 28 | + def create_notification(problem) | ||
| 29 | + # build the hoi client | ||
| 30 | + sms = Hoi::SMS.new(api_token, subdomain) | ||
| 31 | + | ||
| 32 | + # send sms | ||
| 33 | + room_id.split(',').each do |number| | ||
| 34 | + sms.send :dest => number, :msg => "http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} #{notification_description problem}" | ||
| 35 | + end | ||
| 36 | + | ||
| 37 | + end | ||
| 38 | +end | ||
| 0 | \ No newline at end of file | 39 | \ No newline at end of file |
app/models/problem.rb
| @@ -153,7 +153,7 @@ class Problem | @@ -153,7 +153,7 @@ class Problem | ||
| 153 | update_attributes!(attrs) | 153 | update_attributes!(attrs) |
| 154 | end | 154 | end |
| 155 | 155 | ||
| 156 | - def remove_cached_notice_attribures(notice) | 156 | + def remove_cached_notice_attributes(notice) |
| 157 | update_attributes!( | 157 | update_attributes!( |
| 158 | :messages => attribute_count_descrease(:messages, notice.message), | 158 | :messages => attribute_count_descrease(:messages, notice.message), |
| 159 | :hosts => attribute_count_descrease(:hosts, notice.host), | 159 | :hosts => attribute_count_descrease(:hosts, notice.host), |
config/initializers/_load_config.rb
| @@ -60,6 +60,9 @@ default_config.each do |k,v| | @@ -60,6 +60,9 @@ default_config.each do |k,v| | ||
| 60 | Errbit::Config.send("#{k}=", v) if Errbit::Config.send(k) === nil | 60 | Errbit::Config.send("#{k}=", v) if Errbit::Config.send(k) === nil |
| 61 | end | 61 | end |
| 62 | 62 | ||
| 63 | +# Disable GitHub oauth if gem is missing | ||
| 64 | +Errbit::Config.github_authentication = false unless defined?(OmniAuth::Strategies::GitHub) | ||
| 65 | + | ||
| 63 | # Set SMTP settings if given. | 66 | # Set SMTP settings if given. |
| 64 | if smtp = Errbit::Config.smtp_settings | 67 | if smtp = Errbit::Config.smtp_settings |
| 65 | ActionMailer::Base.delivery_method = :smtp | 68 | ActionMailer::Base.delivery_method = :smtp |
config/initializers/devise.rb
| @@ -122,7 +122,8 @@ Devise.setup do |config| | @@ -122,7 +122,8 @@ Devise.setup do |config| | ||
| 122 | config.omniauth :github, | 122 | config.omniauth :github, |
| 123 | Errbit::Config.github_client_id, | 123 | Errbit::Config.github_client_id, |
| 124 | Errbit::Config.github_secret, | 124 | Errbit::Config.github_secret, |
| 125 | - :scope => Errbit::Config.github_access_scope.join(",") | 125 | + :scope => Errbit::Config.github_access_scope.join(","), |
| 126 | + :skip_info => true | ||
| 126 | end | 127 | end |
| 127 | 128 | ||
| 128 | # ==> Navigation configuration | 129 | # ==> Navigation configuration |
lib/issue_trackers/apis/mingle.rb
| 1 | +require 'active_resource' | ||
| 2 | + | ||
| 1 | module Mingle | 3 | module Mingle |
| 2 | class Card < ActiveResource::Base | 4 | class Card < ActiveResource::Base |
| 3 | # site template ~> "https://username:password@mingle.example.com/api/v1/projects/:project_id/" | 5 | # site template ~> "https://username:password@mingle.example.com/api/v1/projects/:project_id/" |
spec/fabricators/notification_service_fabricator.rb
| @@ -5,6 +5,6 @@ Fabricator :notification_service do | @@ -5,6 +5,6 @@ Fabricator :notification_service do | ||
| 5 | subdomain { sequence :word } | 5 | subdomain { sequence :word } |
| 6 | end | 6 | end |
| 7 | 7 | ||
| 8 | -%w(campfire hipchat).each do |t| | 8 | +%w(campfire hipchat hoiio).each do |t| |
| 9 | Fabricator "#{t}_notification_service".to_sym, :from => :notification_service, :class_name => "NotificationService::#{t.camelcase}Service" | 9 | Fabricator "#{t}_notification_service".to_sym, :from => :notification_service, :class_name => "NotificationService::#{t.camelcase}Service" |
| 10 | end | 10 | end |
| @@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
| 1 | +require 'spec_helper' | ||
| 2 | + | ||
| 3 | +describe NotificationService::HoiioService do | ||
| 4 | + it "it should send a notification to hoiio" do | ||
| 5 | + # setup | ||
| 6 | + notice = Fabricate :notice | ||
| 7 | + notification_service = Fabricate :hoiio_notification_service, :app => notice.app | ||
| 8 | + problem = notice.problem | ||
| 9 | + | ||
| 10 | + # hoi stubbing | ||
| 11 | + sms = mock('HoiioService') | ||
| 12 | + Hoi::SMS.stub(:new).and_return(sms) | ||
| 13 | + sms.stub(:send) { true } | ||
| 14 | + | ||
| 15 | + #assert | ||
| 16 | + sms.should_receive(:send) | ||
| 17 | + | ||
| 18 | + notification_service.create_notification(problem) | ||
| 19 | + end | ||
| 20 | +end | ||
| 21 | + |