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
data/README.md
CHANGED
@@ -1,25 +1,180 @@
|
|
1
1
|
# OMF Web
|
2
2
|
|
3
|
-
|
3
|
+
This gem provides the componetes for building a web-based data visualization service.
|
4
|
+
The typical use case is to allow a user to investigate a data set stored in one or more databases
|
5
|
+
as well as life data streams.
|
6
|
+
|
7
|
+
The core components are:
|
4
8
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
+
* A **DataSource** which holds a specific data set organised as a table. It is defined
|
10
|
+
by a *Schema* and rows may be dynamically added and removed.
|
11
|
+
|
12
|
+
* A [**Widget**](#widgets) which defines what is displayed on parts of a web page.
|
9
13
|
|
10
|
-
|
14
|
+
* A **Renderer** which defines the conversion of a widget's state into HTML.
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
This will start a web server at port 3000. Point your browser there and you should see somthing like:
|
16
|
+
* A **Theme** which defines what renderes to use to maintain a common look and feel
|
17
|
+
across a single web site.
|
16
18
|
|
17
|
-
|
19
|
+
A visualization web site based on this components is normally deployed on a rack-based
|
20
|
+
web server, such as [Thin](http://code.macournoyer.com/thin/).
|
21
|
+
A sample *config.ru* file can be found in the gem's
|
22
|
+
"lib/omf-web" directory.
|
18
23
|
|
19
|
-
|
24
|
+
The core component is the Widget. It defines the structure of the web site and also maintains
|
25
|
+
session state. Widgets fall roughly into two categories. The *content* widgets define what is
|
26
|
+
shown in a certain area on a page, while the *layout* widget define how all the content widgets
|
27
|
+
are arranged. A web site is defined by a tree of widgets where the internal nodes of the tree are layout
|
28
|
+
widgets and the leaf nodes are content widget.
|
20
29
|
|
21
|
-
|
30
|
+
This tree is normally defined by one or more YAML files which at start-up are loaded into
|
22
31
|
|
32
|
+
wd = YAML.load_file(file_name)
|
33
|
+
OMF::Web.register_widget wd[:widget]
|
34
|
+
|
35
|
+
where a basic configuration file would look like:
|
36
|
+
|
37
|
+
widget:
|
38
|
+
name: Main
|
39
|
+
top_level: true
|
40
|
+
type: layout/tabbed
|
41
|
+
widgets:
|
42
|
+
- name: Ping Line
|
43
|
+
type: data/line_chart3
|
44
|
+
data_source:
|
45
|
+
name: ping
|
46
|
+
mapping:
|
47
|
+
x_axis: oml_ts_client
|
48
|
+
y_axis: rtt
|
49
|
+
|
50
|
+
- name: Table
|
51
|
+
type: data/table2
|
52
|
+
data_source:
|
53
|
+
name: ping
|
54
|
+
|
55
|
+
and results in a web site as shown below:
|
56
|
+
|
57
|
+
__add screen shot here__
|
58
|
+
|
59
|
+
## Widgets <a id="widgets"/>
|
60
|
+
|
61
|
+
The above configuration file describes three widgets. A *layout* widget of type "layout/tabbed" and two *content*
|
62
|
+
widget of type "data/line_chart3" and "data/table2" respectively. A *tabbed* layout will show one its content
|
63
|
+
widgets and provide a selector for the user to switch between the available ones. In the above example, the
|
64
|
+
choices are "Ping Line" and "Table".
|
65
|
+
|
66
|
+
The content widgets in the above example are both data widgets. Data widgets are associated with one or more
|
67
|
+
data sources. The sub type (separated by a "/") defines the visualizaton method used. In the above example, the
|
68
|
+
content of the data source "ping" can be visualized both as a line chart ("type/line_chart3") or in a table
|
69
|
+
format ("type/table"). Most widgets will require additional parameter settings. For instance, the line chart needs
|
70
|
+
to be instructed which of the columns of the the *data_source* should be mapped to which coordinate ("mapping").
|
71
|
+
|
72
|
+
All widget share the following configuration options:
|
73
|
+
|
74
|
+
|
75
|
+
* __id: string__ (optional)
|
76
|
+
Each widget can be given an id which needs to be unique within a web application. A widget can be
|
77
|
+
inserted into the widget tree at more than one location by refering to it's ID via the __id_ref__ option.
|
78
|
+
|
79
|
+
* __name: string__ (required)
|
80
|
+
The name of a widget is often used by the Theme to label a widget.
|
81
|
+
|
82
|
+
* __type: string__ (required)
|
83
|
+
The type defines the type of widget to be used.
|
84
|
+
|
85
|
+
## Layout Widgets <a id="layout_widgets"/>
|
86
|
+
|
87
|
+
A layout widget implements a specific strategy to arrange its children widget within a certain part of a web page.
|
88
|
+
It is permissble for some or all of the children widgets to be layout widgets themselves.
|
89
|
+
|
90
|
+
All layout widgets are of type 'layout' with an additional sub type identifying the specific layout startegy. They also
|
91
|
+
share the following configuration options:
|
92
|
+
|
93
|
+
* __top_level: boolean__ (optional)
|
94
|
+
When set to true it defines the layout of an entire web page. It will be up to the associated Theme to list all
|
95
|
+
defined pages (top-level widgets) and how to switch between them.
|
96
|
+
|
97
|
+
* __priority: integer__ (optional)
|
98
|
+
The priority is only relevant when top_level is set to true and defines the ranking order among all top level
|
99
|
+
layouts. It is normally used by the Theme to rank the list of pages.
|
100
|
+
|
101
|
+
* __widgets: array of widgets__ (required)
|
102
|
+
The widgets option takes an array of widget defintions or references to widgets defined somewhere else.
|
103
|
+
|
104
|
+
* __render: array of render options__ (optional)
|
105
|
+
Render options are used by the _Theme_ to control various aspects of how the layout and its children are being
|
106
|
+
rendered. See the documention of the respective _Theme_ for further information.
|
107
|
+
|
108
|
+
The following layout widgets are currently available:
|
109
|
+
|
110
|
+
* [One column layout](#one_column_layout)
|
111
|
+
* [Two column layout](#two_column_layout)
|
112
|
+
* [Flow layout](#flow_layout)
|
113
|
+
* [Tabbed layout](#tabbed_layout)
|
114
|
+
* [Stacked layout](#stacked_layout)
|
115
|
+
|
116
|
+
### One Column Layout (type: layout/one_column)<a id="one_column_layout"/>
|
117
|
+
|
118
|
+
The one column layout arranges its children in a vertical session with each children widget being able to
|
119
|
+
span the entire width given to its parent.
|
120
|
+
|
121
|
+
### Two column layout (type: layout/two_columns/XX_YY)<a id="two_column_layout"/>
|
122
|
+
|
123
|
+
The two column layout splits its layout space into two columns and renders a _left_ array of widgets in the
|
124
|
+
left column, and a _right_ array of widgets in the right column. Each column is rendered identical to
|
125
|
+
the behavior defined in the one column layout. The third level type declaration defines on how the space is
|
126
|
+
divided among the two columns. The following options are available where the first number defines the portion
|
127
|
+
in percent taken up by the left column and the right column given the reminder.
|
128
|
+
|
129
|
+
* layout/two_columns/50_50
|
130
|
+
* layout/two_columns/66_33
|
131
|
+
* layout/two_columns/33_66
|
132
|
+
* layout/two_columns/75_25
|
133
|
+
* layout/two_columns/25_75
|
134
|
+
|
135
|
+
The __widgets__ option should contain two named arrays, __left__ and __right__, each containing a list of widgets
|
136
|
+
to be rendered vertically in the respective column.
|
137
|
+
|
138
|
+
### Flow Layout <a id="flow_column_layout"/>
|
139
|
+
|
140
|
+
The flow layout arranges its widgets first horizontally from left to right. If a widget's width would exceed
|
141
|
+
the width of the entire layout, it will be rendered at the left edge of a new "line" below the previous widgets.
|
142
|
+
Changing the width of the layout image may result in a reflow of all the widgets.
|
143
|
+
|
144
|
+
### Tabbed Layout <a id="tabbed_column_layout"/>
|
145
|
+
|
146
|
+
A tabbed layout is only rendering one of the widgets and a theme-dependent mechanism to select which widget is being shown.
|
147
|
+
Selecting a new widget will likely result in a new page request from the server. However, this is up to the
|
148
|
+
|
149
|
+
### Stacked Layout <a id="stacked_column_layout"/>
|
150
|
+
|
151
|
+
A stacked layout is very similar as the tabbed layout as it only shows one of its children widgets at any time. The main
|
152
|
+
difference is in how the Theme renders it. As a general rule, a stacked layout is used for providing multiple,
|
153
|
+
alternative represenatations of the same data set. As a consequence, the theme will provide a 'light' switching
|
154
|
+
mechanism using the same surrounding chrome, often including a common title. By refering to the same data set,
|
155
|
+
switching among presetnation styles will normally not require a call back to the server.
|
156
|
+
|
157
|
+
## Content Widgets <a id="content_widgets"/>
|
158
|
+
|
159
|
+
_Some Introductory Text_
|
160
|
+
|
161
|
+
The following content widgets are currently available:
|
162
|
+
|
163
|
+
* [Data widget](#data_widget)
|
164
|
+
|
165
|
+
### Data Widget <a id="data_widget"/>
|
166
|
+
|
167
|
+
* __data_source__: _data_source_ (required)
|
168
|
+
The data source providing the data to be visualised by this widget. See ??? for a more
|
169
|
+
thorough description of the additonal parameters to further describe the data source in
|
170
|
+
the context of this widget.
|
171
|
+
|
172
|
+
* __mapping__: _mapping_decl_ (required)
|
173
|
+
Declares the mapping of columns in the data source to visual properties of the widget.
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
-------------------------------------------------------------------------------------
|
23
178
|
** These notes are way out of date. Look at the 'demo' example for some guidance **
|
24
179
|
|
25
180
|
This module is used to define and run a web server which allows a user to explore and
|
data/bin/omf-web-basic
CHANGED
@@ -4,10 +4,10 @@ OMF_VERSION = 5.4
|
|
4
4
|
|
5
5
|
# $LOAD_PATH
|
6
6
|
$: << "/usr/share/omf-common-#{OMF_VERSION}"
|
7
|
-
$: << "/usr/share/
|
7
|
+
$: << "/usr/share/omf_oml-#{OMF_VERSION}"
|
8
8
|
$: << "/usr/share/omf-web-#{OMF_VERSION}"
|
9
9
|
|
10
|
-
ENV['GEM_PATH'] = "/usr/share/omf-common-#{OMF_VERSION}/gems/1.8:/usr/share/
|
10
|
+
ENV['GEM_PATH'] = "/usr/share/omf-common-#{OMF_VERSION}/gems/1.8:/usr/share/omf_oml-#{OMF_VERSION}/gems/1.8:/usr/share/omf-web-#{OMF_VERSION}/gems/1.8"
|
11
11
|
|
12
12
|
require 'rubygems'
|
13
13
|
gem 'rack', '1.3.5'
|
@@ -19,7 +19,7 @@ require 'yaml'
|
|
19
19
|
require 'ostruct'
|
20
20
|
require 'optparse'
|
21
21
|
|
22
|
-
require '
|
22
|
+
require 'omf_oml/table'
|
23
23
|
|
24
24
|
require 'omf-web/tabbed_server'
|
25
25
|
require 'omf-web/tab/code/code_service'
|
data/doc/index.md
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
# OMF Web
|
2
|
+
|
3
|
+
This gem provides the componetes for building a web-based data visualization service.
|
4
|
+
The typical use case is to allow a user to investigate a data set stored in one or more databases
|
5
|
+
as well as life data streams.
|
6
|
+
|
7
|
+
The core components are:
|
8
|
+
|
9
|
+
* A +DataSource+ which holds a specific data set organised as a table. It is defined
|
10
|
+
by a +Schema+ and rows may be dynamically added and removed.
|
11
|
+
|
12
|
+
* A +Widget+ which defines what is displayed on parts of a web page.
|
13
|
+
|
14
|
+
* A +Renderer+ which defines the conversion of a widget's state into HTML.
|
15
|
+
|
16
|
+
* A +Theme+ which defines what renderes to use to maintain a common look and feel
|
17
|
+
across a single web site.
|
18
|
+
|
19
|
+
A visualization web site based on this components is normally deployed on a rack-based
|
20
|
+
web server, such as +Thin+. A sample +config.ru+ file can be found in the gem's
|
21
|
+
"lib/omf-web" directory.
|
22
|
+
|
23
|
+
The core component is the Widget. It defines the structure of the web site and also maintains
|
24
|
+
session state. Widgets fall roughly into two categories. The +content+ widgets define what is
|
25
|
+
shown in a certain area on a page, while the +layout+ widget define how all the content widgets
|
26
|
+
are arranged. A web site is defined by a tree of widgets where the internal nodes of the tree are layout
|
27
|
+
widgets and the leaf nodes are content widget.
|
28
|
+
|
29
|
+
This tree is normally defined by one or more YAML files which at start-up are loaded into
|
30
|
+
|
31
|
+
wd = YAML.load_file(file_name)
|
32
|
+
OMF::Web.register_widget wd[:widget]
|
33
|
+
|
34
|
+
where a basic configuration file would look like:
|
35
|
+
|
36
|
+
widget:
|
37
|
+
name: Main
|
38
|
+
top_level: true
|
39
|
+
type: layout/tabbed
|
40
|
+
widgets:
|
41
|
+
- name: Ping Line
|
42
|
+
type: data/line_chart3
|
43
|
+
data_source:
|
44
|
+
name: ping
|
45
|
+
mapping:
|
46
|
+
x_axis: oml_ts_client
|
47
|
+
y_axis: rtt
|
48
|
+
|
49
|
+
- name: Table
|
50
|
+
type: data/table2
|
51
|
+
data_source:
|
52
|
+
name: ping
|
53
|
+
|
54
|
+
and result in a web site as shown below:
|
55
|
+
|
56
|
+
__add screen shot here__
|
57
|
+
|
58
|
+
The above configuration file describes three widgets. A layout widget of type "layout/tabbed" and two content
|
59
|
+
widget of type "data/line_chart3" and "data/table2" respectively. A "tabbed" layout will show one its content
|
60
|
+
widgets and provide a selector for the user to switch between the available ones. In the above example, the
|
61
|
+
choices are "Ping Line" and "Table".
|
62
|
+
|
63
|
+
The content widgets in the above example are both data widgets. Data widgets are associated with one or more
|
64
|
+
data sources. The sub type (separated by a "/") defines the visualizaton method used. In the above example, the
|
65
|
+
content of the data source "ping" can be visualized both as a line chart ("type/line_chart3") or in a table
|
66
|
+
format ("type/table"). Most widgets will require additional paramter settings. For instance, the line chart needs
|
67
|
+
be instructed which of the columns of the the data_source should be mapped to which coordinate ("mapping").
|
68
|
+
|
69
|
+
All widget share the following configuration options:
|
70
|
+
|
71
|
+
|
72
|
+
* __id: string__ (optional)
|
73
|
+
Each widget can be given an id which needs to be unique within a web application. A widget can be
|
74
|
+
inserted into the widget tree at more than one location by refering to it's ID via the __id_ref__ option.
|
75
|
+
|
76
|
+
* __name: string__ (required)
|
77
|
+
The name of a widget is often used by the Theme to label a widget.
|
78
|
+
|
79
|
+
* __type: string__ (required)
|
80
|
+
The type defines the type of widget to be used.
|
81
|
+
|
82
|
+
## Layout Widgets
|
83
|
+
|
84
|
+
A layout widget implements a specific strategy to arrange its children widget within a certain part of a web page.
|
85
|
+
It is permissble for some or all of the children widgets to be layout widgets themselves.
|
86
|
+
|
87
|
+
All layout widgets are of type 'layout' with an additional sub type identifying the specific layout startegy. They also
|
88
|
+
share the following configuration options:
|
89
|
+
|
90
|
+
* __top_level: boolean__ (optional)
|
91
|
+
When set to true it defines the layout of an entire web page. It will be up to the associated Theme to list all
|
92
|
+
defined pages (top-level widgets) and how to switch between them.
|
93
|
+
|
94
|
+
* __priority: integer__ (optional)
|
95
|
+
The priority is only relevant when top_level is set to true and defines the ranking order among all top level
|
96
|
+
layouts. It is normally used by the Theme to rank the list of pages.
|
97
|
+
|
98
|
+
* __widgets: array of widgets__ (required)
|
99
|
+
The widgets option takes an array of widget defintions or references to widgets defined somewhere else.
|
100
|
+
|
101
|
+
* __render: array of render options__ (optional)
|
102
|
+
Render options are used by the _Theme_ to control various aspects of how the layout and its children are being
|
103
|
+
rendered. See the documention of the respective _Theme_ for further information.
|
104
|
+
|
105
|
+
The following layout widgets are currently available:
|
106
|
+
|
107
|
+
* One column layout
|
108
|
+
* Two column layout
|
109
|
+
* Flow layout
|
110
|
+
* Tabbed layout
|
111
|
+
* Stacked layout
|
112
|
+
|
113
|
+
### One Column Layout (type: layout/one_column)
|
114
|
+
|
115
|
+
The one column layout arranges its children in a vertical session with each children widget being able to
|
116
|
+
span the entire width given to its parent.
|
117
|
+
|
118
|
+
### Two column layout (type: layout/two_columns/XX_YY)
|
119
|
+
|
120
|
+
The two column layout splits its layout space into two columns and renders a _left_ array of widgets in the
|
121
|
+
left column, and a _right_ array of widgets in the right column. Each column is rendered identical to
|
122
|
+
the behavior defined in the one column layout. The third level type declaration defines on how the space is
|
123
|
+
divided among the two columns. The following options are available where the first number defines the portion
|
124
|
+
in percent taken up by the left column and the right column given the reminder.
|
125
|
+
|
126
|
+
* layout/two_columns/50_50
|
127
|
+
* layout/two_columns/66_33
|
128
|
+
* layout/two_columns/33_66
|
129
|
+
* layout/two_columns/75_25
|
130
|
+
* layout/two_columns/25_75
|
131
|
+
|
132
|
+
The __widgets__ option should contain two named arrays, __left__ and __right__, each containing a list of widgets
|
133
|
+
to be rendered vertically in the respective column.
|
134
|
+
|
135
|
+
### Flow Layout
|
136
|
+
|
137
|
+
The flow layout arranges its widgets first horizontally from left to right. If a widget's width would exceed
|
138
|
+
the width of the entire layout, it will be rendered at the left edge of a new "line" below the previous widgets.
|
139
|
+
Changing the width of the layout image may result in a reflow of all the widgets.
|
140
|
+
|
141
|
+
### Tabbed Layout
|
142
|
+
|
143
|
+
A tabbed layout is only rendering one of the widgets and a theme-dependent mechanism to select which widget is being shown.
|
144
|
+
Selecting a new widget will likely result in a new page request from the server. However, this is up to the
|
145
|
+
|
146
|
+
### Stacked Layout
|
147
|
+
|
148
|
+
|
149
|
+
** These notes are way out of date. Look at the 'demo' example for some guidance **
|
150
|
+
|
151
|
+
This module is used to define and run a web server which allows a user to explore and
|
152
|
+
intereact with various experiments. It is a stand-alone unit communicating through
|
153
|
+
the OMF messaging framework with other entities.
|
154
|
+
|
155
|
+
The content of such a web site consists of
|
156
|
+
|
157
|
+
* A +Page+ which is essentially representing a context, most likely that of a
|
158
|
+
a single experiment.
|
159
|
+
|
160
|
+
* Pages can contain multiple +Cards+. The containing Page will contain
|
161
|
+
navigational elements to switch between those cards
|
162
|
+
|
163
|
+
* Each card contains one or more +Widgets+ which are arranged by an
|
164
|
+
associated +Formatter+ implementing a certain layout.
|
165
|
+
|
166
|
+
* A +Session+ represents the context of a specific user of the server. Users
|
167
|
+
may be associated with different privileges (not implemented) which determine
|
168
|
+
what pages they can see (and interact) and also what cards and widgets
|
169
|
+
|
170
|
+
* Theme ... explain
|
171
|
+
|
172
|
+
The actual session state is kept in the widgets. The card description (defCard)
|
173
|
+
defines the formatter to use and the type of widgets to populate it with. The
|
174
|
+
respective widgets are initialised the first time such a card is rendered
|
175
|
+
within a user session and kept in the session to be reused the next time
|
176
|
+
the user requests the card. The primary decision for this design is the fact
|
177
|
+
that many widgets visualize dynamic state and any updates to that should be
|
178
|
+
propagated to the user's web browser if that widget instance is visisble there.
|
179
|
+
Therefore, many widgets either establish web sockets back to the server or
|
180
|
+
issue periodic AJAX calls. Maintaining interal widget state will also speed
|
181
|
+
up the rendering of a specific card. The drawback of this design is that it
|
182
|
+
can create substantial state for each user session. Given the envisioned use
|
183
|
+
case this is not really a concern as the number of active sessions will be small.
|
184
|
+
However, we do envision use cases where the server will run for a long time, which
|
185
|
+
in term will require pruning of 'dead' sessions and the associated freeing of
|
186
|
+
state.
|
187
|
+
|
188
|
+
With such a desing the main extension point will be around widgets and to a lesser
|
189
|
+
extend around formaters and themes.
|
190
|
+
|
191
|
+
As the primary objective of this package is to visualize and interact with dynamic
|
192
|
+
system state we introduce a few more concepts.
|
193
|
+
|
194
|
+
* An +Event+ is a time-stamped tuple (hash) which describes the properties of a
|
195
|
+
specific event whch occured at a certain time (timestamp).
|
196
|
+
|
197
|
+
* An +EventList+ which holds an (ordered ?) list of Events with every event belonging
|
198
|
+
to the same schema. It will be the primary source of information for widgets.
|
199
|
+
|
200
|
+
It provides means for other objects to subscribe to receive notification when the
|
201
|
+
list changes. There is also an associated policy on how to maintain the list
|
202
|
+
(e.g. keep only the last N recent events). In addition, an event list may subscribe
|
203
|
+
to the OMF messaging framework to receive events created by system and other
|
204
|
+
experiment services.
|
205
|
+
|
@@ -3,7 +3,7 @@ require 'omf-common/mobject2'
|
|
3
3
|
OMF::Common::Loggable.init_log 'demo'
|
4
4
|
|
5
5
|
|
6
|
-
require '
|
6
|
+
require 'omf_oml/network'
|
7
7
|
|
8
8
|
# require 'omf-web/tabbed_server'
|
9
9
|
# require 'omf-web/tab/graph/init'
|
@@ -47,7 +47,7 @@ nw.create_node :n2, :x => 0.6, :y => 0.8, :capacity => 0.8
|
|
47
47
|
nw.create_link :l01, :n0, :n1, :load => 0.8
|
48
48
|
nw.create_link :l12, :n1, :n2, :load => 0.4
|
49
49
|
|
50
|
-
require '
|
50
|
+
require 'omf_oml/table'
|
51
51
|
|
52
52
|
s = OmlSchema.new [[:ts, :float], [:name, :string], [:capacity, :int]]
|
53
53
|
node_table = OMF::OML::OmlTable.new('nodes', s)
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rack/auth/abstract/handler'
|
2
|
+
require 'rack/auth/abstract/request'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Auth
|
6
|
+
# Rack::Auth::Basic implements HTTP Basic Authentication, as per RFC 2617.
|
7
|
+
#
|
8
|
+
# Initialize with the Rack application that you want protecting,
|
9
|
+
# and a block that checks if a username and password pair are valid.
|
10
|
+
#
|
11
|
+
# See also: <tt>example/protectedlobster.rb</tt>
|
12
|
+
|
13
|
+
class Basic < AbstractHandler
|
14
|
+
|
15
|
+
|
16
|
+
def initialize(app, realm = nil, url_only = nil, &authenticator)
|
17
|
+
super app, realm, &authenticator
|
18
|
+
@url_only = url_only # only check those urls
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
if @url_only
|
24
|
+
path_info = env["PATH_INFO"]
|
25
|
+
u = @url_only.find do |u|
|
26
|
+
path_info.start_with?(u)
|
27
|
+
end
|
28
|
+
if u.nil?
|
29
|
+
return @app.call(env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
auth = Basic::Request.new(env)
|
34
|
+
#puts ">>>> CHECKING #{env["PATH_INFO"]}"
|
35
|
+
return unauthorized unless auth.provided?
|
36
|
+
|
37
|
+
return bad_request unless auth.basic?
|
38
|
+
|
39
|
+
if valid?(auth)
|
40
|
+
env['REMOTE_USER'] = auth.username
|
41
|
+
|
42
|
+
return @app.call(env)
|
43
|
+
end
|
44
|
+
|
45
|
+
unauthorized
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def challenge
|
52
|
+
'Basic realm="%s"' % realm
|
53
|
+
end
|
54
|
+
|
55
|
+
def valid?(auth)
|
56
|
+
@authenticator.call(*auth.credentials)
|
57
|
+
end
|
58
|
+
|
59
|
+
class Request < Auth::AbstractRequest
|
60
|
+
def basic?
|
61
|
+
:basic == scheme
|
62
|
+
end
|
63
|
+
|
64
|
+
def credentials
|
65
|
+
@credentials ||= params.unpack("m*").first.split(/:/, 2)
|
66
|
+
end
|
67
|
+
|
68
|
+
def username
|
69
|
+
credentials.first
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|