omf_web 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +168 -13
- data/bin/omf-web-basic +3 -3
- data/doc/index.md +205 -0
- data/example/NOT_WORKING/brooklyn/brooklyn_server.rb +2 -2
- data/example/NOT_WORKING/frisbee/data_sources/parse_log.rb +1 -1
- data/example/NOT_WORKING/frisbee/viz_server.rb +1 -1
- data/example/NOT_WORKING/gec12/gec12_demo_server.rb +1 -1
- data/example/NOT_WORKING/gec12/visualization.rb +2 -2
- data/example/NOT_WORKING/network/network_server.rb +2 -2
- data/example/NOT_WORKING/wimax/test.rb +2 -2
- data/example/NOT_WORKING/wimax/viz_server.rb +2 -2
- data/example/bridge/auth_basic.rb +75 -0
- data/example/bridge/config.ru +101 -0
- data/example/bridge/configure/configure_widget.rb +32 -0
- data/example/bridge/data_sources/sensor-sqlite.rb +28 -6
- data/example/bridge/data_sources/test31.sq3 +0 -0
- data/example/bridge/htdocs/{js/graph → graph/js}/bridge.js +2 -2
- data/example/bridge/htdocs/{js/graph → graph/js}/event_line_chart.js +7 -6
- data/example/bridge/htdocs/{js/graph → graph/js}/event_table.js +13 -5
- data/example/bridge/htdocs/template/login.html +23 -0
- data/example/bridge/viz_server.rb +3 -5
- data/example/bridge/widgets/configure.yaml +12 -0
- data/example/bridge/widgets/login.yaml +16 -0
- data/example/bridge/{overview.yaml → widgets/overview.yaml} +7 -4
- data/example/demo/data_sources/animals.rb +1 -1
- data/example/demo/data_sources/downloads.rb +1 -1
- data/example/demo/data_sources/generator.rb +1 -1
- data/example/demo/data_sources/histogram.rb +1 -1
- data/example/demo/data_sources/mobile_network.rb +4 -3
- data/example/demo/data_sources/movies.rb +1 -1
- data/example/demo/data_sources/network.rb +4 -3
- data/example/demo/data_sources/returns.rb +1 -1
- data/example/demo/data_sources/static_network.rb +4 -3
- data/example/demo/data_sources/walk.rb +1 -1
- data/example/demo/demo_viz_server.rb +1 -1
- data/example/demo/widgets/linked_graphs_tab.yaml +1 -1
- data/example/openflow-gec15/README.md +21 -0
- data/example/openflow-gec15/code_tab.yaml +36 -0
- data/example/openflow-gec15/dashboard_tab.yaml +72 -0
- data/example/openflow-gec15/doc/screenshot.png +0 -0
- data/example/openflow-gec15/exp_source.rb +104 -0
- data/example/openflow-gec15/of_viz_server.rb +63 -0
- data/example/openflow-gec15/openflow-demo.sq3 +0 -0
- data/example/openflow-gec15/raw_tab.yaml +37 -0
- data/example/openflow-gec15/repository/of-exp.rb +12 -0
- data/example/openflow-gec15/repository/sample.md +52 -0
- data/example/openflow-gec15/repository/trema-ctl6.rb +148 -0
- data/example/simple/README.md +2 -0
- data/example/simple/data_sources/gimi31.sq3 +0 -0
- data/example/simple/data_sources/ping_source.rb +56 -0
- data/example/simple/simple_viz_server.rb +39 -0
- data/example/simple/widgets/charts_tab.yaml +38 -0
- data/lib/omf-web/config.ru +31 -3
- data/lib/omf-web/data_source_proxy.rb +29 -26
- data/lib/omf-web/rack/session_authenticator.rb +93 -0
- data/lib/omf-web/rack/tab_mapper.rb +10 -5
- data/lib/omf-web/rack/websocket_handler.rb +17 -6
- data/lib/omf-web/theme/abstract_page.rb +1 -1
- data/lib/omf-web/theme/bright/flow_renderer.rb +2 -2
- data/lib/omf-web/theme/bright/layout_renderer.rb +15 -0
- data/lib/omf-web/theme/bright/mustache_renderer.rb +29 -0
- data/lib/omf-web/theme/bright/one_column_renderer.rb +2 -2
- data/lib/omf-web/theme/bright/page.rb +33 -8
- data/lib/omf-web/theme/bright/tabbed_renderer.rb +2 -3
- data/lib/omf-web/theme/bright/two_columns_renderer.rb +3 -4
- data/lib/omf-web/version.rb +1 -1
- data/lib/omf-web/widget/code_widget.rb +0 -7
- data/lib/omf-web/widget/layout/two_columns_layout.rb +3 -2
- data/lib/omf-web/widget/mustache_widget.rb +44 -0
- data/lib/omf-web/widget.rb +14 -1
- data/lib/omf_common/lobject.rb +6 -3
- data/omf_web.gemspec +3 -1
- data/share/htdocs/graph/js/abstract_nv_chart.js +14 -4
- data/share/htdocs/graph/js/abstract_widget.js +5 -4
- data/share/htdocs/graph/js/line_chart3.js +2 -0
- data/share/htdocs/graph/js/map2.js +3 -3
- data/share/htdocs/graph/js/network2.js +51 -19
- data/share/htdocs/graph/js/scatter_plot.js +6 -2
- data/share/htdocs/graph/js/table2.js +5 -2
- data/share/htdocs/js/data_source2.js +40 -8
- data/share/htdocs/js/mustache.js +29 -0
- data/share/htdocs/theme/abstract/abstract.js +10 -3
- data/share/htdocs/vendor/mustache-0.7.0/CHANGES +21 -0
- data/share/htdocs/vendor/mustache-0.7.0/LICENSE +10 -0
- data/share/htdocs/vendor/mustache-0.7.0/README.md +374 -0
- data/share/htdocs/vendor/mustache-0.7.0/jquery.mustache.js +635 -0
- data/share/htdocs/vendor/mustache-0.7.0/mustache.js +612 -0
- data/share/htdocs/vendor/nv_d3/js/nv.d3.js +9 -1
- data/share/htdocs/vendor/raphael-2.1.0/raphael.js +5815 -0
- metadata +74 -9
- data/DESIGN_NOTES.txt +0 -56
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
|
3
3
|
require 'omf_common/lobject'
|
4
|
-
require '
|
4
|
+
require 'omf_oml/network'
|
5
5
|
|
6
6
|
module OMF::Web
|
7
7
|
|
@@ -25,11 +25,14 @@ module OMF::Web
|
|
25
25
|
raise "Repeated try to register data source '#{name}'"
|
26
26
|
end
|
27
27
|
if data_source.is_a? OMF::OML::OmlNetwork
|
28
|
-
|
29
|
-
@@datasources[name] = dsh
|
30
|
-
else
|
31
|
-
@@datasources[name] = data_source
|
28
|
+
raise "Register link and node table separately "
|
32
29
|
end
|
30
|
+
# dsh = data_source.to_tables(opts)
|
31
|
+
# @@datasources[name] = dsh
|
32
|
+
# else
|
33
|
+
# @@datasources[name] = data_source
|
34
|
+
# end
|
35
|
+
@@datasources[name] = data_source
|
33
36
|
end
|
34
37
|
|
35
38
|
def self.[](name)
|
@@ -63,36 +66,35 @@ module OMF::Web
|
|
63
66
|
ds_name = ds_name.to_sym
|
64
67
|
ds = @@datasources[ds_name]
|
65
68
|
unless ds
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
69
|
+
top = "#{ds_name}/"
|
70
|
+
names = @@datasources.keys.find_all { |ds_name| ds_name.to_s.start_with? top }
|
71
|
+
unless names.empty?
|
72
|
+
return names.map do |ds_name|
|
73
|
+
OMF::Web::SessionStore[ds_name, :dsp] ||= self.new(ds_name, @@datasources[ds_name])
|
71
74
|
end
|
72
75
|
end
|
76
|
+
# debug ">>>> #{dsa}"
|
77
|
+
# # let's check for sub table, such as network/nodes
|
78
|
+
# main, sub = ds_descr[:name].split('/')
|
79
|
+
# if (sub)
|
80
|
+
# if ds_top = @@datasources[main.to_sym]
|
81
|
+
# ds = ds_top[sub.to_sym]
|
82
|
+
# end
|
83
|
+
# end
|
73
84
|
unless ds
|
74
85
|
raise "Unknown data source '#{ds_name}' (#{@@datasources.keys.inspect})"
|
75
86
|
end
|
76
87
|
end
|
77
88
|
if ds.is_a? Hash
|
89
|
+
raise "Is this actually used anywhere?"
|
78
90
|
proxies = ds.map do |name, ds|
|
79
91
|
id = "#{ds_name}_#{name}".to_sym
|
80
92
|
proxy = OMF::Web::SessionStore[id, :dsp] ||= self.new(id, ds)
|
81
93
|
end
|
82
94
|
return proxies
|
83
|
-
|
84
|
-
# n_name = "#{ds_name}_nodes".to_sym
|
85
|
-
# l_name = "#{ds_name}_links".to_sym
|
86
|
-
# if (nodes = OMF::Web::SessionStore[n_name, :dsp])
|
87
|
-
# # assume links exist as well
|
88
|
-
# links = OMF::Web::SessionStore[l_name, :dsp]
|
89
|
-
# else
|
90
|
-
# nodes = OMF::Web::SessionStore[n_name, :dsp] = self.new(n_name, ds[:nodes])
|
91
|
-
# links = OMF::Web::SessionStore[l_name, :dsp] = self.new(l_name, ds[:links])
|
92
|
-
# end
|
93
|
-
# return [nodes, links]
|
94
95
|
end
|
95
96
|
|
97
|
+
#debug ">>>>> DS: #{ds_descr.inspect} - #{ds}"
|
96
98
|
proxy = OMF::Web::SessionStore[ds_name, :dsp] ||= self.new(ds_name, ds)
|
97
99
|
return [proxy]
|
98
100
|
end
|
@@ -119,11 +121,11 @@ module OMF::Web
|
|
119
121
|
rows = ds.rows[(offset - ds.offset) .. -1]
|
120
122
|
if rows && rows.length > 0
|
121
123
|
debug "on_changed: sending #{rows.length}"
|
122
|
-
block.call
|
124
|
+
block.call :added, rows
|
123
125
|
end
|
124
|
-
@data_source.
|
125
|
-
debug "on_changed:
|
126
|
-
block.call
|
126
|
+
@data_source.on_content_changed(block.object_id) do |action, rows|
|
127
|
+
debug "on_changed: #{action}: #{rows.inspect}"
|
128
|
+
block.call action, rows
|
127
129
|
end
|
128
130
|
end
|
129
131
|
|
@@ -144,7 +146,8 @@ module OMF::Web
|
|
144
146
|
opts[:update_url] = "/_update/#{@name}?sid=#{sid}"
|
145
147
|
opts[:sid] = sid
|
146
148
|
unless opts[:slice] # don't send any data if this is a sliced one
|
147
|
-
opts[:rows] = @data_source.rows[0 .. 20]
|
149
|
+
#opts[:rows] = @data_source.rows[0 .. 20]
|
150
|
+
opts[:rows] = []
|
148
151
|
opts[:offset] = @data_source.offset
|
149
152
|
end
|
150
153
|
#puts "to_java2>>>>> #{opts.to_json.inspect}"
|
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
require 'omf_common/lobject'
|
3
|
+
require 'rack'
|
4
|
+
require 'omf-web/session_store'
|
5
|
+
|
6
|
+
|
7
|
+
module OMF::Web::Rack
|
8
|
+
class SessionAuthenticator < OMF::Common::LObject
|
9
|
+
|
10
|
+
def self.active?
|
11
|
+
@@active
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.authenticated?
|
15
|
+
self[:authenticated]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.authenticate
|
19
|
+
self[:authenticated] = true
|
20
|
+
self[:valid_until] = Time.now + @@expire_after
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.logout
|
24
|
+
self[:authenticated] = false
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.[](key)
|
28
|
+
OMF::Web::SessionStore[key, :authenticator]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.[]=(key, value)
|
32
|
+
OMF::Web::SessionStore[key, :authenticator] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
@@active = false
|
36
|
+
# Expire authenticated session after being idle for that many seconds
|
37
|
+
@@expire_after = 2592000
|
38
|
+
|
39
|
+
#
|
40
|
+
# opts -
|
41
|
+
# :no_session - Array of regexp to ignore
|
42
|
+
#
|
43
|
+
def initialize(app, opts = {})
|
44
|
+
@app = app
|
45
|
+
@opts = opts
|
46
|
+
@opts[:no_session] = (@opts[:no_session] || []).map { |s| Regexp.new(s) }
|
47
|
+
if @opts[:expire_after]
|
48
|
+
@@expire_after = @opts[:expire_after]
|
49
|
+
end
|
50
|
+
@@active = true
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def call(env)
|
55
|
+
#puts env.keys.inspect
|
56
|
+
req = ::Rack::Request.new(env)
|
57
|
+
sid = nil
|
58
|
+
path_info = req.path_info
|
59
|
+
#puts "REQUEST: #{path_info}"
|
60
|
+
unless @opts[:no_session].find {|rx| rx.match(path_info) }
|
61
|
+
sid = req.cookies['sid'] || "s#{(rand * 10000000).to_i}_#{(rand * 10000000).to_i}"
|
62
|
+
debug "Setting session for '#{req.path_info}' to '#{sid}'"
|
63
|
+
Thread.current["sessionID"] = sid
|
64
|
+
# If 'login_url' is defined, check if this session is authenticated
|
65
|
+
login_url = @opts[:login_url]
|
66
|
+
if login_url && login_url != req.path_info
|
67
|
+
if authenticated = self.class[:authenticated]
|
68
|
+
# Check if it hasn't imed out
|
69
|
+
if self.class[:valid_until] < Time.now
|
70
|
+
debug "Session '#{sid}' expired"
|
71
|
+
authenticated = false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
unless authenticated
|
75
|
+
return [301, {'Location' => login_url, "Content-Type" => ""}, ['Login first']]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
self.class[:valid_until] = Time.now + @@expire_after
|
79
|
+
end
|
80
|
+
|
81
|
+
status, headers, body = @app.call(env)
|
82
|
+
if sid
|
83
|
+
headers['Set-Cookie'] = "sid=#{sid}" ##: name2=value2; Expires=Wed, 09-Jun-2021 ]
|
84
|
+
end
|
85
|
+
[status, headers, body]
|
86
|
+
end
|
87
|
+
end # class
|
88
|
+
|
89
|
+
end # module
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
@@ -32,12 +32,17 @@ module OMF::Web::Rack
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def call(env)
|
35
|
+
#puts env.keys.inspect
|
36
|
+
|
35
37
|
req = ::Rack::Request.new(env)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
#puts "COOKIES>>>> #{req.cookies.inspect}"
|
39
|
+
#req.cookies['user'] = 'booo'
|
40
|
+
|
41
|
+
# sessionID = req.params['sid']
|
42
|
+
# if sessionID.nil? || sessionID.empty?
|
43
|
+
# sessionID = "s#{(rand * 10000000).to_i}"
|
44
|
+
# end
|
45
|
+
# Thread.current["sessionID"] = sessionID
|
41
46
|
|
42
47
|
OMF::Web::Theme.require 'page'
|
43
48
|
body, headers = render_page(req)
|
@@ -53,12 +53,13 @@ module OMF::Web::Rack
|
|
53
53
|
dsp = find_data_source(args)
|
54
54
|
return unless dsp # should define appropriate exception
|
55
55
|
debug "Received registration for datasource proxy '#{dsp}'"
|
56
|
-
dsp.on_changed(args['offset']) do |
|
56
|
+
dsp.on_changed(args['offset']) do |action, rows|
|
57
57
|
msg = {
|
58
58
|
type: 'datasource_update',
|
59
59
|
datasource: dsp.name,
|
60
|
-
rows:
|
61
|
-
|
60
|
+
rows: rows,
|
61
|
+
action: action
|
62
|
+
#offset: offset
|
62
63
|
}
|
63
64
|
send_data(msg.to_json)
|
64
65
|
end
|
@@ -81,14 +82,24 @@ module OMF::Web::Rack
|
|
81
82
|
end
|
82
83
|
sdsp = dsp.create_slice(col_name, col_value)
|
83
84
|
context[:sliced_datasource] = {:col_name => col_name, :dsp => sdsp}
|
84
|
-
sdsp.on_changed(0) do |
|
85
|
+
sdsp.on_changed(0) do |action, rows|
|
85
86
|
msg = {
|
86
87
|
type: 'datasource_update',
|
87
88
|
datasource: args['ds_name'],
|
88
|
-
rows:
|
89
|
-
|
89
|
+
rows: rows,
|
90
|
+
action: action
|
91
|
+
#offset: offset
|
90
92
|
}
|
91
93
|
send_data(msg.to_json)
|
94
|
+
#
|
95
|
+
# do |new_rows, offset|
|
96
|
+
# msg = {
|
97
|
+
# type: 'datasource_update',
|
98
|
+
# datasource: args['ds_name'],
|
99
|
+
# rows: new_rows,
|
100
|
+
# offset: offset
|
101
|
+
# }
|
102
|
+
# send_data(msg.to_json)
|
92
103
|
end
|
93
104
|
end
|
94
105
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
|
-
require 'omf-web/theme/bright/
|
2
|
+
require 'omf-web/theme/bright/layout_renderer'
|
3
3
|
|
4
4
|
module OMF::Web::Theme
|
5
5
|
|
6
|
-
class FlowRenderer <
|
6
|
+
class FlowRenderer < LayoutRenderer
|
7
7
|
|
8
8
|
def initialize(layout_widget, widgets, opts)
|
9
9
|
super opts
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require 'omf-web/theme/abstract_page'
|
3
|
+
|
4
|
+
module OMF::Web::Theme
|
5
|
+
|
6
|
+
class MustacheRenderer < Erector::Widget
|
7
|
+
|
8
|
+
def initialize(widget, opts)
|
9
|
+
super opts
|
10
|
+
@widget = widget
|
11
|
+
@opts = opts
|
12
|
+
end
|
13
|
+
|
14
|
+
def content()
|
15
|
+
base_id = "mr#{self.object_id}"
|
16
|
+
opts = @opts.dup
|
17
|
+
opts[:base_id] = base_id
|
18
|
+
div :id => base_id, :class => "mustache_widget" do
|
19
|
+
javascript(%{
|
20
|
+
L.require('#OML.mustache', 'js/mustache', function() {
|
21
|
+
OML.mustache(#{opts.to_json});
|
22
|
+
});
|
23
|
+
})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'omf-web/theme/abstract_page'
|
2
|
+
require 'omf-web/rack/session_authenticator'
|
2
3
|
|
3
4
|
module OMF::Web::Theme
|
4
5
|
class Page < OMF::Web::Theme::AbstractPage
|
@@ -33,16 +34,25 @@ module OMF::Web::Theme
|
|
33
34
|
|
34
35
|
def content
|
35
36
|
super
|
37
|
+
@renderer = @widget.content
|
36
38
|
div :id => 'doc3' do
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
if @renderer.render? :header
|
40
|
+
div :id => 'hd' do
|
41
|
+
if @renderer.render? :top_line
|
42
|
+
render_top_line
|
43
|
+
end
|
44
|
+
if @renderer.render? :title
|
45
|
+
h1 @page_title || 'Missing :page_title'
|
46
|
+
end
|
47
|
+
end
|
40
48
|
end
|
41
49
|
div :id => 'bd' do
|
42
50
|
render_body
|
43
51
|
end
|
44
|
-
|
45
|
-
|
52
|
+
if @renderer.render? :footer
|
53
|
+
div :id => 'ft' do
|
54
|
+
render_footer
|
55
|
+
end
|
46
56
|
end
|
47
57
|
end
|
48
58
|
end
|
@@ -59,7 +69,8 @@ module OMF::Web::Theme
|
|
59
69
|
@tabs.each do |h|
|
60
70
|
lopts = h[:id] == @tab ? {:class => :current} : {}
|
61
71
|
li lopts do
|
62
|
-
a :href => "#{@prefix}/#{h[:id]}?sid=#{Thread.current["sessionID"]}" do
|
72
|
+
#a :href => "#{@prefix}/#{h[:id]}?sid=#{Thread.current["sessionID"]}" do
|
73
|
+
a :href => "#{@prefix}/#{h[:id]}" do
|
63
74
|
span h[:name], :class => :tab_text
|
64
75
|
end
|
65
76
|
end
|
@@ -69,8 +80,22 @@ module OMF::Web::Theme
|
|
69
80
|
|
70
81
|
def render_tools_menu
|
71
82
|
div :id => :tools_menu do
|
72
|
-
|
83
|
+
render_authentication
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def render_authentication
|
88
|
+
if OMF::Web::Rack::SessionAuthenticator.active?
|
89
|
+
if OMF::Web::Rack::SessionAuthenticator.authenticated?
|
90
|
+
# text OMF::Web::Rack::Session[:name]
|
91
|
+
# text ' | '
|
92
|
+
a 'Log out', :href => '/logout'
|
93
|
+
else
|
94
|
+
a 'Log in', :href => '/tab/login'
|
95
|
+
end
|
73
96
|
end
|
97
|
+
|
98
|
+
|
74
99
|
end
|
75
100
|
|
76
101
|
def render_body
|
@@ -81,7 +106,7 @@ module OMF::Web::Theme
|
|
81
106
|
def render_card_body
|
82
107
|
return unless @widget
|
83
108
|
Thread.current["top_renderer"] = self
|
84
|
-
rawtext @
|
109
|
+
rawtext @renderer.to_html
|
85
110
|
end
|
86
111
|
|
87
112
|
def render_footer
|
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
require 'omf-web/theme/bright/widget_chrome'
|
1
|
+
require 'omf-web/theme/bright/layout_renderer'
|
3
2
|
|
4
3
|
module OMF::Web::Theme
|
5
4
|
|
6
|
-
class TabbedRenderer <
|
5
|
+
class TabbedRenderer < LayoutRenderer
|
7
6
|
|
8
7
|
def initialize(layout_widget, widgets, opts)
|
9
8
|
super opts
|
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
|
-
require 'omf-web/theme/bright/widget_chrome'
|
1
|
+
require 'omf-web/theme/bright/layout_renderer'
|
3
2
|
|
4
3
|
module OMF::Web::Theme
|
5
4
|
|
6
|
-
class TwoColumnsRenderer <
|
7
|
-
|
5
|
+
class TwoColumnsRenderer < LayoutRenderer
|
6
|
+
|
8
7
|
DEFAULT_LAYOUT = '66_33'
|
9
8
|
|
10
9
|
@@layout2class = {
|
data/lib/omf-web/version.rb
CHANGED
@@ -19,12 +19,6 @@ module OMF::Web::Widget
|
|
19
19
|
unless (content_descr = opts[:content])
|
20
20
|
raise "Missing 'content' option in '#{opts.describe}'"
|
21
21
|
end
|
22
|
-
# if content_descr.is_a? OMF::Web::ContentProxy
|
23
|
-
# @content_proxy = content_descr
|
24
|
-
# else
|
25
|
-
# #@content_proxy = OMF::Web::ContentRepository[opts].load(content_descr)
|
26
|
-
# @content_proxy = OMF::Web::Repository.create_content_proxy_for(content_descr, opts)
|
27
|
-
# end
|
28
22
|
@content_proxy = OMF::Web::ContentRepository.create_content_proxy_for(content_descr, opts)
|
29
23
|
end
|
30
24
|
|
@@ -36,7 +30,6 @@ module OMF::Web::Widget
|
|
36
30
|
@content_proxy.mime_type
|
37
31
|
end
|
38
32
|
|
39
|
-
|
40
33
|
def update_url
|
41
34
|
@content_proxy.content_url
|
42
35
|
end
|
@@ -8,8 +8,9 @@ module OMF::Web::Widget::Layout
|
|
8
8
|
|
9
9
|
def initialize(type, opts)
|
10
10
|
super opts
|
11
|
-
|
12
|
-
@
|
11
|
+
wt = opts[:widgets] || opts # support opts[:left] as well as opts[:widgets][:left]
|
12
|
+
@left = (wt[:left] || []).map {|w| OMF::Web::Widget.create_widget(w)}
|
13
|
+
@right = (wt[:right] || []).map {|w| OMF::Web::Widget.create_widget(w)}
|
13
14
|
end
|
14
15
|
|
15
16
|
def content()
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
require 'omf-web/widget/abstract_widget'
|
3
|
+
require 'omf-web/content/repository'
|
4
|
+
|
5
|
+
module OMF::Web::Widget
|
6
|
+
|
7
|
+
# Renders the content of a moustache file in the context of a data source
|
8
|
+
#
|
9
|
+
class MustacheWidget < AbstractWidget
|
10
|
+
|
11
|
+
def self.create_mustache_widget(type, wdescr)
|
12
|
+
return self.new(wdescr)
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :content_proxy
|
16
|
+
|
17
|
+
def initialize(opts)
|
18
|
+
super opts
|
19
|
+
# if (content_descr = opts[:content])
|
20
|
+
# opts[:content_proxy] = OMF::Web::ContentRepository.create_content_proxy_for(content_descr, opts)
|
21
|
+
# end
|
22
|
+
end
|
23
|
+
|
24
|
+
def title
|
25
|
+
@opts[:title] || 'No Title'
|
26
|
+
end
|
27
|
+
|
28
|
+
def content()
|
29
|
+
OMF::Web::Theme.require 'mustache_renderer'
|
30
|
+
OMF::Web::Theme::MustacheRenderer.new(self, @opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
def collect_data_sources(ds_set)
|
34
|
+
if @opts[:data_sources]
|
35
|
+
@opts[:data_sources].each do |ds|
|
36
|
+
ds_set.add(ds[:stream])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
ds_set
|
40
|
+
end
|
41
|
+
|
42
|
+
end # class
|
43
|
+
|
44
|
+
end
|
data/lib/omf-web/widget.rb
CHANGED
@@ -5,7 +5,8 @@ module OMF::Web::Widget
|
|
5
5
|
|
6
6
|
|
7
7
|
@@widgets = {}
|
8
|
-
@@descriptions = {}
|
8
|
+
@@descriptions = {}
|
9
|
+
@@type2class = {}
|
9
10
|
|
10
11
|
def self.register_widget(wdescr)
|
11
12
|
unless id = wdescr[:id]
|
@@ -22,6 +23,15 @@ module OMF::Web::Widget
|
|
22
23
|
@@descriptions
|
23
24
|
end
|
24
25
|
|
26
|
+
def self.register_widget_type(id, widget_class)
|
27
|
+
id = id.to_sym
|
28
|
+
if (@@type2class.key? id)
|
29
|
+
raise "Repeated try to register widget type '#{id}'"
|
30
|
+
end
|
31
|
+
@@type2class[id] = widget_class
|
32
|
+
end
|
33
|
+
|
34
|
+
|
25
35
|
# Return the number of top level widgets. If 'restrict_to' is an
|
26
36
|
# array, only return those.
|
27
37
|
#
|
@@ -82,6 +92,9 @@ module OMF::Web::Widget
|
|
82
92
|
when /^code/
|
83
93
|
require 'omf-web/widget/code_widget'
|
84
94
|
w = OMF::Web::Widget::CodeWidget.create_code_widget(type, wdescr)
|
95
|
+
when /^moustache/
|
96
|
+
require 'omf-web/widget/mustache_widget'
|
97
|
+
w = OMF::Web::Widget::MustacheWidget.create_mustache_widget(type, wdescr)
|
85
98
|
else
|
86
99
|
raise "Unknown widget type '#{type}' (#{wdescr.inspect})"
|
87
100
|
end
|
data/lib/omf_common/lobject.rb
CHANGED
@@ -150,9 +150,12 @@ module OMF::Common
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def _logger(category = nil)
|
153
|
-
unless @logger
|
154
|
-
|
155
|
-
|
153
|
+
unless @logger #&& category.nil?
|
154
|
+
cat = self.class.to_s
|
155
|
+
if category
|
156
|
+
cat = "#{cat}-#{category}"
|
157
|
+
end
|
158
|
+
@logger = OMF::Common::Loggable.logger(cat)
|
156
159
|
end
|
157
160
|
return @logger
|
158
161
|
end
|
data/omf_web.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
# specify any dependencies here; for example:
|
23
23
|
# s.add_development_dependency "minitest", "~> 2.11.3"
|
24
|
-
s.add_runtime_dependency "
|
24
|
+
s.add_runtime_dependency "omf_oml", "~> 0.9"
|
25
25
|
s.add_runtime_dependency "erector", "~> 0.8.3"
|
26
26
|
s.add_runtime_dependency "activesupport", "~> 3.0.0" # required by erector:table
|
27
27
|
s.add_runtime_dependency "rack", "~> 1.3.5"
|
@@ -33,4 +33,6 @@ Gem::Specification.new do |s|
|
|
33
33
|
s.add_runtime_dependency "json", "~> 1.7.3"
|
34
34
|
s.add_runtime_dependency "grit", "~> 2.5.0"
|
35
35
|
s.add_runtime_dependency "sqlite3", "~> 1.3.6"
|
36
|
+
s.add_runtime_dependency "postgres-pr", "~> 0.6.3"
|
37
|
+
s.add_runtime_dependency "websocket-rack", "~> 0.4.0"
|
36
38
|
end
|
@@ -26,7 +26,14 @@ L.provide('OML.abstract_nv_chart', ["graph/js/abstract_chart", "#OML.abstract_ch
|
|
26
26
|
margin: {
|
27
27
|
top: 0, right: 0, bottom: 0, left: 50 // not sure what impact this really has?
|
28
28
|
}
|
29
|
+
},
|
30
|
+
|
31
|
+
defaults: function() {
|
32
|
+
return this.deep_defaults({
|
33
|
+
transition_duration: 500
|
34
|
+
}, OML.abstract_nv_chart.__super__.defaults.call(this));
|
29
35
|
},
|
36
|
+
|
30
37
|
|
31
38
|
configure_base_layer: function(vis) {
|
32
39
|
this.base_layer = vis;
|
@@ -116,10 +123,13 @@ L.provide('OML.abstract_nv_chart', ["graph/js/abstract_chart", "#OML.abstract_ch
|
|
116
123
|
},
|
117
124
|
|
118
125
|
redraw: function(data) {
|
119
|
-
this.base_layer//.select(".chart_layer")
|
120
|
-
|
121
|
-
|
122
|
-
|
126
|
+
var bl = this.base_layer//.select(".chart_layer")
|
127
|
+
.datum(this._datum(data, this.chart))
|
128
|
+
;
|
129
|
+
if (this.opts.transition_duration > 0) {
|
130
|
+
bl = bl.transition().duration(500)
|
131
|
+
}
|
132
|
+
bl.call(this.chart);
|
123
133
|
},
|
124
134
|
|
125
135
|
})
|
@@ -282,6 +282,7 @@ L.provide('OML.abstract_widget', ["vendor/d3/d3.js"], function () {
|
|
282
282
|
switch (type) {
|
283
283
|
case 'int':
|
284
284
|
case 'float':
|
285
|
+
case 'key' :
|
285
286
|
var scale = descr.scale;
|
286
287
|
var min_value = descr.min;
|
287
288
|
var max_value = descr.max;
|
@@ -311,10 +312,10 @@ L.provide('OML.abstract_widget', ["vendor/d3/d3.js"], function () {
|
|
311
312
|
var color = color_f(v);
|
312
313
|
return color;
|
313
314
|
};
|
314
|
-
case 'key' :
|
315
|
-
return function(d) {
|
316
|
-
return d[index];
|
317
|
-
}
|
315
|
+
// case 'key' :
|
316
|
+
// return function(d) {
|
317
|
+
// return d[index];
|
318
|
+
// }
|
318
319
|
default:
|
319
320
|
throw "Unknown mapping type '" + type + "'";
|
320
321
|
}
|