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
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
|