omf_web 0.9.6 → 0.9.7
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 +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
|
}
|