appboard 1.0.5 → 1.0.6

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.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