geckoboard-push 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,70 @@
1
+ = geckoboard-push
2
+
3
+ * http://github.com/kickcode/geckoboard-push
4
+
5
+ == DESCRIPTION:
6
+
7
+ This is a Ruby library allowing you to push updates to Geckoboard widgets.
8
+
9
+ == FEATURES:
10
+
11
+ Exposes a Geckoboard::Push class allowing updates for the following widget types:
12
+
13
+ * number and secondary value
14
+ * text
15
+ * RAG
16
+ * line chart
17
+ * pie chart
18
+ * geckometer
19
+ * funnel chart
20
+
21
+ == SYNOPSIS:
22
+
23
+ Simply add to your Gemfile as follows:
24
+
25
+ gem 'geckoboard-push'
26
+
27
+ Then run "bundle install" and once installed, you need to configure the API key for your Geckoboard account:
28
+
29
+ Geckoboard::Push.api_key = "my_api_key"
30
+
31
+ Once that's done, you can push updates to widgets as so:
32
+
33
+ Geckoboard::Push.new("my_widget_key").number_and_secondary_value(100, 10)
34
+
35
+ == REQUIREMENTS:
36
+
37
+ geckoboard-push depends upon httparty.
38
+
39
+ == INSTALL:
40
+
41
+ It's best to add it to the Gemfile for your app, but if needed you can install the gem manually:
42
+
43
+ gem install geckoboard-push
44
+
45
+ == CONTRIBUTORS:
46
+
47
+ Elliott Draper
48
+
49
+ == LICENSE:
50
+
51
+ Copyright 2011 Elliott Draper <el@kickcode.com>
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining
54
+ a copy of this software and associated documentation files (the
55
+ "Software"), to deal in the Software without restriction, including
56
+ without limitation the rights to use, copy, modify, merge, publish,
57
+ distribute, sublicense, and/or sell copies of the Software, and to
58
+ permit persons to whom the Software is furnished to do so, subject to
59
+ the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
67
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
68
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
69
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
70
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), "geckoboard", "push")
@@ -0,0 +1,97 @@
1
+ gem 'httparty'
2
+ require 'httparty'
3
+ require 'json'
4
+
5
+ module Geckoboard
6
+ class Push
7
+ class << self
8
+ # API configuration
9
+ attr_accessor :api_key
10
+ attr_accessor :api_version
11
+ end
12
+
13
+ # Custom error type for handling API errors
14
+ class Error < Exception; end
15
+
16
+ include HTTParty
17
+ base_uri 'https://push.geckoboard.com'
18
+
19
+ # Initializes the push object for a specific widget
20
+ def initialize(widget_key)
21
+ @widget_key = widget_key
22
+ end
23
+
24
+ # Makes a call to Geckoboard to push data to the current widget
25
+ def push(data)
26
+ raise Geckoboard::Push::Error.new("Api key not configured.") if Geckoboard::Push.api_key.nil? || Geckoboard::Push.api_key.empty?
27
+ result = JSON.parse(self.class.post("/#{Geckoboard::Push.api_version || 'v1'}/send/#{@widget_key}", {:body => {:api_key => Geckoboard::Push.api_key, :data => data}.to_json}))
28
+ raise Geckoboard::Push::Error.new(result["error"]) unless result["success"]
29
+ result["success"]
30
+ end
31
+
32
+ # Value and previous value should be numeric values
33
+ def number_and_secondary_value(value, previous_value)
34
+ self.push(:item => [{:text => "", :value => value}, {:text => "", :value => previous_value}])
35
+ end
36
+
37
+ # Items should be an array of hashes, each hash containing:
38
+ # - text
39
+ # - type (should be either :alert, or :info, optional)
40
+ def text(items)
41
+ data = items.collect do |item|
42
+ type = case item[:type]
43
+ when :alert
44
+ 1
45
+ when :info
46
+ 2
47
+ else
48
+ 0
49
+ end
50
+ {:text => item[:text], :type => type}
51
+ end
52
+ self.push(:item => data)
53
+ end
54
+
55
+ # Red, amber and green should be values
56
+ def rag(red, amber, green)
57
+ self.push(:item => [{:value => red}, {:value => amber}, {:value => green}])
58
+ end
59
+
60
+ # Values should be an array of numeric values
61
+ # Colour, x_axis and y_axis are optional settings
62
+ def line(values, colour = nil, x_axis = nil, y_axis = nil)
63
+ self.push(:item => values, :settings => {:axisx => x_axis, :axisy => y_axis, :colour => colour})
64
+ end
65
+
66
+ # Items should be an array of hashes, each hash containing:
67
+ # - value (numeric value)
68
+ # - label (optional)
69
+ # - colour (optional)
70
+ def pie(items)
71
+ data = items.collect do |item|
72
+ {:value => item[:value], :label => item[:label], :colour => item[:colour]}
73
+ end
74
+ self.push(:item => data)
75
+ end
76
+
77
+ # Value, min and max should be numeric values
78
+ def geckometer(value, min, max)
79
+ self.push(:item => value, :min => {:value => min}, :max => {:value => max})
80
+ end
81
+
82
+ # Items should be an array of hashes, each hash containing:
83
+ # - value (numeric value)
84
+ # - label (optional)
85
+ # Reverse defaults to false, and when true flips the colours on the widget
86
+ # Hide percentage defaults to false, and when true hides the percentage value on the widget
87
+ def funnel(items, reverse = false, hide_percentage = false)
88
+ data = items.collect do |item|
89
+ {:value => item[:value], :label => item[:label]}
90
+ end
91
+ opts = {:item => data}
92
+ opts[:type] = "reverse" if reverse
93
+ opts[:percentage] = "hide" if hide_percentage
94
+ self.push(opts)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,77 @@
1
+ require 'test/unit'
2
+ gem 'fakeweb'
3
+ require 'fakeweb'
4
+ gem 'mocha'
5
+ require 'mocha'
6
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "lib", "geckoboard", "push")
7
+
8
+ class PushTest < Test::Unit::TestCase
9
+ def setup
10
+ FakeWeb.allow_net_connect = false
11
+ Geckoboard::Push.api_key = "12345"
12
+ @push = Geckoboard::Push.new("54321")
13
+ end
14
+
15
+ def test_with_no_api_key
16
+ Geckoboard::Push.api_key = nil
17
+ assert_raise Geckoboard::Push::Error do
18
+ @push.number_and_secondary_value(100, 10)
19
+ end
20
+ end
21
+
22
+ def test_invalid_key
23
+ Geckoboard::Push.api_key = "invalid"
24
+ response = Net::HTTPOK.new("1.1", 200, "OK")
25
+ response.instance_variable_set(:@body, '{"success":false,"error":"Api key has wrong format. "}')
26
+ response.instance_variable_set(:@read, true)
27
+ Net::HTTP.any_instance.expects(:request).returns(response)
28
+ assert_raise Geckoboard::Push::Error do
29
+ @push.number_and_secondary_value(100, 10)
30
+ end
31
+ end
32
+
33
+ def test_number_and_secondary_value
34
+ expect_http_request({"api_key" => "12345", "data" => {"item" => [{"text" => "", "value" => 100}, {"text" => "", "value" => 10}]}}.to_json)
35
+ assert_equal true, @push.number_and_secondary_value(100, 10)
36
+ end
37
+
38
+ def test_text
39
+ expect_http_request({"api_key" => "12345", "data" => {"item" => [{"text" => "Test1", "type" => 2}, {"text" => "Test2", "type" => 1}]}}.to_json)
40
+ assert_equal true, @push.text([{:type => :info, :text => "Test1"}, {:type => :alert, :text => "Test2"}])
41
+ end
42
+
43
+ def test_rag
44
+ expect_http_request({"api_key" => "12345", "data" => {"item" => [{"value" => 1}, {"value" => 2}, {"value" => 3}]}}.to_json)
45
+ assert_equal true, @push.rag(1,2,3)
46
+ end
47
+
48
+ def test_line
49
+ expect_http_request({"api_key" => "12345", "data" => {"item" => [1,2,3], "settings" => {"axisx" => "x axis", "axisy" => "y axis", "colour" => "ff9900"}}}.to_json)
50
+ assert_equal true, @push.line([1,2,3], "ff9900", "x axis", "y axis")
51
+ end
52
+
53
+ def test_pie
54
+ expect_http_request({"api_key" => "12345", "data" => {"item" => [{"value" => 1, "label" => "Test1", "colour" => "ff9900"}, {"value" => 2, "label" => "Test2", "colour" => "ff0099"}]}}.to_json)
55
+ assert_equal true, @push.pie([{:value => 1, :label => "Test1", :colour => "ff9900"}, {:value => 2, :label => "Test2", :colour => "ff0099"}])
56
+ end
57
+
58
+ def test_geckometer
59
+ expect_http_request({"api_key" => "12345", "data" => {"item" => 100, "min" => {"value" => 50}, "max" => {"value" => 200}}}.to_json)
60
+ assert_equal true, @push.geckometer(100, 50, 200)
61
+ end
62
+
63
+ def test_funnel
64
+ expect_http_request({"api_key" => "12345", "data" => {"item" => [{"value" => 5, "label" => "Test1"}, {"value" => 10, "label" => "Test2"}], "type" => "reverse", "percentage" => "hide"}}.to_json)
65
+ assert_equal true, @push.funnel([{:label => "Test1", :value => 5}, {:label => "Test2", :value => 10}], true, true)
66
+ end
67
+
68
+ def expect_http_request(json)
69
+ response = Net::HTTPOK.new("1.1", 200, "OK")
70
+ response.instance_variable_set(:@body, '{"success":true}')
71
+ response.instance_variable_set(:@read, true)
72
+ Net::HTTP.any_instance.expects(:request).with do |request|
73
+ assert_equal json, request.body
74
+ request.path == "/v1/send/54321" && request.method == "POST" && request.body == json
75
+ end.returns(response)
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geckoboard-push
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Elliott Draper
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-12-08 00:00:00 +00:00
18
+ default_executable:
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
+ segments:
29
+ - 0
30
+ - 8
31
+ - 1
32
+ version: 0.8.1
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: fakeweb
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 3
46
+ - 0
47
+ version: 1.3.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: mocha
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ - 10
61
+ - 0
62
+ version: 0.10.0
63
+ type: :development
64
+ version_requirements: *id003
65
+ description:
66
+ email: el@kickcode.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - README.rdoc
73
+ files:
74
+ - README.rdoc
75
+ - test/geckoboard/push_test.rb
76
+ - lib/geckoboard/push.rb
77
+ - lib/geckoboard-push.rb
78
+ has_rdoc: true
79
+ homepage: http://docs.geckoboard.com/api/push.html
80
+ licenses: []
81
+
82
+ post_install_message:
83
+ rdoc_options:
84
+ - --main
85
+ - README.rdoc
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.3.7
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Ruby library for pushing widget updates to Geckoboard.
111
+ test_files: []
112
+