flowdock 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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