omf_web 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/doc/tutorial/tut01/hello_world.yaml +12 -0
- data/doc/tutorial/tut02/gen.csv +1 -0
- data/doc/tutorial/tut02/simple_graph.yaml +28 -0
- data/doc/tutorial/tut03/stacked.yaml +37 -0
- data/doc/tutorial/tut04/create_db.rb +56 -0
- data/doc/tutorial/tut04/gen.sq3 +0 -0
- data/doc/tutorial/tut04/realtime_graph.yaml +47 -0
- data/doc/tutorial/tut05/gen_maxs-laptop-3.local-35511_foo_2013-12-19t19.20.46+1100 +125 -0
- data/doc/tutorial/tut05/monitor_generator_oml.rb +36 -0
- data/doc/tutorial/tut05/realtime_graph_omsp.yaml +47 -0
- data/lib/omf-web/content/git_repository.rb +3 -3
- data/lib/omf-web/content/irods_repository.rb +2 -1
- data/lib/omf-web/content/repository.rb +5 -0
- data/lib/omf-web/content/static_repository.rb +1 -1
- data/lib/omf-web/data_source_proxy.rb +18 -10
- data/lib/omf-web/session_store.rb +18 -0
- data/lib/omf-web/theme/bright/code_renderer.rb +1 -1
- data/lib/omf-web/thin/server.rb +100 -34
- data/lib/omf-web/version.rb +1 -1
- data/omf_web.gemspec +1 -0
- data/share/htdocs/graph/js/abstract_chart.js +8 -1
- data/share/htdocs/graph/js/abstract_multiple_datasource_chart.js +82 -0
- data/share/htdocs/graph/js/abstract_widget.js +13 -11
- data/share/htdocs/js/data_source3.js +6 -6
- data/share/htdocs/js/data_source_repo.js +2 -2
- metadata +211 -216
- data/doc/tutorial/tut01/hello_world.rb +0 -27
- data/doc/tutorial/tut02/hello_graph.rb +0 -85
- data/doc/tutorial/tut03/hello_database.rb +0 -69
- data/doc/tutorial/tut03/nmetric.sq3 +0 -0
data/lib/omf-web/thin/server.rb
CHANGED
@@ -41,12 +41,12 @@ module OMF::Web
|
|
41
41
|
|
42
42
|
def load_environment(opts)
|
43
43
|
unless cf = opts[:omf_config_file]
|
44
|
-
|
44
|
+
fatal "Missing config file"
|
45
45
|
abort
|
46
46
|
end
|
47
47
|
|
48
48
|
unless File.readable? cf
|
49
|
-
|
49
|
+
fatal "Can't read config file '#{cf}'"
|
50
50
|
abort
|
51
51
|
end
|
52
52
|
|
@@ -75,18 +75,32 @@ module OMF::Web
|
|
75
75
|
load_repository(repo)
|
76
76
|
end
|
77
77
|
|
78
|
-
|
79
|
-
|
78
|
+
widgets = cfg[:widgets] || []
|
79
|
+
if (tabs = cfg[:tabs])
|
80
|
+
tabs.each {|t| t[:top_level] = true}
|
81
|
+
widgets += tabs
|
82
|
+
end
|
83
|
+
if widgets.empty?
|
84
|
+
fatal "Can't find 'widgets' or 'tabs' section in config file '#{cf}' - #{cfg.keys}"
|
80
85
|
abort
|
81
86
|
end
|
82
|
-
|
83
|
-
|
87
|
+
widgets.each do |w|
|
88
|
+
register_widget w
|
89
|
+
end
|
90
|
+
|
91
|
+
# Any other file to load before opening shop
|
92
|
+
if init = cfg[:init]
|
93
|
+
unless init.is_a? Enumerable
|
94
|
+
init = [init]
|
95
|
+
end
|
96
|
+
init.each {|f| load_ruby_file(f) }
|
84
97
|
end
|
98
|
+
|
85
99
|
end
|
86
100
|
|
87
101
|
def load_datasource(config)
|
88
102
|
unless id = config[:id]
|
89
|
-
|
103
|
+
fatal "Missing id in datasource configuration"
|
90
104
|
abort
|
91
105
|
end
|
92
106
|
if config[:database]
|
@@ -95,6 +109,8 @@ module OMF::Web
|
|
95
109
|
load_datasource_file(id, config)
|
96
110
|
elsif config[:omsp]
|
97
111
|
load_omsp_endpoint(id, config)
|
112
|
+
elsif config[:generator]
|
113
|
+
load_generator(id, config[:generator])
|
98
114
|
else
|
99
115
|
abort "Unknown datasource type - #{config}"
|
100
116
|
end
|
@@ -102,13 +118,13 @@ module OMF::Web
|
|
102
118
|
|
103
119
|
def load_database(id, config)
|
104
120
|
unless db_cfg = config[:database]
|
105
|
-
|
121
|
+
fatal "Missing database configuration in datasource '#{config}'"
|
106
122
|
abort
|
107
123
|
end
|
108
124
|
db = get_database(db_cfg)
|
109
125
|
if query_s = config[:query]
|
110
126
|
unless schema = config[:schema]
|
111
|
-
|
127
|
+
fatal "Missing schema configuration in datasource '#{config}'"
|
112
128
|
abort
|
113
129
|
end
|
114
130
|
require 'omf_oml/schema'
|
@@ -116,12 +132,12 @@ module OMF::Web
|
|
116
132
|
table = db.create_table(id, config)
|
117
133
|
else
|
118
134
|
unless table_name = config.delete(:table)
|
119
|
-
|
135
|
+
fatal "Missing 'table' in datasource configuration '#{config}'"
|
120
136
|
abort
|
121
137
|
end
|
122
138
|
config[:name] = id
|
123
139
|
unless table = db.create_table(table_name, config)
|
124
|
-
|
140
|
+
fatal "Can't find table '#{table_name}' in database '#{db_cfg}'"
|
125
141
|
abort
|
126
142
|
end
|
127
143
|
end
|
@@ -136,23 +152,21 @@ module OMF::Web
|
|
136
152
|
if db = @databases[config]
|
137
153
|
return db
|
138
154
|
end
|
139
|
-
|
140
|
-
abort
|
141
|
-
end
|
142
|
-
unless id = config.delete(:id)
|
143
|
-
puts "Missing id in database configuration"
|
155
|
+
fatal "Database '#{config}' not defined - (#{@databases.keys})"
|
144
156
|
abort
|
145
157
|
end
|
146
|
-
if
|
147
|
-
|
158
|
+
if id = config.delete(:id)
|
159
|
+
if db = @databases[id.to_s] # already known
|
160
|
+
return db
|
161
|
+
end
|
148
162
|
end
|
149
163
|
|
150
164
|
# unless id = config[:id]
|
151
|
-
#
|
165
|
+
# fatal "Database '#{config}' not defined - (#{@databases.keys})"
|
152
166
|
# abort
|
153
167
|
# end
|
154
168
|
unless url = config.delete(:url)
|
155
|
-
|
169
|
+
fatal "Missing URL for database '#{id}'"
|
156
170
|
abort
|
157
171
|
end
|
158
172
|
if url.start_with?('sqlite:') && ! url.start_with?('sqlite:/')
|
@@ -162,9 +176,11 @@ module OMF::Web
|
|
162
176
|
config[:check_interval] ||= 3.0
|
163
177
|
puts "URL: #{url} - #{config}"
|
164
178
|
begin
|
165
|
-
|
179
|
+
db = OMF::OML::OmlSqlSource.new(url, config)
|
180
|
+
@databases[id] = db if id
|
181
|
+
return db
|
166
182
|
rescue Exception => ex
|
167
|
-
|
183
|
+
fatal "Can't connect to database '#{id}' - #{ex}"
|
168
184
|
abort
|
169
185
|
end
|
170
186
|
end
|
@@ -175,24 +191,27 @@ module OMF::Web
|
|
175
191
|
#
|
176
192
|
def load_datasource_file(name, opts)
|
177
193
|
unless file = opts[:file]
|
178
|
-
|
194
|
+
fatal "Data source file is not defined in '#{opts}'"
|
179
195
|
abort
|
180
196
|
end
|
181
197
|
unless file.start_with? '/'
|
182
|
-
|
198
|
+
File.absolute_path(file, @cfg_dir)
|
183
199
|
end
|
184
200
|
unless File.readable? file
|
185
|
-
|
201
|
+
fatal "Can't read file '#{file}'"
|
186
202
|
abort
|
187
203
|
end
|
188
|
-
|
204
|
+
unless content_type = opts[:content_type]
|
205
|
+
content_type = File.extname(file)[1 .. -1]
|
206
|
+
end
|
207
|
+
case content_type.to_s
|
189
208
|
when 'json'
|
190
209
|
ds = JSONDataSource.new(file)
|
191
210
|
when 'csv'
|
192
211
|
require 'omf_oml/csv_table'
|
193
212
|
ds = OMF::OML::OmlCsvTable.create name, file, has_csv_header: true
|
194
213
|
else
|
195
|
-
|
214
|
+
fatal "Unknown content type '#{content_type}'"
|
196
215
|
abort
|
197
216
|
end
|
198
217
|
OMF::Web.register_datasource ds, name: name
|
@@ -201,21 +220,57 @@ module OMF::Web
|
|
201
220
|
def load_omsp_endpoint(id, config)
|
202
221
|
oconfig = config[:omsp]
|
203
222
|
unless port = oconfig[:port]
|
204
|
-
|
223
|
+
fatal "Need port in OMSP definition '#{oconfig}' - datasource '#{id}'"
|
205
224
|
abort
|
206
225
|
end
|
207
226
|
ep = @omsp_endpoints[port] ||= OmspEndpointProxy.new(port)
|
208
227
|
ep.add_datasource(id, config)
|
209
228
|
end
|
210
229
|
|
230
|
+
def load_generator(id, config)
|
231
|
+
if file = config[:load]
|
232
|
+
load_ruby_file(file)
|
233
|
+
end
|
234
|
+
unless klass_name = config[:class]
|
235
|
+
fatal "Missing 'class' options for generator '#{id}'"
|
236
|
+
abort
|
237
|
+
end
|
238
|
+
klass = nil
|
239
|
+
begin
|
240
|
+
klass = Kernel.const_get(klass_name)
|
241
|
+
rescue
|
242
|
+
fatal "Can't find class '#{klass_name}' referenced in generator '#{id}'"
|
243
|
+
abort
|
244
|
+
end
|
245
|
+
opts = config[:opts] || {}
|
246
|
+
debug "Creating new generator '#{id}' from '#{klass_name}' with '#{opts}'"
|
247
|
+
unless klass.respond_to? :create_data_source
|
248
|
+
fatal "Class '#{klass_name}' doesn't have a 'create_data_source' class method."
|
249
|
+
abort
|
250
|
+
end
|
251
|
+
klass.create_data_source(id, opts)
|
252
|
+
end
|
253
|
+
|
254
|
+
def load_ruby_file(file)
|
255
|
+
unless file.start_with? '/'
|
256
|
+
file = File.absolute_path(file, @cfg_dir)
|
257
|
+
end
|
258
|
+
unless File.readable? file
|
259
|
+
fatal "Can't read file '#{file}'"
|
260
|
+
abort
|
261
|
+
end
|
262
|
+
debug "Loading #{file}"
|
263
|
+
load(file)
|
264
|
+
end
|
265
|
+
|
211
266
|
|
212
267
|
def load_repository(config)
|
213
268
|
unless id = config[:id]
|
214
|
-
|
269
|
+
fatal "Missing id in respository configuration"
|
215
270
|
abort
|
216
271
|
end
|
217
272
|
unless type = config[:type]
|
218
|
-
|
273
|
+
fatal "Missing 'type' in respository configuration '#{id}'"
|
219
274
|
abort
|
220
275
|
end
|
221
276
|
|
@@ -223,20 +278,31 @@ module OMF::Web
|
|
223
278
|
case type
|
224
279
|
when 'file'
|
225
280
|
unless top_dir = config[:top_dir]
|
226
|
-
|
281
|
+
fatal "Missing 'top_dir' in respository configuration '#{id}'"
|
227
282
|
abort
|
228
283
|
end
|
229
284
|
unless top_dir.start_with? '/'
|
230
|
-
top_dir = File.join(@
|
285
|
+
top_dir = File.join(@cfg_dir, top_dir)
|
231
286
|
end
|
287
|
+
#puts "TOP>>> #{File.absolute_path top_dir}"
|
232
288
|
OMF::Web::ContentRepository.register_repo(id, type: :file, top_dir: top_dir)
|
233
289
|
else
|
234
|
-
|
290
|
+
fatal "Unknown repository type '#{type}'. Only supporting 'file'."
|
235
291
|
abort
|
236
292
|
end
|
237
293
|
|
238
294
|
end
|
239
295
|
|
296
|
+
def register_widget(w)
|
297
|
+
unless w[:id]
|
298
|
+
require 'digest/md5'
|
299
|
+
w[:id] = Digest::MD5.hexdigest(w[:name] || "tab#{rand(10000)}")[0, 8]
|
300
|
+
end
|
301
|
+
w[:top_level] = true
|
302
|
+
w[:type] ||= 'layout/one_column'
|
303
|
+
OMF::Web.register_widget w
|
304
|
+
end
|
305
|
+
|
240
306
|
# Recusively Symbolize keys of hash
|
241
307
|
#
|
242
308
|
def _rec_sym_keys(hash)
|
@@ -330,4 +396,4 @@ module OMF::Web
|
|
330
396
|
end # class OmspEndpointProxy
|
331
397
|
|
332
398
|
end # class
|
333
|
-
end # module
|
399
|
+
end # module
|
data/lib/omf-web/version.rb
CHANGED
data/omf_web.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.add_runtime_dependency "websocket-rack", "~> 0.4.0"
|
35
35
|
s.add_runtime_dependency "rack-accept", "~> 0.4.0"
|
36
36
|
s.add_runtime_dependency "i18n"
|
37
|
+
s.add_runtime_dependency "rake"
|
37
38
|
|
38
39
|
# Do we need the next two dependencies?
|
39
40
|
#s.add_runtime_dependency "sqlite3", "~> 1.3.6"
|
@@ -77,6 +77,13 @@ define(["graph/abstract_widget"], function (abstract_widget) {
|
|
77
77
|
this.update();
|
78
78
|
},
|
79
79
|
|
80
|
+
configure_base_layer: function(vis) {
|
81
|
+
this.base_layer = vis.append("svg:g");
|
82
|
+
if (this.base_css_class) {
|
83
|
+
this.base_layer.attr("class", this.base_css_class);
|
84
|
+
}
|
85
|
+
},
|
86
|
+
|
80
87
|
_resize_base_el: function(w, h) {
|
81
88
|
// Do not add margins to the base_el, but to the inside of the SVG panes
|
82
89
|
this.w = w;
|
@@ -290,4 +297,4 @@ define(["graph/abstract_widget"], function (abstract_widget) {
|
|
290
297
|
});
|
291
298
|
|
292
299
|
return abstract_chart;
|
293
|
-
});
|
300
|
+
});
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
define(["graph/abstract_chart"], function(abstract_chart) {
|
3
|
+
|
4
|
+
var graph = abstract_chart.extend({
|
5
|
+
// MAKE SURE THIS IS DEFINED IN SUB CLASS
|
6
|
+
data_source_names: ['change', 'me'],
|
7
|
+
|
8
|
+
initialize: function(opts) {
|
9
|
+
graph.__super__.initialize.call(this, opts);
|
10
|
+
},
|
11
|
+
|
12
|
+
// Find the appropriate data source and bind to it
|
13
|
+
//
|
14
|
+
init_data_source: function() {
|
15
|
+
var self = this;
|
16
|
+
var o = self.opts;
|
17
|
+
var sources = o.data_sources;
|
18
|
+
var ds_names = self.data_source_names;
|
19
|
+
|
20
|
+
if (! (sources instanceof Array)) {
|
21
|
+
throw "Expected an array";
|
22
|
+
}
|
23
|
+
if (sources.length != ds_names.length) {
|
24
|
+
throw "Expected '" + ds_names.length + "' data source, but only found '" + sources.length + "'.";
|
25
|
+
}
|
26
|
+
|
27
|
+
var dsh = self.data_source = {};
|
28
|
+
_.map(sources, function(s) {
|
29
|
+
dsh[s.name] = self.init_single_data_source(s);
|
30
|
+
});
|
31
|
+
_.each(ds_names, function(ds_name) {
|
32
|
+
if (dsh[ds_name] == undefined) {
|
33
|
+
throw "Missing data source '" + ds_name + "'. Check for spelling of name.";
|
34
|
+
}
|
35
|
+
});
|
36
|
+
},
|
37
|
+
|
38
|
+
process_schema: function() {
|
39
|
+
var self = this;
|
40
|
+
var ds_names = self.data_source_names;
|
41
|
+
|
42
|
+
var schemas = self.schema = {};
|
43
|
+
_.each(ds_names, function(ds_name) {
|
44
|
+
schemas[ds_name] = self.process_single_schema(self.data_source[ds_name]);
|
45
|
+
});
|
46
|
+
|
47
|
+
var om = self.opts.mapping;
|
48
|
+
if (om == undefined) {
|
49
|
+
throw "Missing mapping instructions in 'options'.";
|
50
|
+
}
|
51
|
+
self.mapping = {};
|
52
|
+
_.each(ds_names, function(ds_name) {
|
53
|
+
var mapping = om[ds_name];
|
54
|
+
if (mapping == undefined) {
|
55
|
+
throw "Missing mapping instructions in 'options' for '" + ds_name + "'.";
|
56
|
+
}
|
57
|
+
self.mapping[ds_name] = self.process_single_mapping(ds_name, mapping, self.decl_properties[ds_name]);
|
58
|
+
});
|
59
|
+
},
|
60
|
+
|
61
|
+
/*
|
62
|
+
* Return schema for +stream+.
|
63
|
+
*/
|
64
|
+
schema_for_stream: function(stream) {
|
65
|
+
var schema = this.schema[stream];
|
66
|
+
return schema;
|
67
|
+
},
|
68
|
+
|
69
|
+
update: function() {
|
70
|
+
var data = {};
|
71
|
+
var self = this;
|
72
|
+
|
73
|
+
_.each(self.data_source_names, function(ds_name) {
|
74
|
+
data[ds_name] = self.data_source[ds_name].rows();
|
75
|
+
}, self);
|
76
|
+
self.redraw(data);
|
77
|
+
},
|
78
|
+
|
79
|
+
}); // end of graph
|
80
|
+
|
81
|
+
return graph;
|
82
|
+
});
|
@@ -31,7 +31,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
31
31
|
x: 0,
|
32
32
|
y: 0
|
33
33
|
},
|
34
|
-
}
|
34
|
+
};
|
35
35
|
},
|
36
36
|
|
37
37
|
//base_css_class: 'oml-chart',
|
@@ -93,6 +93,8 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
93
93
|
}
|
94
94
|
this._resize_base_el(w,h);
|
95
95
|
|
96
|
+
OHUB.trigger(o.id + '.resize', {width: w, height: h});
|
97
|
+
|
96
98
|
return this;
|
97
99
|
},
|
98
100
|
|
@@ -120,10 +122,10 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
120
122
|
var self = this;
|
121
123
|
|
122
124
|
if (! (sources instanceof Array)) {
|
123
|
-
throw "Expected an array"
|
125
|
+
throw "Expected an array";
|
124
126
|
}
|
125
127
|
if (sources.length != 1) {
|
126
|
-
throw "Can only process a SINGLE source"
|
128
|
+
throw "Can only process a SINGLE source";
|
127
129
|
}
|
128
130
|
this.data_source = this.init_single_data_source(sources[0]);
|
129
131
|
},
|
@@ -136,7 +138,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
136
138
|
var self = this;
|
137
139
|
OHUB.bind(ds.event_name, function() {
|
138
140
|
self.update();;
|
139
|
-
})
|
141
|
+
});
|
140
142
|
return ds;
|
141
143
|
},
|
142
144
|
|
@@ -166,7 +168,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
166
168
|
_.map(properties_decl, function(a) {
|
167
169
|
var pname = a[0]; var type = a[1]; var def = a[2];
|
168
170
|
var descr = om[pname];
|
169
|
-
m[pname] = self.create_mapping(pname, descr, source_name, type, def)
|
171
|
+
m[pname] = self.create_mapping(pname, descr, source_name, type, def);
|
170
172
|
});
|
171
173
|
return m;
|
172
174
|
},
|
@@ -194,7 +196,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
194
196
|
create_mapping: function(mname, descr, stream, type, def) {
|
195
197
|
var self = this;
|
196
198
|
if (descr == undefined && typeof(def) == 'object') {
|
197
|
-
descr = def
|
199
|
+
descr = def;
|
198
200
|
}
|
199
201
|
if (descr == undefined || typeof(descr) != 'object' ) {
|
200
202
|
if (type == 'index') {
|
@@ -208,7 +210,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
208
210
|
var cf_i = cf();
|
209
211
|
value = function(x) {
|
210
212
|
return cf_i(x);
|
211
|
-
}
|
213
|
+
};
|
212
214
|
}
|
213
215
|
return value;
|
214
216
|
}
|
@@ -256,7 +258,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
256
258
|
var t = index_f(join);
|
257
259
|
//var r = t[join];
|
258
260
|
return t;
|
259
|
-
}
|
261
|
+
};
|
260
262
|
} else {
|
261
263
|
if (descr.values) {
|
262
264
|
// provided custom mapping for values
|
@@ -264,7 +266,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
264
266
|
var def_value = descr['default'];
|
265
267
|
return function(x) {
|
266
268
|
return values[x] || def_value;
|
267
|
-
}
|
269
|
+
};
|
268
270
|
}
|
269
271
|
var pname = descr.property;
|
270
272
|
if (pname == undefined) {
|
@@ -331,7 +333,7 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
331
333
|
if (source[prop] == null) {
|
332
334
|
source[prop] = defaults[prop];
|
333
335
|
} else if((typeof(source[prop]) == 'object') && defaults[prop]) {
|
334
|
-
this.deep_defaults(source[prop], defaults[prop])
|
336
|
+
this.deep_defaults(source[prop], defaults[prop]);
|
335
337
|
}
|
336
338
|
}
|
337
339
|
return source;
|
@@ -341,4 +343,4 @@ define(['omf/data_source_repo', 'vendor/d3/d3'], function(ds_repo) {
|
|
341
343
|
});
|
342
344
|
|
343
345
|
return abstract_widget;
|
344
|
-
})
|
346
|
+
});
|
@@ -13,11 +13,11 @@ function omf_web_data_source(opts) {
|
|
13
13
|
version: "0.1",
|
14
14
|
name: name,
|
15
15
|
schema: schema,
|
16
|
-
rows: function() {return rows},
|
16
|
+
rows: function() { return rows; },
|
17
17
|
index_for_column: index_for_column,
|
18
18
|
is_dynamic: is_dynamic,
|
19
19
|
event_name: event_name,
|
20
|
-
}
|
20
|
+
};
|
21
21
|
|
22
22
|
var indexes = {};
|
23
23
|
var unique_index_check = null;
|
@@ -30,18 +30,18 @@ function omf_web_data_source(opts) {
|
|
30
30
|
var index = indexes[i];
|
31
31
|
if (!index) {
|
32
32
|
index = indexes[i] = {};
|
33
|
-
_.each(rows, function(r) { index[r[i]] = r; })
|
33
|
+
_.each(rows, function(r) { index[r[i]] = r; });
|
34
34
|
}
|
35
35
|
return function(key) {
|
36
36
|
return indexes[i][key]; // need fresh lookup as we may redo index
|
37
|
-
}
|
37
|
+
};
|
38
38
|
}
|
39
39
|
|
40
40
|
function update_indexes() {
|
41
41
|
// This can most likley be done more efficiently if we consider what has changed
|
42
42
|
_.each(indexes, function(ignore, i) {
|
43
43
|
var index = indexes[i] = {};
|
44
|
-
_.each(rows, function(r) { index[r[i]] = r; })
|
44
|
+
_.each(rows, function(r) { index[r[i]] = r; });
|
45
45
|
});
|
46
46
|
}
|
47
47
|
|
@@ -53,7 +53,7 @@ function omf_web_data_source(opts) {
|
|
53
53
|
var opts = _;
|
54
54
|
var interval = -1;
|
55
55
|
if (typeof(opts) == 'number') {
|
56
|
-
interval = opts
|
56
|
+
interval = opts;
|
57
57
|
} else if (opts == true) {
|
58
58
|
interval = 3;
|
59
59
|
}
|
@@ -7,7 +7,7 @@ define(['omf/data_source3'], function(data_source) {
|
|
7
7
|
function context() {};
|
8
8
|
|
9
9
|
context.register = function(opts) {
|
10
|
-
var id = opts.id || opts.name;
|
10
|
+
var id = opts.id || opts.stream || opts.name;
|
11
11
|
if (sources[id] == null) {
|
12
12
|
sources[id] = data_source(opts);
|
13
13
|
}
|
@@ -19,7 +19,7 @@ define(['omf/data_source3'], function(data_source) {
|
|
19
19
|
var dynamic = false;
|
20
20
|
|
21
21
|
if (typeof(ds_descr) == 'object') {
|
22
|
-
name = ds_descr.id || ds_descr.name;
|
22
|
+
name = ds_descr.id || ds_descr.stream || ds_descr.name;
|
23
23
|
dynamic = ds_descr.dynamic;
|
24
24
|
} else {
|
25
25
|
name = ds_descr;
|