omf_web 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +1 -1
- data/bin/omf_web_demo +3 -0
- data/bin/omf_web_demo.sh +0 -0
- data/doc/tutorial/tut01/hello_world.rb +27 -0
- data/doc/tutorial/tut02/hello_graph.rb +85 -0
- data/doc/tutorial/tut03/hello_database.rb +69 -0
- data/doc/tutorial/tut03/nmetric.sq3 +0 -0
- data/example/bridge/config.ru +2 -1
- data/example/demo/data_sources/downloads.csv +96 -1
- data/example/demo/demo_viz_server.rb +46 -28
- data/example/openflow-gec15/README.md +2 -0
- data/example/openflow-gec15/doc/gec15_topo.png +0 -0
- data/example/openflow-gec15/exp_source.rb +48 -9
- data/example/openflow-gec15/of_viz_server.rb +1 -1
- data/example/openflow-gec15/repository/of-exp.rb +117 -12
- data/example/openflow-gec15/repository/trema-ctl6.rb +2 -2
- data/example/simple/README.md +29 -1
- data/example/simple/data_sources/ping_source.rb +2 -2
- data/lib/irods4r/directory.rb +49 -0
- data/lib/irods4r/file.rb +53 -0
- data/lib/irods4r/icommands.rb +63 -0
- data/lib/irods4r.rb +34 -0
- data/lib/omf-web/content/content_proxy.rb +14 -5
- data/lib/omf-web/content/file_repository.rb +36 -75
- data/lib/omf-web/content/git_repository.rb +39 -35
- data/lib/omf-web/content/irods_repository.rb +191 -0
- data/lib/omf-web/content/repository.rb +84 -21
- data/lib/omf-web/content/static_repository.rb +61 -0
- data/lib/omf-web/data_source_proxy.rb +3 -3
- data/lib/omf-web/rack/session_authenticator.rb +67 -35
- data/lib/omf-web/rack/tab_mapper.rb +2 -1
- data/lib/omf-web/rack/websocket_handler.rb +49 -10
- data/lib/omf-web/session_store.rb +9 -8
- data/lib/omf-web/theme/bright/page.rb +1 -1
- data/lib/omf-web/thin/runner.rb +18 -5
- data/lib/omf-web/version.rb +1 -1
- data/lib/omf-web/widget/text/maruku/output/to_html.rb +8 -2
- data/lib/omf_web.rb +17 -2
- data/omf_web.gemspec +0 -1
- data/share/htdocs/graph/js/abstract_widget.js +3 -1
- data/share/htdocs/graph/js/barchart_brush.js +240 -0
- data/share/htdocs/js/data_source2.js +4 -1
- data/share/htdocs/js/mustache.js +17 -11
- data/share/htdocs/theme/bright/css/bright.css +1 -1
- data/share/htdocs/vendor/{bootstrap-2.1.1 → bootstrap-2.3.1}/css/bootstrap-responsive.css +56 -5
- data/share/htdocs/vendor/bootstrap-2.3.1/css/bootstrap-responsive.min.css +9 -0
- data/share/htdocs/vendor/{bootstrap-2.1.1 → bootstrap-2.3.1}/css/bootstrap.css +856 -472
- data/share/htdocs/vendor/bootstrap-2.3.1/css/bootstrap.min.css +9 -0
- data/share/htdocs/vendor/{bootstrap-2.1.1 → bootstrap-2.3.1}/img/glyphicons-halflings-white.png +0 -0
- data/share/htdocs/vendor/{bootstrap-2.1.1 → bootstrap-2.3.1}/img/glyphicons-halflings.png +0 -0
- data/share/htdocs/vendor/{bootstrap-2.1.1 → bootstrap-2.3.1}/js/bootstrap.js +427 -178
- data/share/htdocs/vendor/bootstrap-2.3.1/js/bootstrap.min.js +6 -0
- data/share/htdocs/vendor/jquery-tipsy/css/tipsy.css +25 -0
- data/share/htdocs/vendor/jquery-tipsy/js/jquery.tipsy.js +258 -0
- metadata +27 -14
- data/bin/omf-web-basic +0 -235
- data/share/htdocs/vendor/.DS_Store +0 -0
- data/share/htdocs/vendor/bootstrap-2.1.1/css/bootstrap-responsive.min.css +0 -9
- data/share/htdocs/vendor/bootstrap-2.1.1/css/bootstrap.min.css +0 -9
- data/share/htdocs/vendor/bootstrap-2.1.1/js/bootstrap.min.js +0 -6
- data/share/htdocs/vendor/jquery-ui-1.8.23/index.html +0 -383
@@ -1,12 +1,117 @@
|
|
1
|
-
defProperty('wired', 'omf.nicta.node2', "Wired node (endpoint)") # baseline.ndz
|
2
|
-
defGroup('ap', property.ap) do |node|
|
3
1
|
|
4
2
|
# wlan0 is not part of OVS
|
5
3
|
# the IP address is the GRE tunnel endpoint
|
6
4
|
node.net.w0.mode = "adhoc"
|
7
5
|
node.net.w0.type = 'g'
|
8
6
|
node.net.w0.channel = "6"
|
9
7
|
node.net.w0.essid = "adhoc"
|
10
8
|
node.net.w0.ip = "172.16.2.1"
|
11
|
-
# wlan1 is part of OVS
|
12
9
|
node.net.w1.mode = "master"
|
13
10
|
node.net.w1.type = 'g'
|
14
11
|
node.net.w1.channel = "10"
|
15
12
|
node.net.w1.essid = "ap"
|
16
13
|
|
17
14
|
onNodeUp do |n|
|
18
15
|
n.exec("ifconfig br-int up; ovs-vsctl set controller br-int connection-mode=out-of-band; ifconfig eth0 0")
|
19
16
|
n.exec("ovs-vsctl add-port br-int gre1 -- set interface gre1 type=gre options:remote_ip=172.16.2.2")
|
20
17
|
n.exec("ovs-vsctl add-port br-int eth0")
|
21
18
|
n.exec("ovs-vsctl add-port br-int wlan1")
|
22
19
|
n.exec("while true; do timeout 10 nmetrics-oml2 -s 2 -i eth0 --oml-server tcp:10.0.0.200:5000 --oml-exp-id 1 --oml-id 1 --oml-text; done")
|
23
20
|
#n.exec("/root/monitor_ovs_ports.rb --oml-id ap --oml-server tcp:norbit.npc.nicta.com.au:5000")
|
24
21
|
end
|
25
22
|
|
26
|
-
defGroup('adhoc', property.adhoc) do |node|
|
27
23
|
|
28
24
|
# wlan0 is not part of OVS
|
29
25
|
# the IP address is the GRE tunnel endpoint
|
30
26
|
node.net.w0.mode = "adhoc"
|
31
27
|
node.net.w0.type = 'g'
|
32
28
|
node.net.w0.channel = "6"
|
33
29
|
node.net.w0.essid = "adhoc"
|
34
30
|
node.net.w0.ip = "172.16.2.2"
|
35
31
|
|
36
32
|
onNodeUp do |n|
|
37
33
|
n.exec("ifconfig br-int up; ovs-vsctl set controller br-int connection-mode=out-of-band; ifconfig eth0 0")
|
38
34
|
n.exec("ovs-vsctl add-port br-int gre1 -- set interface gre1 type=gre options:remote_ip=172.16.2.1")
|
39
35
|
n.exec("ovs-vsctl add-port br-int eth0")
|
40
36
|
#n.exec("/root/monitor_ovs_ports.rb --oml-id adhoc --oml-server tcp:norbit.npc.nicta.com.au:5000")
|
41
37
|
end
|
42
|
-
defGroup('wireless', property.wireless) do |node|
|
43
38
|
# no OVS on this node
|
44
39
|
node.net.w0.mode = "managed"
|
45
40
|
node.net.w0.type = 'g'
|
46
41
|
node.net.w0.channel = "10"
|
47
42
|
node.net.w0.essid = "ap"
|
48
43
|
node.net.w0.ip = "172.16.1.4"
|
49
44
|
node.addApplication("test:app:otg2", :id => 'flow1') do |app|
|
50
45
|
app.setProperty('cbr:rate', 800000)
|
51
46
|
app.setProperty('udp:local_host', '172.16.1.4')
|
52
47
|
app.setProperty('udp:dst_host', '172.16.1.1')
|
53
48
|
app.setProperty('udp:dst_port', 3000)
|
54
49
|
app.measure('udp_out', :samples => 1)
|
55
50
|
end
|
56
51
|
|
57
52
|
node.addApplication("test:app:otg2", :id => 'flow2') do |app|
|
58
53
|
app.setProperty('cbr:rate', 800000)
|
59
54
|
app.setProperty('udp:local_host', '172.16.1.4')
|
60
55
|
app.setProperty('udp:dst_host', '172.16.1.1')
|
61
56
|
app.setProperty('udp:dst_port', 3000)
|
62
57
|
app.measure('udp_out', :samples => 1)
|
63
58
|
end
|
64
|
-
defGroup('wired', property.wired) do |node|
|
65
59
|
node.addApplication("test:app:otr2") do |app|
|
66
60
|
app.setProperty('udp:local_host', '172.16.1.1')
|
67
61
|
app.setProperty('udp:local_port', 3000)
|
68
62
|
app.measure('udp_in', :samples => 1)
|
69
63
|
end
|
70
|
-
# no OVS on this node
|
71
64
|
node.net.e0.ip = "172.16.1.1"
|
72
|
-
onEvent(:ALL_UP) do |event|
|
73
65
|
allGroups.exec("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
|
74
|
-
group("wired").startApplications
|
75
66
|
info "Start your OpenFlow controller now!"
|
76
|
-
while true
|
77
67
|
info "Starting flow 1"
|
78
68
|
group("wireless").startApplication('flow1')
|
79
69
|
sleep 10
|
80
70
|
info "Starting flow 2"
|
81
71
|
group("wireless").startApplication('flow2')
|
82
72
|
sleep 10
|
83
73
|
info "Stopping flow 1. Flow 2 should now re-route over flow 1's path"
|
84
74
|
group("wireless").stopApplication('flow1')
|
85
75
|
sleep 20
|
86
76
|
info "Starting flow 1. Should use secondary path now."
|
87
77
|
group("wireless").startApplication('flow1')
|
88
78
|
sleep 20
|
89
79
|
info "Stopping flow 2"
|
90
80
|
group("wireless").stopApplication('flow2')
|
91
81
|
info "Stopping flow 1"
|
92
82
|
group("wireless").stopApplication('flow1')
|
93
83
|
sleep 10
|
94
84
|
info "Restarting experiment cycle"
|
95
85
|
end
|
96
|
-
|
97
|
-
|
86
|
+
defProperty('wired', 'omf.nicta.node2', "Wired node (endpoint)") # baseline.ndz
|
87
|
+
defProperty('ap', 'omf.nicta.node3', "Access Point") # ovs-5.4.2-precise.ndz
|
88
|
+
defProperty('adhoc', 'omf.nicta.node4', "Secondary path node with ad-hoc link to AP") # ovs-5.4.2-precise.ndz
|
89
|
+
defProperty('wireless', 'omf.nicta.node5', "Wireless node (endpoint)") # baseline.ndz
|
90
|
+
|
91
|
+
defGroup('ap', property.ap) do |node|
|
92
|
+
# wlan0 is not part of OVS
|
93
|
+
# the IP address is the GRE tunnel endpoint
|
94
|
+
node.net.w0.mode = "adhoc"
|
95
|
+
node.net.w0.type = 'g'
|
96
|
+
node.net.w0.channel = "6"
|
97
|
+
node.net.w0.essid = "adhoc"
|
98
|
+
node.net.w0.ip = "172.16.2.1"
|
99
|
+
|
100
|
+
# wlan1 is part of OVS
|
101
|
+
node.net.w1.mode = "master"
|
102
|
+
node.net.w1.type = 'g'
|
103
|
+
node.net.w1.channel = "10"
|
104
|
+
node.net.w1.essid = "ap"
|
105
|
+
end
|
106
|
+
|
107
|
+
defGroup('adhoc', property.adhoc) do |node|
|
108
|
+
# wlan0 is not part of OVS
|
109
|
+
# the IP address is the GRE tunnel endpoint
|
110
|
+
node.net.w0.mode = "adhoc"
|
111
|
+
node.net.w0.type = 'g'
|
112
|
+
node.net.w0.channel = "6"
|
113
|
+
node.net.w0.essid = "adhoc"
|
114
|
+
node.net.w0.ip = "172.16.2.2"
|
115
|
+
end
|
116
|
+
|
117
|
+
defGroup('wireless', property.wireless) do |node|
|
118
|
+
# no OVS on this node
|
119
|
+
node.net.w0.mode = "managed"
|
120
|
+
node.net.w0.type = 'g'
|
121
|
+
node.net.w0.channel = "10"
|
122
|
+
node.net.w0.essid = "ap"
|
123
|
+
node.net.w0.ip = "172.16.1.4"
|
124
|
+
|
125
|
+
node.addApplication("test:app:otg2", :id => 'flow1') do |app|
|
126
|
+
app.setProperty('cbr:rate', 800000)
|
127
|
+
app.setProperty('udp:local_host', '172.16.1.4')
|
128
|
+
app.setProperty('udp:dst_host', '172.16.1.1')
|
129
|
+
app.setProperty('udp:dst_port', 3000)
|
130
|
+
app.measure('udp_out', :samples => 1)
|
131
|
+
end
|
132
|
+
node.addApplication("test:app:otg2", :id => 'flow2') do |app|
|
133
|
+
app.setProperty('cbr:rate', 800000)
|
134
|
+
app.setProperty('udp:local_host', '172.16.1.4')
|
135
|
+
app.setProperty('udp:dst_host', '172.16.1.1')
|
136
|
+
app.setProperty('udp:dst_port', 3000)
|
137
|
+
app.measure('udp_out', :samples => 1)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
defGroup('wired', property.wired) do |node|
|
142
|
+
node.addApplication("test:app:otr2") do |app|
|
143
|
+
app.setProperty('udp:local_host', '172.16.1.1')
|
144
|
+
app.setProperty('udp:local_port', 3000)
|
145
|
+
app.measure('udp_in', :samples => 1)
|
146
|
+
end
|
147
|
+
|
148
|
+
# no OVS on this node
|
149
|
+
node.net.e0.ip = "172.16.1.1"
|
150
|
+
end
|
151
|
+
|
152
|
+
onEvent(:ALL_UP) do |event|
|
153
|
+
allGroups.exec("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
|
154
|
+
|
155
|
+
ovs_init="ovs-vsctl del-br br-int; ovs-vsctl add-br br-int;
|
156
|
+
ovs-vsctl set-controller br-int tcp:10.0.0.200:6633;
|
157
|
+
ovs-vsctl set controller br-int connection-mode=out-of-band; ifconfig eth0 0"
|
158
|
+
|
159
|
+
group("ap").exec(ovs_init)
|
160
|
+
group("adhoc").exec(ovs_init)
|
161
|
+
|
162
|
+
group("ap").exec("ovs-vsctl add-port br-int gre1 -- set interface gre1 type=gre options:remote_ip=172.16.2.2")
|
163
|
+
group("adhoc").exec("ovs-vsctl add-port br-int gre1 -- set interface gre1 type=gre options:remote_ip=172.16.2.1")
|
164
|
+
|
165
|
+
group("ap").exec("ovs-vsctl add-port br-int eth0")
|
166
|
+
group("ap").exec("ovs-vsctl add-port br-int wlan1")
|
167
|
+
group("adhoc").exec("ovs-vsctl add-port br-int eth0")
|
168
|
+
|
169
|
+
group("ap").exec("echo \"<omlc id='AP' exp_id='openflow-demo'><collect url='tcp:10.0.0.200:3004'><stream mp='net_if' name='net_if' samples='1'/></collect><collect url='tcp:10.0.0.200:5000' encoding='text'><stream mp='net_if' name='net_if1' samples='1'/></collect></omlc>\" > /tmp/oml.xml")
|
170
|
+
group("ap").exec("nmetrics-oml2 -s 1 -i eth0 -i wlan0 -i wlan1 --oml-config /tmp/oml.xml")
|
171
|
+
|
172
|
+
#group("ap").exec("/root/monitor_ovs_ports.rb --oml-id ap --oml-server tcp:norbit.npc.nicta.com.au:5000")
|
173
|
+
#group("adhoc").exec("/root/monitor_ovs_ports.rb --oml-id adhoc --oml-server tcp:norbit.npc.nicta.com.au:5000")
|
174
|
+
|
175
|
+
group("wired").startApplications
|
176
|
+
|
177
|
+
info "Start your OpenFlow controller now!"
|
178
|
+
sleep 10
|
179
|
+
|
180
|
+
while true
|
181
|
+
info "Starting flow 1"
|
182
|
+
group("wireless").startApplication('flow1')
|
183
|
+
sleep 10
|
184
|
+
info "Starting flow 2"
|
185
|
+
group("wireless").startApplication('flow2')
|
186
|
+
sleep 10
|
187
|
+
info "Stopping flow 1. Flow 2 should now re-route over flow 1's path"
|
188
|
+
group("wireless").stopApplication('flow1')
|
189
|
+
sleep 20
|
190
|
+
info "Starting flow 1. Should use secondary path now."
|
191
|
+
group("wireless").startApplication('flow1')
|
192
|
+
sleep 20
|
193
|
+
info "Stopping flow 2"
|
194
|
+
group("wireless").stopApplication('flow2')
|
195
|
+
sleep 10
|
196
|
+
info "Stopping flow 1"
|
197
|
+
group("wireless").stopApplication('flow1')
|
198
|
+
sleep 10
|
199
|
+
info "Restarting experiment cycle"
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
data/example/simple/README.md
CHANGED
@@ -1,2 +1,30 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
# Example/Simple
|
3
|
+
|
4
|
+
Essentially the 'Hello World' example of a viz server. Taking data out of a database and putting it into a graph.
|
5
|
+
|
6
|
+
Start the server through:
|
7
|
+
|
8
|
+
ruby -I$OMF_WEB_HOME/lib $OMF_WEB_HOME/example/simple/simple_viz_server.rb start
|
9
|
+
|
10
|
+
where $OMF_WEB_HOME points to the directory containing the __omf_web__ code. You will also need to __omf_oml__ package.
|
11
|
+
You may either install the Gem, or download the source code from https://github.com/mytestbed/omf_oml. In the later case you
|
12
|
+
will need to add a '-I$OMF_OML_HOME/lib' falg to the above command.
|
13
|
+
|
14
|
+
After all that, the console putput should look like:
|
15
|
+
|
16
|
+
DEBUG OmlSqlSource: Opening DB (sqlite:///Users/max/src/omf_web/example/simple/data_sources/gimi31.sq3)
|
17
|
+
DEBUG OmlSqlSource: DB: #<Sequel::SQLite::Database: "sqlite:///Users/max/src/omf_web/example/simple/data_sources/gimi31.sq3">
|
18
|
+
DEBUG OmlSqlSource: Finding tables [:_senders, :_experiment_metadata, :pingmonitor_myping]
|
19
|
+
DEBUG OmlSqlSource: Found table: pingmonitor_myping
|
20
|
+
DEBUG OmlSchema: schema: '[{:name=>:oml_sender, :type=>:string, :title=>"Oml Sender"}, {:name=>:oml_sender_id, :type=>:integer, :title=>"Oml Sender Id"}, {:name=>:oml_seq, :type=>:integer, :title=>"Oml Seq"}, {:name=>:oml_ts_client, :type=>:float, :title=>"Oml Ts Client"}, {:name=>:oml_ts_server, :type=>:float, :title=>"Oml Ts Server"}, {:name=>:dest_addr, :type=>:string, :title=>"Dest Addr"}, {:name=>:ttl, :type=>:integer, :title=>"Ttl"}, {:name=>:rtt, :type=>:float, :title=>"Rtt"}, {:name=>:rtt_unit, :type=>:string, :title=>"Rtt Unit"}]'
|
21
|
+
INFO PingDB: Stream: pingmonitor_myping
|
22
|
+
DEBUG OmlSqlRow-pingmonitor_myping: Read 145/145 rows from 'pingmonitor_myping'
|
23
|
+
INFO Server: >> Thin web server (v1.3.1 codename Triple Espresso)
|
24
|
+
DEBUG Server: >> Debugging ON
|
25
|
+
DEBUG Server: >> Tracing ON
|
26
|
+
INFO Server: >> Maximum connections set to 1024
|
27
|
+
INFO Server: >> Listening on 0.0.0.0:3000, CTRL+C to stop
|
28
|
+
|
29
|
+
This starts a web server on the local machine listening on port 3000. Now point your browser there and you should see the
|
30
|
+
result of a 'ping' experiment.
|
@@ -27,7 +27,7 @@ class PingDB < OMF::Common::LObject
|
|
27
27
|
def setup_table(stream)
|
28
28
|
schema = stream.schema.clone
|
29
29
|
schema.insert_column_at(0, :link)
|
30
|
-
puts stream.schema.names.inspect
|
30
|
+
#puts stream.schema.names.inspect
|
31
31
|
|
32
32
|
t = OMF::OML::OmlTable.new(:ping, schema)
|
33
33
|
stream.on_new_tuple() do |v|
|
@@ -53,4 +53,4 @@ class PingDB < OMF::Common::LObject
|
|
53
53
|
end
|
54
54
|
|
55
55
|
end
|
56
|
-
wv = PingDB.new(
|
56
|
+
wv = PingDB.new("sqlite://#{File.dirname(__FILE__)}/gimi31.sq3").run()
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
require 'irods4r'
|
3
|
+
|
4
|
+
module IRODS4r
|
5
|
+
|
6
|
+
# This class proxies a directory in an iRODS environment
|
7
|
+
#
|
8
|
+
class Directory
|
9
|
+
|
10
|
+
def list()
|
11
|
+
FileEnumerator.new(@dir_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def file?
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
|
18
|
+
def directory?
|
19
|
+
return true
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(dir_name)
|
23
|
+
@dir_name = dir_name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class FileEnumerator
|
28
|
+
include Enumerable
|
29
|
+
|
30
|
+
def each()
|
31
|
+
while e = @entries.shift
|
32
|
+
e = e.strip
|
33
|
+
if e.start_with? 'C-'
|
34
|
+
# it's a directory
|
35
|
+
yield Directory.new(e[3 .. -1])
|
36
|
+
else
|
37
|
+
yield File.new(::File.join(@dir_name, e))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(dir_name)
|
43
|
+
r = `ils #{dir_name}`
|
44
|
+
@dir_name = dir_name
|
45
|
+
@entries = r.lines.to_a
|
46
|
+
@entries.shift # the first line is the directory name again
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/irods4r/file.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
require 'irods4r/directory'
|
3
|
+
|
4
|
+
module IRODS4r
|
5
|
+
|
6
|
+
#class NotFoundException < Exception; end
|
7
|
+
class NoFileException < Exception; end
|
8
|
+
class FileExistsException < Exception; end
|
9
|
+
|
10
|
+
# This class proxies a file in an iRODS environment
|
11
|
+
#
|
12
|
+
class File
|
13
|
+
|
14
|
+
# Create a file resource 'path'. If 'must_not_exist' is true,
|
15
|
+
# throw exception if resource already exists.
|
16
|
+
#
|
17
|
+
def self.create(path, must_not_exist = true, opts = {})
|
18
|
+
if must_not_exist
|
19
|
+
raise FileExistsException.new(path) if ICommands.exist?(path)
|
20
|
+
end
|
21
|
+
self.new(path, opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# Return the content of this file
|
26
|
+
def read()
|
27
|
+
ICommands.read(@path)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Write content to this file.
|
31
|
+
#
|
32
|
+
# WARN: This will overwrite any previous content
|
33
|
+
#
|
34
|
+
def write(content)
|
35
|
+
ICommands.write(@path, content)
|
36
|
+
end
|
37
|
+
|
38
|
+
def file?
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
|
42
|
+
def directory?
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :path
|
47
|
+
|
48
|
+
private
|
49
|
+
def initialize(path, opts = {})
|
50
|
+
@path = path
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
require 'irods4r'
|
3
|
+
|
4
|
+
module IRODS4r
|
5
|
+
|
6
|
+
# This module interfaces directly with the IRODS system
|
7
|
+
#
|
8
|
+
module ICommands
|
9
|
+
class ICommandException < IRODS4rException; end
|
10
|
+
|
11
|
+
# Return the list of files found at 'path'.
|
12
|
+
def self.ls(path)
|
13
|
+
r = `ils #{path}`
|
14
|
+
#raise ICommandException.new($?) unless $?.exitstatus == 0
|
15
|
+
if r.empty?
|
16
|
+
raise NotFoundException.new("Can't find resource '#{path}'")
|
17
|
+
end
|
18
|
+
r.lines
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return content of resource at 'path'
|
22
|
+
#
|
23
|
+
def self.read(path)
|
24
|
+
f = Tempfile.new('irods4r')
|
25
|
+
`iget -f #{path} #{f.path}`
|
26
|
+
raise ICommandException.new($?) unless $?.exitstatus == 0
|
27
|
+
content = f.read
|
28
|
+
f.close
|
29
|
+
f.unlink
|
30
|
+
content
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return content of resource at 'path'
|
34
|
+
#
|
35
|
+
def self.write(path, content)
|
36
|
+
f = Tempfile.new('irods4r')
|
37
|
+
f.write(content)
|
38
|
+
f.close
|
39
|
+
`iput -f #{f.path} #{path}`
|
40
|
+
raise ICommandException.new($?) unless $?.exitstatus == 0
|
41
|
+
f.unlink
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.exist?(path)
|
45
|
+
`ils #{path}`
|
46
|
+
$?.exitstatus == 0
|
47
|
+
end
|
48
|
+
|
49
|
+
# Copy the resource at 'path' in iRODS to 'file_path'
|
50
|
+
# in the local file system.
|
51
|
+
#
|
52
|
+
def self.export(path, file_path, create_parent_path = true)
|
53
|
+
#puts ">>>> #{path} -> #{file_path}"
|
54
|
+
if create_parent_path
|
55
|
+
require 'fileutils'
|
56
|
+
FileUtils.mkpath ::File.dirname(file_path)
|
57
|
+
end
|
58
|
+
`iget -f #{path} #{file_path}`
|
59
|
+
raise ICommandException.new($?) unless $?.exitstatus == 0
|
60
|
+
end
|
61
|
+
end #module
|
62
|
+
end # module
|
63
|
+
|
data/lib/irods4r.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module IRODS4r
|
4
|
+
|
5
|
+
class IRODS4rException < Exception; end
|
6
|
+
class NotFoundException < IRODS4rException; end
|
7
|
+
class NoDirectoryException < IRODS4rException; end
|
8
|
+
|
9
|
+
# Return a IRODS4r object for 'irodsPath' if it exists.
|
10
|
+
#
|
11
|
+
# @param [String] irodsPath Absolute path into iRODS
|
12
|
+
# @param [Hash] opts Options to use for establishing context
|
13
|
+
# @return [Directory|File]
|
14
|
+
#
|
15
|
+
def self.find(irodsPath = ".", opts = {})
|
16
|
+
r = ICommands.ls(irodsPath)
|
17
|
+
name = r.to_a[0].strip
|
18
|
+
if name.end_with? ':'
|
19
|
+
Directory.new(name[0 ... -1])
|
20
|
+
else
|
21
|
+
File.new(name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return true if 'path' exists
|
26
|
+
def self.exists?(path)
|
27
|
+
ICommands.exist?(path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'irods4r/directory'
|
32
|
+
require 'irods4r/file'
|
33
|
+
require 'irods4r/icommands'
|
34
|
+
|
@@ -39,10 +39,6 @@ module OMF::Web
|
|
39
39
|
def on_post(req)
|
40
40
|
data = req.POST
|
41
41
|
write(data['content'], data['message'])
|
42
|
-
# if (content = data['content']) != @content
|
43
|
-
# @content = content
|
44
|
-
# @repository.add_and_commit(@content_handle, content, data['message'], req)
|
45
|
-
# end
|
46
42
|
[true.to_json, "text/json"]
|
47
43
|
end
|
48
44
|
|
@@ -62,6 +58,19 @@ module OMF::Web
|
|
62
58
|
end
|
63
59
|
alias :read :content
|
64
60
|
|
61
|
+
# Return a new proxy for a url relative to this one
|
62
|
+
def create_proxy_for_url(url)
|
63
|
+
unless url.match ':'
|
64
|
+
unless url.start_with? '/'
|
65
|
+
# relative
|
66
|
+
ap = @repository.path(@content_descriptor)
|
67
|
+
url = File.join(File.dirname(ap), url)
|
68
|
+
end
|
69
|
+
url = @repository.get_url_for_path(url)
|
70
|
+
end
|
71
|
+
@repository.create_content_proxy_for(url)
|
72
|
+
end
|
73
|
+
|
65
74
|
private
|
66
75
|
|
67
76
|
def initialize(content_descriptor, repository)
|
@@ -72,7 +81,7 @@ module OMF::Web
|
|
72
81
|
@content_id = content_descriptor[:url_key]
|
73
82
|
@content_url = "/_content/#{@content_id}" # That most likley should come from the content handler
|
74
83
|
|
75
|
-
@mime_type = @content_descriptor[:mime_type] ||= repository.mime_type_for_file(content_descriptor
|
84
|
+
@mime_type = @content_descriptor[:mime_type] ||= repository.mime_type_for_file(content_descriptor)
|
76
85
|
@name = content_descriptor[:name]
|
77
86
|
|
78
87
|
@@proxies[@content_id] = self
|
@@ -12,41 +12,39 @@ module OMF::Web
|
|
12
12
|
#
|
13
13
|
class FileContentRepository < ContentRepository
|
14
14
|
|
15
|
-
@@file_repositories = {}
|
16
|
-
|
17
|
-
# Return the repository which is referenced to by elements in 'opts'.
|
18
|
-
#
|
19
|
-
#
|
20
|
-
def self.[](name)
|
21
|
-
unless repo = @@file_repositories[name.to_sym]
|
22
|
-
raise "Unknown file repo '#{name}'"
|
23
|
-
end
|
24
|
-
repo
|
25
|
-
end
|
26
|
-
|
27
|
-
# Register an existing directory to the system. It will be
|
28
|
-
# consulted for all content url's strarting with
|
29
|
-
# 'file:_top_dir_:'. If 'is_primary' is set to true, it will
|
30
|
-
# become the default repo for all newly created content
|
31
|
-
# in this app.
|
32
|
-
#
|
33
|
-
def self.register_file_repo(name, top_dir, is_primary = false)
|
34
|
-
name = name.to_sym
|
35
|
-
if @@file_repositories[name]
|
36
|
-
warn "Ignoring repeated registration of file rep '#{name}'"
|
37
|
-
return
|
38
|
-
end
|
39
|
-
repo = @@file_repositories[name] = FileContentRepository.new(name, top_dir)
|
40
|
-
if is_primary
|
41
|
-
@@primary_repository = repo
|
42
|
-
end
|
43
|
-
end
|
15
|
+
# @@file_repositories = {}
|
16
|
+
#
|
17
|
+
# # Return the repository which is referenced to by elements in 'opts'.
|
18
|
+
# #
|
19
|
+
# #
|
20
|
+
# def self.[](name)
|
21
|
+
# unless repo = @@file_repositories[name.to_sym]
|
22
|
+
# raise "Unknown file repo '#{name}'"
|
23
|
+
# end
|
24
|
+
# repo
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Register an existing directory to the system. It will be
|
28
|
+
# # consulted for all content url's strarting with
|
29
|
+
# # 'file:_top_dir_:'. If 'is_primary' is set to true, it will
|
30
|
+
# # become the default repo for all newly created content
|
31
|
+
# # in this app.
|
32
|
+
# #
|
33
|
+
# def self.register_file_repo(name, top_dir, is_primary = false)
|
34
|
+
# name = name.to_sym
|
35
|
+
# if @@file_repositories[name]
|
36
|
+
# warn "Ignoring repeated registration of file rep '#{name}'"
|
37
|
+
# return
|
38
|
+
# end
|
39
|
+
# repo = @@file_repositories[name] = FileContentRepository.new(name, top_dir)
|
40
|
+
# if is_primary
|
41
|
+
# @@primary_repository = repo
|
42
|
+
# end
|
43
|
+
# end
|
44
44
|
|
45
|
-
attr_reader :name, :top_dir
|
46
45
|
|
47
|
-
def initialize(name,
|
48
|
-
|
49
|
-
@top_dir = top_dir
|
46
|
+
def initialize(name, opts)
|
47
|
+
super
|
50
48
|
@url_prefix = "file:#{name}:"
|
51
49
|
end
|
52
50
|
|
@@ -100,48 +98,11 @@ module OMF::Web
|
|
100
98
|
end
|
101
99
|
end
|
102
100
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
#
|
109
|
-
# def find_files(search_pattern, opts = {})
|
110
|
-
# search_pattern = Regexp.new(search_pattern)
|
111
|
-
# tree = @repo.tree
|
112
|
-
# res = []
|
113
|
-
# fs = _find_files(search_pattern, tree, nil, res)
|
114
|
-
#
|
115
|
-
# if (mt = opts[:mime_type])
|
116
|
-
# fs = fs.select { |f| f[:mime_type] == mt }
|
117
|
-
# end
|
118
|
-
# fs
|
119
|
-
# end
|
120
|
-
#
|
121
|
-
# def _find_files(search_pattern, tree, dir_path, res)
|
122
|
-
# tree.contents.each do |e|
|
123
|
-
# d = e.name
|
124
|
-
# long_name = dir_path ? "#{dir_path}/#{d}" : d
|
125
|
-
#
|
126
|
-
# if e.is_a? Grit::Tree
|
127
|
-
# _find_files(search_pattern, e, long_name, res)
|
128
|
-
# else
|
129
|
-
# if long_name.match(search_pattern)
|
130
|
-
# mt = mime_type_for_file(e.name)
|
131
|
-
# path = @url_prefix + long_name
|
132
|
-
# res << {:path => path, :name => e.name,
|
133
|
-
# :mime_type => mt,
|
134
|
-
# #:id => Base64.encode64(long_name).gsub("\n", ''),
|
135
|
-
# :size => e.size, :blob => e.id}
|
136
|
-
# end
|
137
|
-
# # name = e.name
|
138
|
-
# # if File.fnmatch(search_pattern, long_name)
|
139
|
-
# # res << long_name
|
140
|
-
# # end
|
141
|
-
# end
|
142
|
-
# end
|
143
|
-
# res
|
144
|
-
# end
|
101
|
+
# Return a URL for a path in this repo
|
102
|
+
#
|
103
|
+
def get_url_for_path(path)
|
104
|
+
"file:#{path}"
|
105
|
+
end
|
145
106
|
|
146
107
|
def _get_path(content_descr)
|
147
108
|
if content_descr.is_a? String
|