flowdock 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in flowdock.gemspec
4
+ gemspec
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ flowdock (0.1.0)
5
+ httparty (~> 0.7.8)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ addressable (2.2.4)
11
+ crack (0.1.8)
12
+ diff-lcs (1.1.2)
13
+ httparty (0.7.8)
14
+ crack (= 0.1.8)
15
+ rspec (2.6.0)
16
+ rspec-core (~> 2.6.0)
17
+ rspec-expectations (~> 2.6.0)
18
+ rspec-mocks (~> 2.6.0)
19
+ rspec-core (2.6.4)
20
+ rspec-expectations (2.6.0)
21
+ diff-lcs (~> 1.1.2)
22
+ rspec-mocks (2.6.0)
23
+ webmock (1.6.2)
24
+ addressable (>= 2.2.2)
25
+ crack (>= 0.1.7)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ flowdock!
32
+ rspec
33
+ webmock (~> 1.6.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Flowdock Ltd
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,49 @@
1
+ flowdock
2
+ ========
3
+
4
+ Ruby Gem for using the Flowdock API.
5
+
6
+ * http://www.flowdock.com/api
7
+
8
+ Compatibility
9
+ -------------
10
+
11
+ flowdock gem has been tested under Ruby 1.8.7.
12
+
13
+ Requirements
14
+ ------------
15
+
16
+ * HTTParty
17
+
18
+ Install
19
+ -------
20
+
21
+ * gem install flowdock
22
+
23
+ Example
24
+ -------
25
+
26
+ require 'flowdock'
27
+
28
+ # create a new Flow object with target flow's api token and sender information
29
+ flow = Flowdock::Flow.new(:api_token => "56188e2003e370c6efa9711988f7bf02",
30
+ :source => "myapp",
31
+ :from => {:name => "John Doe", :address => "john.doe@yourdomain.com"})
32
+
33
+ # send message to the flow
34
+ flow.send_message(:subject => "Greetings from Flowdock API Gem!",
35
+ :content => "<h2>It works!</h2><p>Now you can start developing your awesome application for Flowdock.</p>",
36
+ :tags => ["cool", "stuff"])
37
+
38
+ API methods
39
+ -----------
40
+
41
+ * Flow methods
42
+
43
+ send_message(params) - Send message to flow. Required parameters for message are :subject and :content. Optional parameter :tags can be used to add tags to message. Currently messages are always sent in the HTML format.
44
+
45
+
46
+ Copyright
47
+ ---------
48
+
49
+ Copyright (c) 2011 Flowdock Ltd. See MIT-LICENSE for further details.
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "flowdock/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "flowdock"
7
+ s.authors = ["anttipitkanen"]
8
+ s.version = Flowdock::GEM_VERSION
9
+ s.email = ["team@flowdock.com"]
10
+ s.homepage = "https://www.flowdock.com/api"
11
+ s.summary = %q{Ruby Gem for using Flowdock's API.}
12
+
13
+ s.rubyforge_project = "flowdock"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency("httparty", "~>0.7.8")
21
+ s.add_development_dependency("rspec")
22
+ s.add_development_dependency("webmock", "~>1.6.0")
23
+ end
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+
4
+ module Flowdock
5
+ FLOWDOCK_API_URL = "https://api.flowdock.com/v1/messages/influx"
6
+
7
+ class Flow
8
+ include HTTParty
9
+ class InvalidParameterError < StandardError; end
10
+ class ApiError < StandardError; end
11
+
12
+ # Required options keys: :api_token, :source, :from => { :name, :address }
13
+ def initialize(options = {})
14
+ @api_token = options[:api_token]
15
+ raise InvalidParameterError, "Flow must have :api_token attribute" if @api_token.blank?
16
+
17
+ @source = options[:source]
18
+ raise InvalidParameterError, "Flow must have valid :source attribute, only alphanumeric characters and underscores can be used" if @source.blank? || !@source.match(/^[a-z0-9\-_ ]+$/i)
19
+
20
+ @project = options[:project]
21
+ raise InvalidParameterError, "Optional attribute :project can only contain alphanumeric characters and underscores" if !@project.blank? && !@project.match(/^[a-z0-9\-_ ]+$/i)
22
+
23
+ @from = options[:from] || {}
24
+ end
25
+
26
+ def send_message(params)
27
+ raise InvalidParameterError, "Message must have both :subject and :content" if params[:subject].blank? || params[:content].blank?
28
+
29
+ from = (params[:from].kind_of?(Hash)) ? params[:from] : @from
30
+ raise InvalidParameterError, "Flow's :from attribute must have both :name and :address" if from[:name].blank? || from[:address].blank?
31
+
32
+ tags = (params[:tags].kind_of?(Array)) ? params[:tags] : []
33
+ tags.reject! { |tag| !tag.kind_of?(String) || tag.blank? }
34
+
35
+ params = {
36
+ :source => @source,
37
+ :format => 'html', # currently only supported format
38
+ :from_name => from[:name],
39
+ :from_address => from[:address],
40
+ :subject => params[:subject],
41
+ :content => params[:content]
42
+ }
43
+ params[:tags] = tags.join(",") if tags.size > 0
44
+ params[:project] = @project unless @project.blank?
45
+
46
+ # Send the request
47
+ resp = self.class.post(get_flowdock_api_url, :body => params)
48
+ raise ApiError, (resp.code == 500 ? "Flowdock API returned error: #{resp.body}" : "HTTP Error #{resp.code}") unless resp.code == 200
49
+ true
50
+ end
51
+
52
+ private
53
+
54
+ def get_flowdock_api_url
55
+ "#{FLOWDOCK_API_URL}/#{@api_token}"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,56 @@
1
+ require 'flowdock'
2
+ require 'grit'
3
+
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ set :flowdock_send_notification, false
6
+
7
+ namespace :flowdock do
8
+ task :set_flowdock_api do
9
+ set :repo, Grit::Repo.new(".")
10
+ config = Grit::Config.new(repo)
11
+ set :flowdock_api, Flowdock::Flow.new(:api_token => flowdock_api_token,
12
+ :source => "Capistrano deployment", :project => flowdock_project_name,
13
+ :from => {:name => config["user.name"], :address => config["user.email"]})
14
+ end
15
+
16
+ task :trigger_notification do
17
+ set :flowdock_send_notification, true
18
+ end
19
+
20
+ task :notify_deploy_finished do
21
+ # send message to the flow
22
+ flowdock_api.send_message(:format => "html",
23
+ :subject => "#{flowdock_project_name} deployed with branch #{branch} on ##{rails_env}",
24
+ :content => notification_message,
25
+ :tags => ["deploy", "#{rails_env}"] | flowdock_deploy_tags)
26
+ end
27
+
28
+ def notification_message
29
+ if branch == current_branch || stage == :production
30
+ message = "<p>The following changes were just deployed to #{host}:</p>"
31
+ commits = repo.commits_between(capture("cat #{previous_release}/REVISION").chomp, current_revision).reverse
32
+
33
+ unless commits.empty?
34
+ commits.each do |c|
35
+ short, long = c.message.split(/\n+/, 2)
36
+
37
+ message << "\n<div style=\"margin-bottom: 10px\"><div style=\"height:30px;width:30px;float:left;margin-right:5px;\"><img src=\"http://gravatar.com/avatar/#{MD5::md5(c.author.email.downcase)}?s=30\" /></div>"
38
+ message << "<div style=\"padding-left: 35px;\">#{CGI.escapeHTML(short)}<br/>"
39
+ if long
40
+ long.gsub!(/\n/, '<br />')
41
+ message << '<p style="margin:5px 0px; padding: 0 5px; border-left: 3px solid #ccc">' + long + '</p>'
42
+ end
43
+ message << "<span style=\"font-size: 90%; color: #333\"><code>#{c.id_abbrev}</code> <a href=\"mailto:#{CGI.escapeHTML(c.author.email)}\">#{CGI.escapeHTML(c.author.name)}</a> on #{c.authored_date.strftime("%b %d, %H:%M")}</span></div></div>"
44
+ end
45
+ end
46
+ else
47
+ message = "Branch #{source.head} was deployed to #{host}. Previously deployed branch was #{current_branch}."
48
+ end
49
+ message
50
+ end
51
+ end
52
+
53
+ before "deploy", "flowdock:trigger_notification"
54
+ before "flowdock:notify_deploy_finished", "flowdock:set_flowdock_api"
55
+ after "deploy", "flowdock:notify_deploy_finished"
56
+ end
@@ -0,0 +1,3 @@
1
+ module Flowdock
2
+ GEM_VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,134 @@
1
+ require 'spec_helper'
2
+
3
+ describe Flowdock do
4
+ describe "with initializing flow" do
5
+ it "should succeed with correct token and source" do
6
+ lambda {
7
+ @flow = Flowdock::Flow.new(:api_token => "test", :source => "myapp")
8
+ }.should_not raise_error
9
+ end
10
+
11
+ it "should succeed with correct token, source and sender information" do
12
+ lambda {
13
+ @flow = Flowdock::Flow.new(:api_token => "test", :source => "myapp",
14
+ :from => {:name => "test", :address => "invalid@nodeta.fi"})
15
+ }.should_not raise_error
16
+ end
17
+
18
+ it "should succeed with correct token, sender information, source and project" do
19
+ lambda {
20
+ @flow = Flowdock::Flow.new(:api_token => "test", :source => "myapp", :project => "myproject",
21
+ :from => {:name => "test", :address => "invalid@nodeta.fi"})
22
+ }.should_not raise_error
23
+ end
24
+
25
+ it "should fail without token" do
26
+ lambda {
27
+ @flow = Flowdock::Flow.new(:api_token => "", :source => "myapp")
28
+ }.should raise_error(Flowdock::Flow::InvalidParameterError)
29
+ end
30
+
31
+ it "should fail without source" do
32
+ lambda {
33
+ @flow = Flowdock::Flow.new(:api_token => "test", :source => "")
34
+ }.should raise_error(Flowdock::Flow::InvalidParameterError)
35
+ end
36
+
37
+ it "should fail when source is not alphanumeric" do
38
+ lambda {
39
+ @flow = Flowdock::Flow.new(:api_token => "test", :source => "$foobar")
40
+ }.should raise_error(Flowdock::Flow::InvalidParameterError)
41
+ end
42
+
43
+ it "should fail when project is not alphanumeric" do
44
+ lambda {
45
+ @flow = Flowdock::Flow.new(:api_token => "test", :source => "myapp", :project => "$foobar")
46
+ }.should raise_error(Flowdock::Flow::InvalidParameterError)
47
+ end
48
+ end
49
+
50
+ describe "with sending messages" do
51
+ before(:each) do
52
+ @token = "test"
53
+ @flow = Flowdock::Flow.new(:api_token => @token, :source => "myapp", :project => "myproject",
54
+ :from => {:name => "Eric Example", :address => "eric@example.com"})
55
+ @example_content = "<h1>Hello</h1>\n<p>Let's rock and roll!</p>"
56
+ end
57
+
58
+ it "should not send without subject" do
59
+ lambda {
60
+ @flow.send_message(:subject => "", :content => "Test")
61
+ }.should raise_error(Flowdock::Flow::InvalidParameterError)
62
+ end
63
+
64
+ it "should not send without content" do
65
+ lambda {
66
+ @flow.send_message(:subject => "Test", :content => "")
67
+ }.should raise_error(Flowdock::Flow::InvalidParameterError)
68
+ end
69
+
70
+ it "should not send without sender information" do
71
+ @flow = Flowdock::Flow.new(:api_token => @token, :source => "myapp")
72
+ lambda {
73
+ @flow.send_message(:subject => "Test", :content => @example_content)
74
+ }.should raise_error(Flowdock::Flow::InvalidParameterError)
75
+ end
76
+
77
+ it "should send with valid parameters and return true" do
78
+ lambda {
79
+ stub_request(:post, "#{Flowdock::FLOWDOCK_API_URL}/#{@token}").
80
+ with(:body => {
81
+ :source => "myapp",
82
+ :project => "myproject",
83
+ :format => "html",
84
+ :from_name => "Eric Example",
85
+ :from_address => "eric@example.com",
86
+ :subject => "Hello World",
87
+ :content => @example_content,
88
+ :tags => "cool,stuff"
89
+ }).
90
+ to_return(:body => "", :status => 200)
91
+
92
+ @flow.send_message(:subject => "Hello World", :content => @example_content, :tags => ["cool", "stuff"]).should be_true
93
+ }.should_not raise_error
94
+ end
95
+
96
+ it "should allow overriding sender information per message" do
97
+ lambda {
98
+ stub_request(:post, "#{Flowdock::FLOWDOCK_API_URL}/#{@token}").
99
+ with(:body => {
100
+ :source => "myapp",
101
+ :project => "myproject",
102
+ :format => "html",
103
+ :from_name => "Test",
104
+ :from_address => "invalid@nodeta.fi",
105
+ :subject => "Hello World",
106
+ :content => @example_content,
107
+ :tags => "cool,stuff"
108
+ }).
109
+ to_return(:body => "", :status => 200)
110
+
111
+ @flow.send_message(:subject => "Hello World", :content => @example_content, :tags => ["cool", "stuff"],
112
+ :from => {:name => "Test", :address => "invalid@nodeta.fi"}).should be_true
113
+ }.should_not raise_error
114
+ end
115
+
116
+ it "should raise error if backend returns anything but 200 OK" do
117
+ lambda {
118
+ stub_request(:post, "#{Flowdock::FLOWDOCK_API_URL}/#{@token}").
119
+ with(:body => {
120
+ :source => "myapp",
121
+ :project => "myproject",
122
+ :format => "html",
123
+ :from_name => "Eric Example",
124
+ :from_address => "eric@example.com",
125
+ :subject => "Hello World",
126
+ :content => @example_content
127
+ }).
128
+ to_return(:body => "Internal Server Error", :status => 500)
129
+
130
+ @flow.send_message(:subject => "Hello World", :content => @example_content).should be_false
131
+ }.should raise_error(Flowdock::Flow::ApiError)
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'webmock/rspec'
4
+
5
+ require 'flowdock'
6
+
7
+ RSpec.configure do |config|
8
+ # some (optional) config here
9
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flowdock
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - anttipitkanen
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-11 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: httparty
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 19
29
+ segments:
30
+ - 0
31
+ - 7
32
+ - 8
33
+ version: 0.7.8
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: webmock
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ hash: 15
59
+ segments:
60
+ - 1
61
+ - 6
62
+ - 0
63
+ version: 1.6.0
64
+ type: :development
65
+ version_requirements: *id003
66
+ description:
67
+ email:
68
+ - team@flowdock.com
69
+ executables: []
70
+
71
+ extensions: []
72
+
73
+ extra_rdoc_files: []
74
+
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - MIT-LICENSE
81
+ - README
82
+ - Rakefile
83
+ - flowdock.gemspec
84
+ - lib/flowdock.rb
85
+ - lib/flowdock/capistrano.rb
86
+ - lib/flowdock/version.rb
87
+ - spec/flowdock_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: https://www.flowdock.com/api
90
+ licenses: []
91
+
92
+ post_install_message:
93
+ rdoc_options: []
94
+
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ requirements: []
116
+
117
+ rubyforge_project: flowdock
118
+ rubygems_version: 1.8.5
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Ruby Gem for using Flowdock's API.
122
+ test_files:
123
+ - spec/flowdock_spec.rb
124
+ - spec/spec_helper.rb