omf_web 0.9.9 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +31 -0
- data/bin/omf_web_server.rb +157 -0
- data/doc/screenshot2.png +0 -0
- data/doc/widget_detail.png +0 -0
- data/example/demo/data_sources/downloads.rb +2 -1
- data/example/simple/README.md +12 -13
- data/example/simple/create_waveform.rb +29 -0
- data/example/simple/introduction.md +17 -0
- data/example/simple/sample.sq3 +0 -0
- data/example/simple/sample.sql +1008 -0
- data/example/simple/simple.yaml +62 -0
- data/example/simple/simple_dynamic.yaml +66 -0
- data/lib/irods4r/file.rb +15 -14
- data/lib/irods4r/icommands.rb +18 -18
- data/lib/irods4r.rb +9 -9
- data/lib/omf-web/config.ru +41 -16
- data/lib/omf-web/content/git_repository.rb +32 -31
- data/lib/omf-web/content/irods_repository.rb +34 -33
- data/lib/omf-web/content/repository.rb +48 -44
- data/lib/omf-web/data_source_proxy.rb +33 -22
- data/lib/omf-web/rack/session_authenticator.rb +48 -12
- data/lib/omf-web/rack/tab_mapper.rb +30 -36
- data/lib/omf-web/rack/websocket_handler.rb +26 -25
- data/lib/omf-web/session_store.rb +16 -13
- data/lib/omf-web/theme/abstract_page.rb +26 -22
- data/lib/omf-web/theme/bright/page.rb +84 -34
- data/lib/omf-web/theme/bright/stacked_renderer.rb +20 -19
- data/lib/omf-web/theme.rb +14 -9
- data/lib/omf-web/thin/runner.rb +38 -36
- data/lib/omf-web/thin/server.rb +255 -0
- data/lib/omf-web/version.rb +1 -1
- data/lib/omf-web/widget/data_widget.rb +6 -6
- data/lib/omf-web/widget/text/maruku/helpers.rb +33 -30
- data/lib/omf-web/widget/text/maruku/input/parse_block.rb +117 -117
- data/lib/omf-web/widget/text/maruku/output/to_html.rb +155 -154
- data/lib/omf-web/widget/text/maruku.rb +17 -16
- data/omf_web.gemspec +6 -2
- data/sample.sq3 +0 -0
- data/share/htdocs/graph/js/gauge.js +524 -0
- data/share/htdocs/vendor/VERSION_MAP.yaml +3 -3
- data/share/htdocs/vendor/backbone-1.0.0/backbone.js +1571 -0
- data/share/htdocs/vendor/d3-3.0/LICENSE.brewer.txt +38 -0
- data/share/htdocs/vendor/d3-3.0/colorbrewer.js +1 -0
- data/share/htdocs/vendor/d3-3.0/d3.js +8810 -0
- data/share/htdocs/vendor/d3-3.0/d3.min.js +5 -0
- data/share/htdocs/vendor/geo_json/Readme.txt +71 -0
- data/share/htdocs/vendor/geo_json/regions.json +41 -0
- data/share/htdocs/vendor/geo_json/switzerland.json +24 -0
- data/share/htdocs/vendor/geo_json/world.json +497 -0
- data/share/htdocs/vendor/nv_d3/js/nv.d3.js +8801 -4447
- data/share/htdocs/vendor/spin/jquery.spin.js +46 -0
- data/share/htdocs/vendor/spin/spin.js +349 -0
- data/share/htdocs/vendor/spin/spin.min.js +1 -0
- data/share/htdocs/vendor/underscore-1.4.4/underscore.js +1227 -0
- metadata +63 -48
- data/example/simple/data_sources/gimi31.sq3 +0 -0
- data/example/simple/data_sources/ping_source.rb +0 -56
- data/example/simple/simple_viz_server.rb +0 -39
- data/example/simple/widgets/charts_tab.yaml +0 -38
- data/share/.DS_Store +0 -0
- data/share/htdocs/.DS_Store +0 -0
- data/share/htdocs/vendor/backbone-0.5.3/backbone.js +0 -1158
- data/share/htdocs/vendor/underscore-1.2.1/underscore.js +0 -958
@@ -1,58 +1,59 @@
|
|
1
1
|
|
2
2
|
require 'omf-web/theme/bright/widget_chrome'
|
3
|
+
require 'omf-web/theme/bright/layout_renderer'
|
3
4
|
|
4
5
|
module OMF::Web::Theme
|
5
|
-
|
6
|
-
class StackedRenderer
|
7
|
-
|
6
|
+
|
7
|
+
class StackedRenderer < LayoutRenderer
|
8
|
+
|
8
9
|
def initialize(stacked_widget, widgets, active_index, opts)
|
9
10
|
@stacked_widget = stacked_widget
|
10
11
|
@widgets = widgets
|
11
12
|
@active_index = active_index
|
12
13
|
@helper = StackedRendererHelper.new(widgets, active_index, opts)
|
13
14
|
@opts = opts
|
14
|
-
end
|
15
|
-
|
15
|
+
end
|
16
|
+
|
16
17
|
def to_html()
|
17
18
|
wp = "w#{@helper.object_id}"
|
18
19
|
@opts[:menu] = @widgets.each_with_index.map do |w, i|
|
19
|
-
wc = w.widget_type.split('/').inject([]) do |a, e|
|
20
|
-
a << (a.empty? ? e : "#{a[-1]}_#{e}")
|
20
|
+
wc = w.widget_type.split('/').inject([]) do |a, e|
|
21
|
+
a << (a.empty? ? e : "#{a[-1]}_#{e}")
|
21
22
|
end
|
22
23
|
{
|
23
|
-
:name => w.name,
|
24
|
-
:class => wc.join(' '),
|
25
|
-
:is_active => (@active_index == i),
|
24
|
+
:name => w.name,
|
25
|
+
:class => wc.join(' '),
|
26
|
+
:is_active => (@active_index == i),
|
26
27
|
:id => "#{wp}_l_#{i}",
|
27
28
|
:js_function => 'OML.show_widget',
|
28
29
|
:inner_class => wp,
|
29
30
|
:index => i,
|
30
31
|
:widget_id => w.dom_id
|
31
32
|
}
|
32
|
-
end
|
33
|
+
end
|
33
34
|
WidgetChrome.new(@stacked_widget, @helper, @opts).to_html
|
34
|
-
end
|
35
|
-
end
|
35
|
+
end
|
36
|
+
end
|
36
37
|
|
37
38
|
class StackedRendererHelper < Erector::Widget
|
38
|
-
|
39
|
+
|
39
40
|
def initialize(widgets, active_index, opts)
|
40
41
|
super opts
|
41
42
|
@widgets = widgets
|
42
43
|
@active_index = active_index
|
43
|
-
end
|
44
|
+
end
|
44
45
|
|
45
46
|
def content()
|
46
47
|
#widget @active_widget
|
47
|
-
widgets = @widgets
|
48
|
+
widgets = @widgets
|
48
49
|
prefix = "w#{self.object_id}"
|
49
50
|
@widgets.each_with_index do |w, i|
|
50
51
|
style = i == @active_index ? '' : 'display:none'
|
51
52
|
div :id => "#{prefix}_#{i}", :class => prefix, :style => style do
|
52
|
-
rawtext w.content.to_html
|
53
|
+
rawtext w.content.to_html
|
53
54
|
end
|
54
|
-
end
|
55
|
+
end
|
55
56
|
end
|
56
|
-
|
57
|
+
|
57
58
|
end
|
58
59
|
end
|
data/lib/omf-web/theme.rb
CHANGED
@@ -2,29 +2,34 @@
|
|
2
2
|
|
3
3
|
module OMF::Web::Theme
|
4
4
|
extend OMF::Common::Loggable
|
5
|
-
|
5
|
+
|
6
6
|
DEFAULT_THEME = 'omf-web/theme/bright'
|
7
7
|
@@search_order = [DEFAULT_THEME] # default theme
|
8
8
|
@@loaded = {}
|
9
9
|
@@additional_renderers = {}
|
10
|
-
|
10
|
+
|
11
11
|
def self.theme=(theme)
|
12
12
|
if theme
|
13
13
|
unless theme.match '.*/'
|
14
14
|
theme = "omf-web/theme/#{theme}" # add default name space
|
15
15
|
end
|
16
16
|
@@loaded = {}
|
17
|
-
@@search_order = [theme]
|
17
|
+
@@search_order = [theme]
|
18
18
|
Kernel::require "#{theme}/init"
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
|
+
def self.include_css(css_file)
|
23
|
+
::Kernel.require 'omf-web/theme/abstract_page'
|
24
|
+
OMF::Web::Theme::AbstractPage.add_depends_on(:css, "/resource/#{css_file}")
|
25
|
+
end
|
26
|
+
|
22
27
|
def self.register_renderer(name, klass, theme = DEFAULT_THEME)
|
23
28
|
tr = @@additional_renderers[theme.to_s] ||= {}
|
24
29
|
tr[name] = klass
|
25
30
|
end
|
26
|
-
|
27
|
-
# Set additional themes to search in the given order for
|
31
|
+
|
32
|
+
# Set additional themes to search in the given order for
|
28
33
|
# implementations of renderes. Allows for partial override
|
29
34
|
# in new themes.
|
30
35
|
#
|
@@ -32,8 +37,8 @@ module OMF::Web::Theme
|
|
32
37
|
@@loaded = {}
|
33
38
|
@@search_order = search_order if search_order
|
34
39
|
end
|
35
|
-
|
36
|
-
|
40
|
+
|
41
|
+
|
37
42
|
def self.require(name)
|
38
43
|
name = name.to_sym
|
39
44
|
return if @@loaded[name]
|
@@ -45,7 +50,7 @@ module OMF::Web::Theme
|
|
45
50
|
Kernel::require "#{theme}/#{name}"
|
46
51
|
end
|
47
52
|
@@loaded[name] = true
|
48
|
-
debug "Using renderer '#{theme}/#{name}'"
|
53
|
+
debug "Using renderer '#{theme}/#{name}'"
|
49
54
|
return
|
50
55
|
rescue LoadError => le
|
51
56
|
# Move on to the next one
|
data/lib/omf-web/thin/runner.rb
CHANGED
@@ -11,26 +11,27 @@ module Thin
|
|
11
11
|
true # will be verified later
|
12
12
|
end
|
13
13
|
end
|
14
|
-
end
|
14
|
+
end
|
15
15
|
|
16
16
|
module OMF::Web
|
17
17
|
class Runner < Thin::Runner
|
18
18
|
include OMF::Common::Loggable
|
19
|
-
|
19
|
+
|
20
20
|
@@instance = nil
|
21
|
-
|
21
|
+
|
22
22
|
def self.instance
|
23
23
|
@@instance
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
attr_reader :options
|
27
|
-
|
27
|
+
|
28
28
|
def initialize(argv, opts = {})
|
29
29
|
raise "SINGLETON" if @@instance
|
30
|
-
|
30
|
+
@@instance = self
|
31
|
+
|
31
32
|
@argv = argv
|
32
33
|
sopts = opts.delete(:ssl) # runner has it's own idea of ssl options
|
33
|
-
|
34
|
+
|
34
35
|
# Default options values
|
35
36
|
app_name = opts[:app_name] || 'omf_web_app'
|
36
37
|
@options = {
|
@@ -46,68 +47,70 @@ module OMF::Web
|
|
46
47
|
:max_persistent_conns => Thin::Server::DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS,
|
47
48
|
:require => [],
|
48
49
|
:wait => Thin::Controllers::Cluster::DEFAULT_WAIT_TIME,
|
49
|
-
|
50
|
+
|
50
51
|
:rackup => File.dirname(__FILE__) + '/../config.ru',
|
51
52
|
:static_dirs => ["#{File.dirname(__FILE__)}/../../../share/htdocs"],
|
52
53
|
:static_dirs_pre => ["./resources"], # directories to prepend to 'static_dirs'
|
53
|
-
|
54
|
+
|
54
55
|
:handlers => {} # procs to call at various times of the server's life cycle
|
55
56
|
}.merge(opts)
|
56
57
|
# Search path for resource files is concatination of 'pre' and 'standard' static dirs
|
57
58
|
@options[:static_dirs] = @options[:static_dirs_pre].concat(@options[:static_dirs])
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
|
60
|
+
|
61
|
+
|
61
62
|
print_options = false
|
62
63
|
p = parser
|
63
64
|
p.separator ""
|
64
|
-
p.separator "OMF options:"
|
65
|
-
p.on("--theme THEME", "Select web theme") do |t| OMF::Web::Theme.theme = t end
|
66
|
-
|
67
|
-
p.separator ""
|
68
|
-
p.separator "Testing options:"
|
69
|
-
p.on("--disable-https", "Run server without SSL") do sopts = nil end
|
70
|
-
p.on("--print-options", "Print option settings after parsing command lines args") do print_options = true end
|
71
|
-
|
65
|
+
p.separator "OMF Web options:"
|
66
|
+
p.on("--theme THEME", "Select web theme") do |t| OMF::Web::Theme.theme = t end
|
67
|
+
|
72
68
|
# Allow application to add it's own parsing options
|
73
69
|
if ph = @options[:handlers][:pre_parse]
|
74
|
-
ph.call(p)
|
70
|
+
ph.arity == 1 ? ph.call(p) : ph.call(p, self)
|
75
71
|
end
|
76
72
|
|
73
|
+
p.separator ""
|
74
|
+
p.separator "Testing options:"
|
75
|
+
p.on("--disable-https", "Run server without SSL") do sopts = nil end
|
76
|
+
p.on("--print-options", "Print option settings after parsing command lines args") do print_options = true end
|
77
|
+
p.separator ""
|
78
|
+
|
77
79
|
parse!
|
78
|
-
|
79
|
-
# unless life_cycle(:post_parse)
|
80
|
-
# puts p.to_s
|
81
|
-
# abort()
|
82
|
-
# end
|
80
|
+
|
83
81
|
if sopts
|
84
82
|
@options[:ssl] = true
|
85
83
|
@options[:ssl_key_file] ||= sopts[:key_file]
|
86
84
|
@options[:ssl_cert_file] ||= sopts[:cert_file]
|
87
85
|
@options[:ssl_verify] ||= sopts[:verify_peer]
|
88
86
|
end
|
87
|
+
life_cycle(:post_parse)
|
89
88
|
|
90
89
|
# Change the name of the root logger so we can apply different logging
|
91
|
-
# policies depending on environment.
|
90
|
+
# policies depending on environment.
|
92
91
|
#
|
93
92
|
OMF::Common::Loggable.set_environment @options[:environment]
|
94
93
|
|
94
|
+
if css = opts[:include_css]
|
95
|
+
require 'omf-web/theme'
|
96
|
+
OMF::Web::Theme.include_css(css)
|
97
|
+
end
|
98
|
+
|
95
99
|
if print_options
|
96
100
|
require 'pp'
|
97
101
|
pp @options
|
98
|
-
end
|
99
|
-
|
100
|
-
@@instance = self
|
102
|
+
end
|
103
|
+
|
101
104
|
end
|
102
|
-
|
105
|
+
|
103
106
|
def life_cycle(step, &exception_block)
|
104
107
|
begin
|
105
108
|
if (p = @options[:handlers][step])
|
106
|
-
p.call()
|
109
|
+
p.arity == 0 ? p.call() : p.call(self)
|
107
110
|
end
|
108
111
|
rescue => ex
|
109
112
|
if exception_block
|
110
|
-
begin
|
113
|
+
begin
|
111
114
|
exception_block.call(ex)
|
112
115
|
rescue => ex2
|
113
116
|
error ex2
|
@@ -118,8 +121,8 @@ module OMF::Web
|
|
118
121
|
debug "#{ex.backtrace.join("\n")}"
|
119
122
|
end
|
120
123
|
end
|
121
|
-
end
|
122
|
-
|
124
|
+
end
|
125
|
+
|
123
126
|
def run!
|
124
127
|
if theme = @options[:theme]
|
125
128
|
require 'omf-web/theme'
|
@@ -131,4 +134,3 @@ module OMF::Web
|
|
131
134
|
end
|
132
135
|
|
133
136
|
|
134
|
-
|
@@ -0,0 +1,255 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'omf_common/lobject'
|
3
|
+
require 'omf_web'
|
4
|
+
|
5
|
+
module OMF::Web
|
6
|
+
|
7
|
+
# Most of the code to run an OMF Web server from a configuration file
|
8
|
+
#
|
9
|
+
# USAGE:
|
10
|
+
#
|
11
|
+
#
|
12
|
+
class Server < OMF::Common::LObject
|
13
|
+
|
14
|
+
def self.start(server_name, description, top_dir, opts = {})
|
15
|
+
self.new(server_name, description, top_dir, opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(server_name, description, top_dir, opts)
|
19
|
+
OMF::Common::Loggable.init_log server_name
|
20
|
+
|
21
|
+
opts = {
|
22
|
+
static_dirs_pre: ["#{top_dir}/htdocs"],
|
23
|
+
handlers: {
|
24
|
+
pre_parse: lambda do |p, runner|
|
25
|
+
p.on("--config CONF_FILE", "File holding description of web site") {|f| runner.options[:omf_config_file] = f}
|
26
|
+
p.on("--top-dir DIR", "Directory to start from for relative data paths [directory of config file]") {|td| @top_dir = td }
|
27
|
+
end,
|
28
|
+
post_parse: lambda { |r| load_environment(r.options) },
|
29
|
+
},
|
30
|
+
authentication: {
|
31
|
+
required: false
|
32
|
+
}
|
33
|
+
}.merge(opts)
|
34
|
+
|
35
|
+
@top_dir = top_dir
|
36
|
+
@databases = {}
|
37
|
+
|
38
|
+
OMF::Web.start(opts)
|
39
|
+
end
|
40
|
+
|
41
|
+
def load_environment(opts)
|
42
|
+
unless cf = opts[:omf_config_file]
|
43
|
+
puts "Missing config file"
|
44
|
+
abort
|
45
|
+
end
|
46
|
+
|
47
|
+
unless File.readable? cf
|
48
|
+
puts "Can't read config file '#{cf}'"
|
49
|
+
abort
|
50
|
+
end
|
51
|
+
|
52
|
+
@top_dir ||= File.dirname(cf)
|
53
|
+
cfg = _rec_sym_keys(YAML.load_file(cf))
|
54
|
+
|
55
|
+
(cfg[:server] || {}).each do |k, v|
|
56
|
+
k = k.to_sym
|
57
|
+
case k
|
58
|
+
when :port
|
59
|
+
opts[:port] = v.to_i
|
60
|
+
else
|
61
|
+
opts[k] = v
|
62
|
+
end
|
63
|
+
end
|
64
|
+
(cfg[:data_sources] || []).each do |ds|
|
65
|
+
load_datasource(ds)
|
66
|
+
end
|
67
|
+
(cfg[:repositories] || []).each do |repo|
|
68
|
+
load_repository(repo)
|
69
|
+
end
|
70
|
+
|
71
|
+
unless wa = cfg[:widgets]
|
72
|
+
puts "Can't find 'widgets' section in config file '#{cf}' - #{cfg.keys}"
|
73
|
+
abort
|
74
|
+
end
|
75
|
+
wa.each do |w|
|
76
|
+
OMF::Web.register_widget w
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def load_datasource(config)
|
81
|
+
unless id = config[:id]
|
82
|
+
puts "Missing id in datasource configuration"
|
83
|
+
abort
|
84
|
+
end
|
85
|
+
case type = config[:type] || 'database'
|
86
|
+
when 'database'
|
87
|
+
load_database(config)
|
88
|
+
when 'file'
|
89
|
+
load_datasource_file(id, config)
|
90
|
+
else
|
91
|
+
abort "Unknown datasource type '#{type}'."
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def load_database(config)
|
96
|
+
unless table_name = config[:table]
|
97
|
+
puts "Missing 'table' in datasource configuration '#{id}'"
|
98
|
+
abort
|
99
|
+
end
|
100
|
+
unless db_cfg = config[:database]
|
101
|
+
puts "Missing database configuration in datasource '#{id}'"
|
102
|
+
abort
|
103
|
+
end
|
104
|
+
db = get_database(db_cfg)
|
105
|
+
unless table = db.create_table(table_name)
|
106
|
+
puts "Can't find table '#{table_name}' in database '#{db}'"
|
107
|
+
abort
|
108
|
+
end
|
109
|
+
OMF::Web.register_datasource table, name: id
|
110
|
+
end
|
111
|
+
|
112
|
+
def get_database(config)
|
113
|
+
require 'omf_oml/table'
|
114
|
+
require 'omf_oml/sql_source'
|
115
|
+
|
116
|
+
if config.is_a? String
|
117
|
+
if db = @databases[config]
|
118
|
+
return db
|
119
|
+
end
|
120
|
+
puts "Database '#{config}' not defined - (#{@databases.keys})"
|
121
|
+
abort
|
122
|
+
end
|
123
|
+
unless id = config[:id]
|
124
|
+
puts "Missing id in database configuration"
|
125
|
+
abort
|
126
|
+
end
|
127
|
+
# unless id = config[:id]
|
128
|
+
# puts "Database '#{config}' not defined - (#{@databases.keys})"
|
129
|
+
# abort
|
130
|
+
# end
|
131
|
+
unless url = config[:url]
|
132
|
+
puts "Missing URL for database '#{id}'"
|
133
|
+
abort
|
134
|
+
end
|
135
|
+
if url.start_with?('sqlite://') && ! url.start_with?('sqlite:///')
|
136
|
+
# inject top dir
|
137
|
+
url.insert('sqlite://'.length, @top_dir + '/')
|
138
|
+
end
|
139
|
+
puts "URL: #{url}"
|
140
|
+
begin
|
141
|
+
return @databases[id] = OMF::OML::OmlSqlSource.new(url, :check_interval => 3.0)
|
142
|
+
rescue Exception => ex
|
143
|
+
puts "Can't connect to database '#{id}' - #{ex}"
|
144
|
+
abort
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# The data to be served as a datasource is contained in a file. We
|
149
|
+
# currently support CSV with headers, and JSON which turns into a
|
150
|
+
# 1 col by 1 row datasource.
|
151
|
+
#
|
152
|
+
def load_datasource_file(name, opts)
|
153
|
+
unless file = opts[:file]
|
154
|
+
puts "Data source file is not defined in '#{opts}'"
|
155
|
+
abort
|
156
|
+
end
|
157
|
+
unless file.start_with? '/'
|
158
|
+
file = File.join(@top_dir, file)
|
159
|
+
end
|
160
|
+
unless File.readable? file
|
161
|
+
puts "Can't read file '#{file}'"
|
162
|
+
abort
|
163
|
+
end
|
164
|
+
case content_type = opts[:content_type].to_s
|
165
|
+
when 'json'
|
166
|
+
ds = JSONDataSource.new(file)
|
167
|
+
when 'csv'
|
168
|
+
require 'omf_oml/csv_table'
|
169
|
+
ds = OMF::OML::OmlCsvTable.create name, file, has_csv_header: true
|
170
|
+
else
|
171
|
+
puts "Unknown content type '#{content_type}'"
|
172
|
+
abort
|
173
|
+
end
|
174
|
+
OMF::Web.register_datasource ds, name: name
|
175
|
+
end
|
176
|
+
|
177
|
+
def load_repository(config)
|
178
|
+
unless id = config[:id]
|
179
|
+
puts "Missing id in respository configuration"
|
180
|
+
abort
|
181
|
+
end
|
182
|
+
unless type = config[:type]
|
183
|
+
puts "Missing 'type' in respository configuration '#{id}'"
|
184
|
+
abort
|
185
|
+
end
|
186
|
+
|
187
|
+
require 'omf-web/content/repository'
|
188
|
+
case type
|
189
|
+
when 'file'
|
190
|
+
unless top_dir = config[:top_dir]
|
191
|
+
puts "Missing 'top_dir' in respository configuration '#{id}'"
|
192
|
+
abort
|
193
|
+
end
|
194
|
+
unless top_dir.start_with? '/'
|
195
|
+
top_dir = File.join(@top_dir, top_dir)
|
196
|
+
end
|
197
|
+
OMF::Web::ContentRepository.register_repo(id, type: :file, top_dir: top_dir)
|
198
|
+
else
|
199
|
+
puts "Unknown repository type '#{type}'. Only supporting 'file'."
|
200
|
+
abort
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
# Recusively Symbolize keys of hash
|
206
|
+
#
|
207
|
+
def _rec_sym_keys(hash)
|
208
|
+
h = {}
|
209
|
+
hash.each do |k, v|
|
210
|
+
if v.is_a? Hash
|
211
|
+
v = _rec_sym_keys(v)
|
212
|
+
elsif v.is_a? Array
|
213
|
+
v = v.map {|e| e.is_a?(Hash) ? _rec_sym_keys(e) : e }
|
214
|
+
end
|
215
|
+
h[k.to_sym] = v
|
216
|
+
end
|
217
|
+
h
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
# This class simulates a DataSource to transfer a JSON file as a database with one row and column
|
222
|
+
|
223
|
+
|
224
|
+
class JSONDataSource < OMF::Common::LObject
|
225
|
+
|
226
|
+
def initialize(file)
|
227
|
+
raw = File.read(file)
|
228
|
+
@content = [[JSON.parse(raw)]]
|
229
|
+
end
|
230
|
+
|
231
|
+
# * rows Returns an array of rows
|
232
|
+
# * on_content_changed(lambda{action, rows}) Call provided block with actions :added, :removed
|
233
|
+
# * create_sliced_table (optional)
|
234
|
+
# * release Not exactly sure when that is being used
|
235
|
+
# * schema Schema of row
|
236
|
+
# * offset
|
237
|
+
def rows
|
238
|
+
@content
|
239
|
+
end
|
240
|
+
|
241
|
+
def offset
|
242
|
+
0
|
243
|
+
end
|
244
|
+
|
245
|
+
def schema
|
246
|
+
require 'omf_oml/schema'
|
247
|
+
OMF::OML::OmlSchema.create([[:content]])
|
248
|
+
end
|
249
|
+
|
250
|
+
def on_content_changed(*args)
|
251
|
+
# do nothing
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end # class
|
255
|
+
end # module
|
data/lib/omf-web/version.rb
CHANGED
@@ -28,8 +28,8 @@ module OMF::Web::Widget
|
|
28
28
|
opts[:js_url] = "graph/js/#{vizType}.js"
|
29
29
|
opts[:js_class] = "OML.#{vizType}"
|
30
30
|
opts[:base_el] = "\##{dom_id}"
|
31
|
-
super opts
|
32
|
-
|
31
|
+
super opts
|
32
|
+
|
33
33
|
if (ds = opts.delete(:data_source))
|
34
34
|
# single source
|
35
35
|
data_sources = {:default => ds}
|
@@ -49,10 +49,10 @@ module OMF::Web::Widget
|
|
49
49
|
end
|
50
50
|
#puts "DTA_WIDGTE>>> #{opts[:data_sources].inspect}"
|
51
51
|
end
|
52
|
-
|
53
|
-
# This is the DOM id which should be used by the renderer for this widget.
|
52
|
+
|
53
|
+
# This is the DOM id which should be used by the renderer for this widget.
|
54
54
|
# We need to keep this here as various renderes at various levels may need
|
55
|
-
# to get a reference to it to allow for such functionalities as
|
55
|
+
# to get a reference to it to allow for such functionalities as
|
56
56
|
# hiding, stacking, ...
|
57
57
|
def dom_id
|
58
58
|
"w#{object_id.abs}"
|
@@ -86,7 +86,7 @@ module OMF::Web::Widget
|
|
86
86
|
# end
|
87
87
|
# end
|
88
88
|
# end
|
89
|
-
#
|
89
|
+
#
|
90
90
|
# def on_ws_close(ws)
|
91
91
|
# raise "ARE WE STILL NEEDING THIS"
|
92
92
|
# @ws = nil
|