appboard 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,7 +12,7 @@ Further reading:
12
12
  * [Demo Dashboard](http://appboard.me/demo)
13
13
  * [Follow us on Twitter](http://twitter.com/appboard)
14
14
 
15
- NOTE: We are currently in private beta. Please let me know (eugene@appboard.me) if you'd like an invite.
15
+ NOTE: We are currently in private beta. Please let me know (dev@appboard.me) if you'd like an invite.
16
16
 
17
17
 
18
18
  Gem Installation
@@ -39,16 +39,21 @@ or you could define API key in call block:
39
39
  require 'rubygems'
40
40
  require 'appboard'
41
41
 
42
- Appboard.push {
42
+ Appboard.setup {
43
43
  apiKey "abcd1234"
44
44
 
45
- widget('some name here') {
46
- uid "abcd1234"
45
+ ...
46
+ }
47
+
48
+ or,
47
49
 
48
- data do
49
- # Data is here
50
- end
51
- }
50
+ require 'rubygems'
51
+ require 'appboard'
52
+
53
+ Appboard.push {
54
+ apiKey "abcd1234"
55
+
56
+ ...
52
57
  }
53
58
 
54
59
 
@@ -69,28 +74,43 @@ Usage
69
74
 
70
75
  There is several options how you could use API:
71
76
 
72
- *publish each widget separately*
77
+
78
+ *Option 1.* Setup new dashboard and pushing data to widget:
79
+
73
80
 
74
81
  require 'rubygems'
75
82
  require 'appboard'
83
+
84
+ Appboard.setup {
85
+ apiKey "zxcv1234"
76
86
 
77
- Appboard.settings = { :apiKey => "zxcv1234" }
87
+ widget('My Clock') {
88
+ type "clock"
89
+ size "1x1"
90
+ }
91
+
92
+ widget('First Indicator') {
93
+ type "singlenumber"
94
+ size "1x1"
95
+ }
96
+ }
78
97
 
79
- widget = Appboard.widget('some name here') {
80
- uid "abcd1234"
98
+ Appboard.widget('First Indicator') {
99
+ data do
100
+ {
101
+ :current => 10
102
+ }
103
+ end
104
+ }
81
105
 
82
- data do
83
- # Data is here
84
- end
85
- }
106
+ puts Appboard.widget('First Indicator').uid # prints widget uid
86
107
 
87
- response = widget.push # push data to Dashboard on appboard.me
88
108
 
89
- response.success? # => true
90
- response.code # => 200
109
+ After seting up dashboard configuration is stored in Appboard class, and widget could be easily accessed by name.
110
+ For already configured dashboards you could push your data by widget uid.
91
111
 
92
112
 
93
- *publish few widgets at once*
113
+ *Option 2.* Pushing data to widget by widget UID
94
114
 
95
115
  require 'rubygems'
96
116
  require 'appboard'
@@ -99,24 +119,23 @@ There is several options how you could use API:
99
119
  apiKey "zxcv1234"
100
120
 
101
121
  widget('widget1') {
102
- uid "abcd1234"
122
+ uid "abcd1234"
123
+
124
+ data do
125
+ # Data is here
126
+ end
127
+ }
103
128
 
104
- data do
105
- # Data is here
106
- end
107
- }
108
129
  widget('widget2') {
109
- uid "poiu4321"
130
+ uid "poiu4321"
110
131
 
111
- data do
112
- # Data is here
113
- end
114
- }
132
+ data do
133
+ # Data is here
134
+ end
135
+ }
115
136
  }
116
137
 
117
138
 
118
- widget = Appboard.widget('widget1') # after you could access widget by name
119
-
120
139
 
121
140
  NOTE: Don't forget to specify your apiKey and widget identifier.
122
141
 
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+ require 'appboard'
3
+
4
+ #
5
+ # Seting up new dashboard.
6
+ # Don't forget to specify your apiKey and widget identifier.
7
+ #
8
+ Appboard.settings = { :apiKey => 'wOUpOJeOozcgPdZa', :debug => true }
9
+
10
+ Appboard.setup() {
11
+ dashboard('my dashboard1') {
12
+ widget('clock') {
13
+ type "clock"
14
+ size "1x1"
15
+ }
16
+
17
+ widget('my indicator 1') {
18
+ type "singlenumber"
19
+ size "1x1"
20
+ }
21
+
22
+ widget('my indicator 2') {
23
+ type "singlenumber"
24
+ size "1x1"
25
+ }
26
+ }
27
+ }
28
+
29
+
30
+ Appboard.widget('my indicator 1') {
31
+ data do
32
+ {
33
+ :current => 10
34
+ }
35
+ end
36
+ }
37
+
38
+ Appboard.widget('my indicator 2') {
39
+ data do
40
+ {
41
+ :current => 20
42
+ }
43
+ end
44
+ }
@@ -7,8 +7,9 @@ module Appboard
7
7
  {
8
8
  :url => url,
9
9
  :apiKey => apiKey,
10
- :version => 'v1',
11
- :logging => false
10
+ :version => 'v1',
11
+ :logging => false,
12
+ :debug => false
12
13
  }
13
14
  rescue Object => e
14
15
  raise "invalid APPBOARD_API_URL: (#{url.inspect}) #{e.class} -> #{e.message}"
@@ -0,0 +1,168 @@
1
+ module Appboard
2
+ # Dashboard configuration
3
+ class DashboardSetup
4
+ # Defines dashboard
5
+ class Dashboard
6
+ def initialize(name, &block)
7
+ @widgets = {}
8
+ @width = 5
9
+ @name = name
10
+
11
+ instance_eval(&block)
12
+ end
13
+
14
+ def widgets
15
+ @widgets
16
+ end
17
+
18
+ def name
19
+ @name
20
+ end
21
+
22
+ def width(value = nil)
23
+ @width = value unless value.nil?
24
+ @width
25
+ end
26
+
27
+ def uid(value = nil)
28
+ @uid = value unless value.nil?
29
+ @uid
30
+ end
31
+
32
+ # Define a widget. May be called inside push loop or separately
33
+ #
34
+ # widget('name') {
35
+ # type "..."
36
+ # size "..."
37
+ # }
38
+ #
39
+ def widget(widget_name)
40
+ if block_given?
41
+ block = Proc.new
42
+ widget = Widget.new(widget_name, &block)
43
+
44
+ raise ArgumentError, "Widget with name '#{widget_name.to_s}' is already defined" if @widgets[widget_name.to_s]
45
+
46
+ @widgets[widget_name.to_s] = widget
47
+ else
48
+ widget = @widgets[widget_name.to_s]
49
+
50
+ raise ArgumentError, "Widget is not defined, to define new widget you must supply a block as the last argument" if widget.nil?
51
+ end
52
+ widget
53
+ end
54
+
55
+ def get_widgets
56
+ widgets = []
57
+
58
+ @widgets.each do |name, widget|
59
+ widgets << widget
60
+ end
61
+
62
+ widgets
63
+ end
64
+
65
+ def has(name)
66
+ true if @widgets[name]
67
+ end
68
+
69
+ def to_json(*a)
70
+ widgets = []
71
+
72
+ @widgets.each do |name, widget|
73
+ widgets << widget
74
+ end
75
+
76
+ {
77
+ :name => @name,
78
+ :width => @width,
79
+ :widgets => widgets
80
+ }.to_json(*a)
81
+ end
82
+ end
83
+
84
+ # Defines widget
85
+ class Widget
86
+ def initialize(name, &block)
87
+ @name = name
88
+ instance_eval(&block)
89
+ end
90
+
91
+ def name
92
+ @name
93
+ end
94
+
95
+ def uid(value = nil)
96
+ @uid = value unless value.nil?
97
+ @uid
98
+ end
99
+
100
+ def type(value = nil)
101
+ @type = value unless value.nil?
102
+ @type
103
+ end
104
+
105
+ def size(value = nil)
106
+ @size = value unless value.nil?
107
+ @size
108
+ end
109
+
110
+ def data(&block)
111
+ @data = block if block_given?
112
+ @data
113
+ end
114
+
115
+ def get_data
116
+ @data.call()
117
+ end
118
+
119
+ def to_json(*a)
120
+ {
121
+ :name => @name,
122
+ :type => @type,
123
+ :size => @size
124
+ }.to_json(*a)
125
+ end
126
+ end
127
+
128
+ # Define API key
129
+ def apiKey(value = nil)
130
+ @apiKey = value unless value.nil?
131
+ @apiKey
132
+ end
133
+
134
+ # Define a dashboard. May be called inside setup loop or separately
135
+ #
136
+ # dashboard('name') {
137
+ # width 5
138
+ #
139
+ # widget('widget 1') {
140
+ # type "..."
141
+ # size "..."
142
+ # }
143
+ #
144
+ # widget('widget 2') {
145
+ # # widget configuration is here
146
+ # }
147
+ # }
148
+ #
149
+ def dashboard(name)
150
+ block = Proc.new
151
+ @dashboard = Dashboard.new(name, &block)
152
+
153
+ self
154
+ end
155
+
156
+ def get_dashboard
157
+ @dashboard
158
+ end
159
+
160
+ def get_widget(name)
161
+ @dashboard.widget(name)
162
+ end
163
+
164
+ def has_widget(name)
165
+ @dashboard.has(name)
166
+ end
167
+ end
168
+ end
@@ -4,19 +4,19 @@ module Appboard
4
4
  # Rescuing Appboard::Error (or RuntimeError) will get all custom exceptions.
5
5
  # If your dashboard is correctly configured and data is specified correctly, you should never expect to see any of these.
6
6
  class Error < RuntimeError
7
-
7
+
8
8
  # BadRequest is raised when a data for widget is specified incorrectly. Message usualy contains reference to documentation.
9
9
  class BadRequest < Error
10
10
  end
11
-
11
+
12
12
  # NotFound is raised when a apiKey, dashboard or widget is not found.
13
13
  class NotFound < Error
14
14
  end
15
-
15
+
16
16
  # ThrottleLimit is raised when throttle limit is reached (more details you could fine here - http://appboard.me/docs/restapi)
17
17
  class ThrottleLimit < Error
18
18
  end
19
-
19
+
20
20
  # MissingConfiguration is raised when we're trying to run send data to widget or dashboard that needs configuration.
21
21
  class MissingConfiguration < Error
22
22
  end
@@ -1,32 +1,72 @@
1
1
  module Appboard
2
2
  module RestAPI
3
-
3
+
4
4
  def default_headers
5
5
  {
6
6
  :content_type => :json,
7
7
  :accept => :json
8
8
  }
9
9
  end
10
+
11
+ def send_data(url, payload)
12
+ json = JSON.generate(payload)
13
+
14
+ begin
15
+ RestClient.put url, json, default_headers
16
+ rescue RestClient::Exception => e
17
+ message = ""
18
+
19
+ begin
20
+ message = JSON.parse(e.response.body)["message"] if e.response.body
21
+ rescue JSON::ParserError => pe
22
+ # ignore
23
+ end
24
+
25
+ raise Error::BadRequest, message if e.http_code == 400
26
+ raise Error::NotFound, message if e.http_code == 404
27
+ raise Error::ThrottleLimit, message if e.http_code == 503
28
+ raise e
29
+ end
30
+ end
31
+
32
+ def send_setup(url, config)
33
+ success = false
34
+ json = config.get_dashboard.to_json
10
35
 
11
- def put(url, payload)
12
- json = JSON.generate(payload)
13
-
14
- begin
15
- RestClient.put url, json, default_headers
16
- rescue RestClient::Exception => e
17
- message = ""
18
-
19
- begin
20
- message = JSON.parse(e.response.body)["message"] if e.response.body
21
- rescue JSON::ParserError => pe
22
- # ignore
23
- end
24
-
25
- raise Error::BadRequest, message if e.http_code == 400
26
- raise Error::NotFound, message if e.http_code == 404
27
- raise Error::ThrottleLimit, message if e.http_code == 503
28
- raise e
29
- end
36
+ begin
37
+ response = RestClient.put url, json, default_headers
38
+
39
+ begin
40
+ dr = JSON.parse(response.body) if response.body
41
+
42
+ # update widgets with data in response
43
+ dr["widgets"].each do |rw|
44
+ widget = config.get_dashboard.widget(rw["name"])
45
+ uid = rw["uid"]
46
+
47
+ widget.uid(uid)
48
+ end
49
+ rescue JSON::ParserError => pe
50
+ raise Error::MissingConfiguration
51
+ end
52
+
53
+ success = true if response.code == 200
54
+ rescue RestClient::Exception => e
55
+ message = ""
56
+
57
+ begin
58
+ message = JSON.parse(e.response.body)["message"] if e.response.body
59
+ rescue JSON::ParserError => pe
60
+ # ignore
61
+ end
62
+
63
+ raise Error::BadRequest, message if e.http_code == 400
64
+ raise Error::NotFound, message if e.http_code == 404
65
+ raise Error::ThrottleLimit, message if e.http_code == 503
66
+ raise e
67
+ end
68
+
69
+ success
30
70
  end
31
71
  end
32
72
  end
@@ -2,8 +2,8 @@ module Appboard #:nodoc:
2
2
  module Version #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 0
5
- TINY = 5
6
-
5
+ TINY = 6
6
+
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
9
9
  end
@@ -1,32 +1,37 @@
1
1
  module Appboard
2
- # Defines widget
3
- class Widget
4
- def initialize(name, &block)
5
- @name = name
6
- instance_eval(&block)
7
- end
8
-
9
- def name
10
- @name
11
- end
12
-
13
- def uid(value = nil)
14
- @uid = value unless value.nil?
15
- @uid
16
- end
17
-
18
- def type(value = nil)
19
- @type = value unless value.nil?
20
- @type
21
- end
22
-
23
- def data(&block)
24
- @data = block if block_given?
25
- @data
26
- end
27
-
28
- def get_data
29
- @data.call()
30
- end
31
- end
2
+ # Defines widget
3
+ class Widget
4
+ def initialize(name, &block)
5
+ @name = name
6
+ instance_eval(&block)
7
+ end
8
+
9
+ def name
10
+ @name
11
+ end
12
+
13
+ def uid(value = nil)
14
+ @uid = value unless value.nil?
15
+ @uid
16
+ end
17
+
18
+ def type(value = nil)
19
+ @uid = value unless value.nil?
20
+ @type
21
+ end
22
+
23
+ def size(value = nil)
24
+ @size = value unless value.nil?
25
+ @size
26
+ end
27
+
28
+ def data(&block)
29
+ @data = block if block_given?
30
+ @data
31
+ end
32
+
33
+ def get_data
34
+ @data.call()
35
+ end
36
+ end
32
37
  end
@@ -0,0 +1,64 @@
1
+ module Appboard
2
+ # Widget pusher
3
+ class WidgetPusher
4
+ # Defines widget
5
+ class Widget
6
+ def initialize(name, &block)
7
+ @name = name
8
+ instance_eval(&block)
9
+ end
10
+
11
+ def name
12
+ @name
13
+ end
14
+
15
+ def uid(value = nil)
16
+ @uid = value unless value.nil?
17
+ @uid
18
+ end
19
+
20
+ def data(&block)
21
+ @data = block if block_given?
22
+ @data
23
+ end
24
+
25
+ def get_data
26
+ @data.call()
27
+ end
28
+ end
29
+
30
+ # Define API key
31
+ def apiKey(value = nil)
32
+ @apiKey = value unless value.nil?
33
+ @apiKey
34
+ end
35
+
36
+ # Define a widget. May be called inside push loop or separately
37
+ #
38
+ # widget('name') {
39
+ # uid "..."
40
+ #
41
+ # data do
42
+ # # Data is here
43
+ # end
44
+ # }
45
+ #
46
+ def widget(widget_name)
47
+ if block_given?
48
+ block = Proc.new
49
+ widget = Widget.new(widget_name, &block)
50
+
51
+ raise ArgumentError, "Widget 'uid' is not defined" if widget.uid.nil?
52
+
53
+ (@widgets ||= []) << widget
54
+ self
55
+ else
56
+ raise ArgumentError, "Widget is not defined, to define new widget you must supply a block as the last argument" if widget.nil?
57
+ end
58
+ end
59
+
60
+ def get_widgets
61
+ @widgets
62
+ end
63
+ end
64
+ end
data/lib/appboard.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'uri'
1
+ require 'uri'
2
2
  require 'json' unless defined? ActiveSupport::JSON
3
3
  require 'restclient'
4
4
 
@@ -8,26 +8,83 @@ require 'appboard/version'
8
8
  require 'appboard/rest_api'
9
9
  require 'appboard/bootstrap'
10
10
  require 'appboard/widget'
11
+ require 'appboard/widgetpusher'
12
+ require 'appboard/dashboardsetup'
11
13
  require 'appboard/exceptions'
12
14
 
13
15
  module Appboard
14
16
 
15
17
  class << self
16
- @@widgets = {}
18
+ @@dashboards = {}
17
19
 
18
20
  include Appboard::Bootstrap
19
21
  include Appboard::RestAPI
20
22
 
21
23
  # Define API key
22
24
  def apiKey(value = nil)
23
- @apiKey = value unless value.nil?
24
- @apiKey
25
- end
25
+ @apiKey = value unless value.nil?
26
+ @apiKey
27
+ end
26
28
 
29
+ # Creates new or updates existing dashboard with defined widgets in block
30
+ #
31
+ # appboard.setup {
32
+ # dashboard('name') {
33
+ # width 5
34
+ #
35
+ # widget('widget 1') {
36
+ # type "..."
37
+ # size "..."
38
+ # }
39
+ #
40
+ # widget('widget 2') {
41
+ # # Widget configuration is here
42
+ # }
43
+ # }
44
+ # }
45
+ #
46
+ # == Options
47
+ # * :apiKey => 'API key'
48
+ # * :logging => false
49
+ # * :debug => false
50
+ #
51
+ # Refer to default config below for how to set these as defaults
52
+ #
53
+ def setup(options = {}, &block)
54
+ config = settings.update(options)
55
+
56
+ if block_given?
57
+ ds = DashboardSetup.new.instance_eval(&block)
58
+
59
+ apiKey = ds.apiKey || config[:apiKey]
60
+ url = "#{config[:url]}/#{config[:version]}/#{apiKey}/setup"
61
+
62
+ result = send_setup url, ds
63
+
64
+ if result && config[:debug]
65
+ puts "Dashboard with name '#{ds.get_dashboard.name}' has been set, and following widgets have been added:"
66
+
67
+ ds.get_dashboard.get_widgets.each do |widget|
68
+ puts " * #{widget.name}, with uid '#{widget.uid}'"
69
+ end
70
+ end
71
+
72
+ @@dashboards[ds.get_dashboard.name] = ds if result
73
+ else
74
+ raise ArgumentError, "Block is expected as argument for Appboard.setup()"
75
+ end
76
+ end
77
+
27
78
  # Push on dashboard all defined widgets in block
28
79
  #
29
80
  # appboard.push {
30
- # # Do stuff in here
81
+ # widget() {
82
+ # uid "..."
83
+ #
84
+ # data {
85
+ # # Data is here
86
+ # }
87
+ # }
31
88
  # }
32
89
  #
33
90
  # == Options
@@ -37,9 +94,20 @@ module Appboard
37
94
  # Refer to default config below for how to set these as defaults
38
95
  #
39
96
  def push(options = {}, &block)
40
- @config = settings.update(options)
41
-
42
- self.instance_eval(&block) if block_given?
97
+ config = settings.update(options)
98
+
99
+ if block_given?
100
+ pusher = WidgetPusher.new.instance_eval(&block)
101
+
102
+ pusher.get_widgets.each do |widget|
103
+ apiKey = pusher.apiKey || config[:apiKey]
104
+ url = "#{config[:url]}/#{config[:version]}/#{apiKey}/data/#{widget.uid}"
105
+
106
+ send_data url, widget.get_data
107
+ end
108
+ else
109
+ raise ArgumentError, "Block is expected as argument for Appboard.push()"
110
+ end
43
111
  end
44
112
 
45
113
  # Define a widget. May be called inside push loop or separately
@@ -47,37 +115,39 @@ module Appboard
47
115
  # widget('name') {
48
116
  # data {
49
117
  # # Data is here
50
- # }
118
+ # }
51
119
  # }
52
120
  #
53
121
  def widget(widget_name)
122
+ config = settings
123
+ dashboard = nil
124
+
125
+ @@dashboards.each do |name, db|
126
+ dashboard = db if db.has_widget(widget_name)
127
+ break if dashboard.nil?
128
+ end
129
+
130
+ raise ArgumentError, "Widget '#{widget_name}' is not defined, to use this method setup dashboard with Appboard.setup()" if dashboard.nil?
131
+
54
132
  if block_given?
55
133
  block = Proc.new
56
- widget = register_widget(widget_name, &block)
57
- send(widget)
134
+
135
+ apiKey = dashboard.apiKey || config[:apiKey]
136
+ uid = dashboard.get_widget(widget_name).uid
137
+ url = "#{config[:url]}/#{config[:version]}/#{apiKey}/data/#{uid}"
138
+
139
+ widget = Widget.new(widget_name, &block)
140
+ send_data url, widget.get_data
58
141
  else
59
- widget = @@widgets[widget_name.to_s]
60
-
61
- raise ArgumentError, "Widget is not defined, to define new widget you must supply a block as the last argument" if widget.nil?
62
- end
142
+ block = Proc.new {}
143
+
144
+ widget = Widget.new(widget_name, &block)
145
+ widget.uid(dashboard.get_widget(widget_name).uid)
146
+ end
147
+
63
148
  widget
64
149
  end
65
150
 
66
- def register_widget(widget_name, &block)
67
- widget = Widget.new(widget_name, &block)
68
-
69
- ((@@widgets[widget_name.to_s] ||= []) << widget).uniq!
70
- widget
71
- end
72
-
73
-
74
- def send(widget)
75
- url = "#{@config[:url]}/#{@config[:version]}/#{@apiKey}/data/#{widget.uid}"
76
-
77
- put url, widget.get_data
78
- end
79
-
80
-
81
151
  def handle_error(e)
82
152
  log.error "#{e.class}: #{e.message}"#, :exception => e
83
153
  e.backtrace.each do |line|
@@ -92,6 +162,5 @@ module Appboard
92
162
  def log=(log)
93
163
  @@log = log
94
164
  end
95
-
96
165
  end
97
166
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appboard
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 5
10
- version: 1.0.5
9
+ - 6
10
+ version: 1.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - appboard.me
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-15 00:00:00 -04:00
18
+ date: 2011-07-19 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -99,13 +99,16 @@ files:
99
99
  - examples/linechart.rb
100
100
  - examples/piechart.rb
101
101
  - examples/radialgauge.rb
102
+ - examples/setupdashboard.rb
102
103
  - examples/singlenumner.rb
103
104
  - lib/appboard.rb
104
105
  - lib/appboard/bootstrap.rb
106
+ - lib/appboard/dashboardsetup.rb
105
107
  - lib/appboard/exceptions.rb
106
108
  - lib/appboard/rest_api.rb
107
109
  - lib/appboard/version.rb
108
110
  - lib/appboard/widget.rb
111
+ - lib/appboard/widgetpusher.rb
109
112
  - LICENSE.txt
110
113
  has_rdoc: true
111
114
  homepage: https://github.com/appboard/appboard