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.
- data/README.rdoc +70 -0
- data/lib/geckoboard-push.rb +1 -0
- data/lib/geckoboard/push.rb +97 -0
- data/test/geckoboard/push_test.rb +77 -0
- metadata +112 -0
data/README.rdoc
ADDED
@@ -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
|
+
|