omf_web 0.9.7 → 0.9.8
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/.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
@@ -14,17 +14,17 @@ module OMF::Web
|
|
14
14
|
#
|
15
15
|
class GitContentRepository < ContentRepository
|
16
16
|
|
17
|
-
@@git_repositories = {}
|
18
|
-
|
19
|
-
# Return the repository which is referenced to by elements in 'opts'.
|
20
|
-
#
|
21
|
-
#
|
22
|
-
def self.[](name)
|
23
|
-
unless repo = @@git_repositories[name.to_sym]
|
24
|
-
raise "Unknown git repo '#{name}'"
|
25
|
-
end
|
26
|
-
repo
|
27
|
-
end
|
17
|
+
# @@git_repositories = {}
|
18
|
+
#
|
19
|
+
# # Return the repository which is referenced to by elements in 'opts'.
|
20
|
+
# #
|
21
|
+
# #
|
22
|
+
# def self.[](name)
|
23
|
+
# unless repo = @@git_repositories[name.to_sym]
|
24
|
+
# raise "Unknown git repo '#{name}'"
|
25
|
+
# end
|
26
|
+
# repo
|
27
|
+
# end
|
28
28
|
|
29
29
|
# Register an existing GIT repo to the system. It will be
|
30
30
|
# consulted for all content url's strarting with
|
@@ -32,17 +32,17 @@ module OMF::Web
|
|
32
32
|
# become the default repo for all newly created content
|
33
33
|
# in this app.
|
34
34
|
#
|
35
|
-
def self.register_git_repo(name, top_dir, is_primary = false)
|
36
|
-
name = name.to_sym
|
37
|
-
if @@git_repositories[name]
|
38
|
-
warn "Ignoring repeated registration of git rep '#{name}'"
|
39
|
-
return
|
40
|
-
end
|
41
|
-
repo = @@git_repositories[name] = GitContentRepository.new(name, top_dir)
|
42
|
-
if is_primary
|
43
|
-
@@primary_repository = repo
|
44
|
-
end
|
45
|
-
end
|
35
|
+
# def self.register_git_repo(name, top_dir, is_primary = false)
|
36
|
+
# name = name.to_sym
|
37
|
+
# if @@git_repositories[name]
|
38
|
+
# warn "Ignoring repeated registration of git rep '#{name}'"
|
39
|
+
# return
|
40
|
+
# end
|
41
|
+
# repo = @@git_repositories[name] = GitContentRepository.new(name, top_dir)
|
42
|
+
# if is_primary
|
43
|
+
# @@primary_repository = repo
|
44
|
+
# end
|
45
|
+
# end
|
46
46
|
|
47
47
|
# def self.read_content(url, opts)
|
48
48
|
# unless (a = url.split(':')).length == 3
|
@@ -57,23 +57,21 @@ module OMF::Web
|
|
57
57
|
|
58
58
|
attr_reader :name, :top_dir
|
59
59
|
|
60
|
-
def initialize(name,
|
61
|
-
|
62
|
-
@
|
63
|
-
@
|
64
|
-
@url_prefix = "git:#{name}:"
|
65
|
-
#@@git_repositories['git:foo'] = self
|
60
|
+
def initialize(name, opts)
|
61
|
+
super
|
62
|
+
@repo = Grit::Repo.new(@top_dir)
|
63
|
+
@url_prefix = "git:#{@name}:"
|
66
64
|
end
|
67
65
|
|
68
66
|
#
|
69
67
|
# Create a URL for a file with 'path' in.
|
70
68
|
# If 'strictly_new' is true, returns nil if 'path' already exists.
|
71
69
|
#
|
72
|
-
def create_url(path, strictly_new = true)
|
73
|
-
return "git:"
|
74
|
-
# TODO: Need to add code to select proper repository
|
75
|
-
return GitContentRepository.create_url(path, strictly_new)
|
76
|
-
end
|
70
|
+
# def create_url(path, strictly_new = true)
|
71
|
+
# return "git:"
|
72
|
+
# # TODO: Need to add code to select proper repository
|
73
|
+
# return GitContentRepository.create_url(path, strictly_new)
|
74
|
+
# end
|
77
75
|
|
78
76
|
|
79
77
|
# Load content described by either a hash or a straightforward path
|
@@ -87,9 +85,9 @@ module OMF::Web
|
|
87
85
|
def create_content_proxy_for(content_descr)
|
88
86
|
path = _get_path(content_descr)
|
89
87
|
# TODO: Make sure that key is really unique across multiple repositories
|
90
|
-
descr = descr ? descr.dup : {}
|
91
88
|
url = @url_prefix + path
|
92
89
|
key = Digest::MD5.hexdigest(url)
|
90
|
+
descr = {}
|
93
91
|
descr[:url] = url
|
94
92
|
descr[:url_key] = key
|
95
93
|
descr[:path] = path
|
@@ -119,6 +117,12 @@ module OMF::Web
|
|
119
117
|
end
|
120
118
|
end
|
121
119
|
|
120
|
+
# Return a URL for a path in this repo
|
121
|
+
#
|
122
|
+
def get_url_for_path(path)
|
123
|
+
@url_prefix + path
|
124
|
+
end
|
125
|
+
|
122
126
|
|
123
127
|
|
124
128
|
#
|
@@ -148,7 +152,7 @@ module OMF::Web
|
|
148
152
|
if long_name.match(search_pattern)
|
149
153
|
mt = mime_type_for_file(e.name)
|
150
154
|
path = @url_prefix + long_name
|
151
|
-
res << {:path => path, :name => e.name,
|
155
|
+
res << {:path => path, url => url_for_path(path), :name => e.name,
|
152
156
|
:mime_type => mt,
|
153
157
|
#:id => Base64.encode64(long_name).gsub("\n", ''),
|
154
158
|
:size => e.size, :blob => e.id}
|
@@ -0,0 +1,191 @@
|
|
1
|
+
|
2
|
+
require 'find'
|
3
|
+
require 'omf_common/lobject'
|
4
|
+
require 'omf_web'
|
5
|
+
require 'omf-web/content/content_proxy'
|
6
|
+
require 'omf-web/content/repository'
|
7
|
+
require 'irods4r'
|
8
|
+
|
9
|
+
module OMF::Web
|
10
|
+
|
11
|
+
# This class provides an interface to a directory based repository
|
12
|
+
# It retrieves, archives and versions content.
|
13
|
+
#
|
14
|
+
class IRodsContentRepository < ContentRepository
|
15
|
+
|
16
|
+
@@irods_repositories = {}
|
17
|
+
|
18
|
+
# Return the repository which is referenced to by elements in 'opts'.
|
19
|
+
#
|
20
|
+
#
|
21
|
+
def self.[](name)
|
22
|
+
unless repo = @@irods_repositories[name.to_sym]
|
23
|
+
raise "Unknown iRODS repo '#{name}'"
|
24
|
+
end
|
25
|
+
repo
|
26
|
+
end
|
27
|
+
|
28
|
+
# Register an existing directory to the system. It will be
|
29
|
+
# consulted for all content url's starting with
|
30
|
+
# 'irods:_top_dir_:'. If 'is_primary' is set to true, it will
|
31
|
+
# become the default repo for all newly created content
|
32
|
+
# in this app.
|
33
|
+
#
|
34
|
+
def self.register_file_repo(name, top_dir, is_primary = false)
|
35
|
+
name = name.to_sym
|
36
|
+
if @@irods_repositories[name]
|
37
|
+
warn "Ignoring repeated registration of iRODS rep '#{name}'"
|
38
|
+
return
|
39
|
+
end
|
40
|
+
repo = @@irods_repositories[name] = self.new(name, top_dir)
|
41
|
+
if is_primary
|
42
|
+
@@primary_repository = repo
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :name, :top_dir
|
47
|
+
|
48
|
+
def initialize(name, opts)
|
49
|
+
super
|
50
|
+
unless @top_dir
|
51
|
+
raise "No top_dir defined (#{opts.keys.inspect})"
|
52
|
+
end
|
53
|
+
@url_prefix = "irods:#{name}:"
|
54
|
+
end
|
55
|
+
|
56
|
+
# Load content described by either a hash or a straightforward path
|
57
|
+
# and return a 'ContentProxy' holding it.
|
58
|
+
#
|
59
|
+
# If descr[:strictly_new] is true, return nil if file for which proxy is requested
|
60
|
+
# already exists.
|
61
|
+
#
|
62
|
+
# @return: Content proxy
|
63
|
+
#
|
64
|
+
def create_content_proxy_for(content_descr)
|
65
|
+
path = _get_path(content_descr)
|
66
|
+
# TODO: Make sure that key is really unique across multiple repositories
|
67
|
+
descr = descr ? descr.dup : {}
|
68
|
+
url = get_url_for_path(path)
|
69
|
+
key = Digest::MD5.hexdigest(url)
|
70
|
+
descr[:url] = url
|
71
|
+
descr[:url_key] = key
|
72
|
+
descr[:path] = path
|
73
|
+
descr[:name] = url # Should be something human digestable
|
74
|
+
if (descr[:strictly_new])
|
75
|
+
return nil if IRODS4r.exists?(path)
|
76
|
+
end
|
77
|
+
proxy = ContentProxy.create(descr, self)
|
78
|
+
return proxy
|
79
|
+
end
|
80
|
+
|
81
|
+
def write(content_descr, content, message)
|
82
|
+
path = _get_path(content_descr)
|
83
|
+
#puts "WRITE PATHS>>> #{path}"
|
84
|
+
f = IRODS4r::File.create(path, false)
|
85
|
+
f.write(content)
|
86
|
+
end
|
87
|
+
|
88
|
+
def read(content_descr)
|
89
|
+
path = _get_path(content_descr)
|
90
|
+
#puts "READ PATHS>>> #{path}"
|
91
|
+
f = IRODS4r::File.create(path, false)
|
92
|
+
f.read()
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Return an array of file names which are in the repository and
|
97
|
+
# match 'search_pattern'
|
98
|
+
#
|
99
|
+
def find_files(search_pattern, opts = {})
|
100
|
+
begin
|
101
|
+
dir = IRODS4r.find(@top_dir)
|
102
|
+
rescue IRODS4r::IRODS4rException
|
103
|
+
return []
|
104
|
+
end
|
105
|
+
res = []
|
106
|
+
_find_files(search_pattern, dir, res, opts[:mime_type])
|
107
|
+
res
|
108
|
+
end
|
109
|
+
|
110
|
+
def _find_files(search_pattern, dir, res, mime_type)
|
111
|
+
dir.list.each do |e|
|
112
|
+
if e.directory?
|
113
|
+
_find_files(search_pattern, e, res, mime_type)
|
114
|
+
else
|
115
|
+
path = e.path
|
116
|
+
if path.match(search_pattern)
|
117
|
+
mt = mime_type_for_file(path)
|
118
|
+
next if mime_type != nil && mime_type != mt
|
119
|
+
res << {:url => get_url_for_path(path), :path => path, #:name => 'foo',
|
120
|
+
:mime_type => mt}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
res
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
# Return a URL for a path in this repo
|
129
|
+
#
|
130
|
+
def get_url_for_path(path)
|
131
|
+
puts "PATH>>>>> '#{path}:#{path.class}'-'#{@top_dir}:#{@top_dir.class}'"
|
132
|
+
if m = path.match("#{@top_dir}(.*)")
|
133
|
+
path = m[1]
|
134
|
+
end
|
135
|
+
url = @url_prefix + path
|
136
|
+
end
|
137
|
+
|
138
|
+
# HACK ALERT!!!
|
139
|
+
#
|
140
|
+
# This method may be called by an entity which wants to access the content
|
141
|
+
# directly through the file system. In the absence of a FUSE mounted iRODS
|
142
|
+
# repo, we 'iget' the resource to a temporary directory and return that
|
143
|
+
# path. The calling entity needs to be aware that any changes to that file
|
144
|
+
# will NOT show up in iRODS without an iput.
|
145
|
+
#
|
146
|
+
# This should really NOT be necessary. Use FUSE
|
147
|
+
#
|
148
|
+
def absolute_path(content_descr)
|
149
|
+
path = _get_path(content_descr)
|
150
|
+
|
151
|
+
require 'etc'
|
152
|
+
tmp_dir = "#{Dir::tmpdir}/LabWiki-#{Etc.getlogin}"
|
153
|
+
# unless Dir.exists? tmp_dir
|
154
|
+
# Dir.mkdir tmp_dir, 0700
|
155
|
+
# end
|
156
|
+
|
157
|
+
target = File.join(tmp_dir, path)
|
158
|
+
IRODS4r::ICommands.export(path, target)
|
159
|
+
target
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
def _get_path(content_descr)
|
164
|
+
#puts ">>>GET PATH #{content_descr.inspect}"
|
165
|
+
if content_descr.is_a? String
|
166
|
+
path = content_descr.to_s
|
167
|
+
if path.start_with? 'irods:'
|
168
|
+
path = File.join(@top_dir, path.split(':')[2])
|
169
|
+
end
|
170
|
+
elsif content_descr.is_a? Hash
|
171
|
+
descr = content_descr
|
172
|
+
unless path = descr[:path]
|
173
|
+
if url = descr[:url]
|
174
|
+
path = File.join(@top_dir, url.split(':')[2]) # irods:repo_name:path
|
175
|
+
end
|
176
|
+
end
|
177
|
+
unless path
|
178
|
+
raise "Missing 'path' or 'url' in content description (#{descr.inspect})"
|
179
|
+
end
|
180
|
+
path = path.to_s
|
181
|
+
else
|
182
|
+
raise "Unsupported type '#{content_descr.class}'"
|
183
|
+
end
|
184
|
+
unless path
|
185
|
+
raise "Can't find path information in '#{content_descr.inspect}'"
|
186
|
+
end
|
187
|
+
return path
|
188
|
+
end
|
189
|
+
|
190
|
+
end # class
|
191
|
+
end # module
|
@@ -22,8 +22,48 @@ module OMF::Web
|
|
22
22
|
:txt => 'text'
|
23
23
|
}
|
24
24
|
|
25
|
+
REPO_PLUGINS = {
|
26
|
+
git: lambda do |name, opts|
|
27
|
+
require 'omf-web/content/git_repository'
|
28
|
+
return GitContentRepository.new(name, opts)
|
29
|
+
end,
|
30
|
+
file: lambda do |name, opts|
|
31
|
+
require 'omf-web/content/file_repository'
|
32
|
+
return FileContentRepository.new(name, opts)
|
33
|
+
end,
|
34
|
+
irods: lambda do |name, opts|
|
35
|
+
require 'omf-web/content/irods_repository'
|
36
|
+
return IRodsContentRepository.new(name, opts)
|
37
|
+
end,
|
38
|
+
static: lambda do |name, opts|
|
39
|
+
require 'omf-web/content/static_repository'
|
40
|
+
return StaticContentRepository.new(name, opts)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
25
44
|
# Repo to be used for all newly created content
|
26
45
|
@@primary_repository = nil
|
46
|
+
@@repositories = {}
|
47
|
+
|
48
|
+
def self.register_repo(name, opts)
|
49
|
+
raise "ArgumentMismatch: Expected Hash, but got #{opts}" unless opts.is_a? Hash
|
50
|
+
|
51
|
+
name = name.to_sym
|
52
|
+
if @@repositories[name]
|
53
|
+
warn "Ignoring repeated registration of repo '#{name}'"
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
unless type = opts[:type]
|
58
|
+
raise "Missing type in repo opts (#{opts})"
|
59
|
+
end
|
60
|
+
unless repo_creator = REPO_PLUGINS[type.to_sym]
|
61
|
+
raise "Unknown repository type '#{type}'"
|
62
|
+
end
|
63
|
+
@@repositories[name] = r = repo_creator.call(name, opts)
|
64
|
+
@@primary_repository = r if opts[:is_primary]
|
65
|
+
end
|
66
|
+
|
27
67
|
|
28
68
|
# Load content described by either a hash or a straightforward url
|
29
69
|
# and return a 'ContentProxy' holding it.
|
@@ -39,7 +79,13 @@ module OMF::Web
|
|
39
79
|
if url_or_descr.is_a? String
|
40
80
|
url = url_or_descr
|
41
81
|
else
|
42
|
-
|
82
|
+
if (text = url_or_descr[:text])
|
83
|
+
# a bit of a hack for small static text blocks
|
84
|
+
# Much better for maintenance is to use a separate file
|
85
|
+
url = "static:-"
|
86
|
+
else
|
87
|
+
url = url_or_descr[:url]
|
88
|
+
end
|
43
89
|
end
|
44
90
|
unless url
|
45
91
|
throw "Can't find url in '#{url_or_descr.inspect}"
|
@@ -49,19 +95,6 @@ module OMF::Web
|
|
49
95
|
repo.create_content_proxy_for(url_or_descr)
|
50
96
|
end
|
51
97
|
|
52
|
-
def self.find_repo_for(url)
|
53
|
-
parts = url.split(':')
|
54
|
-
case type = parts[0]
|
55
|
-
when 'git'
|
56
|
-
require 'omf-web/content/git_repository'
|
57
|
-
return GitContentRepository[parts[1]]
|
58
|
-
when 'file'
|
59
|
-
require 'omf-web/content/file_repository'
|
60
|
-
return FileContentRepository[parts[1]]
|
61
|
-
else
|
62
|
-
raise "Unknown repo type '#{type}'"
|
63
|
-
end
|
64
|
-
end
|
65
98
|
|
66
99
|
def self.absolute_path_for(url)
|
67
100
|
find_repo_for(url).absolute_path(url)
|
@@ -71,6 +104,16 @@ module OMF::Web
|
|
71
104
|
find_repo_for(url).read(url)
|
72
105
|
end
|
73
106
|
|
107
|
+
def self.find_repo_for(url)
|
108
|
+
parts = url.split(':')
|
109
|
+
name = parts[1]
|
110
|
+
unless repo = @@repositories[name.to_sym]
|
111
|
+
raise "Unknown repo '#{name}'"
|
112
|
+
end
|
113
|
+
return repo
|
114
|
+
end
|
115
|
+
|
116
|
+
|
74
117
|
# Find files whose file name matches 'selector'.
|
75
118
|
#
|
76
119
|
# Supported options:
|
@@ -96,16 +139,29 @@ module OMF::Web
|
|
96
139
|
end
|
97
140
|
|
98
141
|
|
99
|
-
|
100
|
-
|
142
|
+
attr_reader :name, :top_dir
|
143
|
+
|
144
|
+
def initialize(name, opts)
|
145
|
+
@name = name
|
146
|
+
if @top_dir = opts[:top_dir]
|
147
|
+
@top_dir = File.expand_path(@top_dir)
|
148
|
+
end
|
149
|
+
end
|
101
150
|
|
102
|
-
|
103
|
-
|
104
|
-
|
151
|
+
#
|
152
|
+
# Return an array of file names which are in the repository and
|
153
|
+
# match 'search_pattern'
|
154
|
+
#
|
155
|
+
def find_files(search_pattern, opts = {})
|
156
|
+
raise "Missing implementation"
|
105
157
|
end
|
106
158
|
|
107
159
|
|
108
|
-
def mime_type_for_file(
|
160
|
+
def mime_type_for_file(content_descriptor)
|
161
|
+
fname = content_descriptor
|
162
|
+
if content_descriptor.is_a? Hash
|
163
|
+
fname = content_descriptor[:path]
|
164
|
+
end
|
109
165
|
ext = fname.split('.')[-1]
|
110
166
|
mt = MIME_TYPE[ext.to_sym] || 'text'
|
111
167
|
end
|
@@ -126,7 +182,14 @@ module OMF::Web
|
|
126
182
|
File.join(@top_dir, path)
|
127
183
|
end
|
128
184
|
|
185
|
+
def path(content_descr)
|
186
|
+
path = _get_path(content_descr)
|
187
|
+
end
|
129
188
|
|
130
|
-
|
189
|
+
# Return a URL for a path in this repo
|
190
|
+
#
|
191
|
+
def get_url_for_path(path)
|
192
|
+
raise "Missing implementation"
|
193
|
+
end
|
131
194
|
end # class
|
132
195
|
end # module
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
require 'omf_common/lobject'
|
3
|
+
require 'omf_web'
|
4
|
+
require 'omf-web/content/content_proxy'
|
5
|
+
require 'omf-web/content/repository'
|
6
|
+
require 'singleton'
|
7
|
+
|
8
|
+
module OMF::Web
|
9
|
+
|
10
|
+
# This class provides an interface to a repository of static,
|
11
|
+
# preloaded content.
|
12
|
+
#
|
13
|
+
class StaticContentRepository < ContentRepository
|
14
|
+
|
15
|
+
|
16
|
+
# Load content described by either a hash or a straightforward path
|
17
|
+
# and return a 'ContentProxy' holding it.
|
18
|
+
#
|
19
|
+
# @return: Content proxy
|
20
|
+
#
|
21
|
+
def create_content_proxy_for(content_descr)
|
22
|
+
debug content_descr
|
23
|
+
if content_descr.is_a? String
|
24
|
+
content_descr = {text: content_descr}
|
25
|
+
end
|
26
|
+
descr = content_descr.dup
|
27
|
+
unless text = descr.delete(:text)
|
28
|
+
raise "Missing ':text' declaraton for static content"
|
29
|
+
end
|
30
|
+
|
31
|
+
key = Digest::MD5.hexdigest(text)
|
32
|
+
@content[key] = text
|
33
|
+
descr[:url] = url = "static:" + key
|
34
|
+
descr[:url_key] = key
|
35
|
+
descr[:name] = content_descr[:name] || url # Should be something human digestable
|
36
|
+
proxy = ContentProxy.create(descr, self)
|
37
|
+
return proxy
|
38
|
+
end
|
39
|
+
|
40
|
+
def read(content_descr)
|
41
|
+
debug "READ: #{content_descr}"
|
42
|
+
@content[content_descr[:url_key]] || 'Unknown'
|
43
|
+
end
|
44
|
+
|
45
|
+
def write(content_descr, content, message)
|
46
|
+
raise "READ ONLY"
|
47
|
+
end
|
48
|
+
|
49
|
+
def mime_type_for_file(content_descriptor)
|
50
|
+
content_descriptor[:mime_type] || 'text'
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(name, opts)
|
54
|
+
super
|
55
|
+
@content = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
end # class
|
61
|
+
end # module
|
@@ -124,7 +124,7 @@ module OMF::Web
|
|
124
124
|
block.call :added, rows
|
125
125
|
end
|
126
126
|
@data_source.on_content_changed(block.object_id) do |action, rows|
|
127
|
-
debug "on_changed: #{action}: #{rows.inspect}"
|
127
|
+
#debug "on_changed: #{action}: #{rows.inspect}"
|
128
128
|
block.call action, rows
|
129
129
|
end
|
130
130
|
end
|
@@ -142,7 +142,7 @@ module OMF::Web
|
|
142
142
|
sid = Thread.current["sessionID"]
|
143
143
|
opts = opts.dup
|
144
144
|
opts[:name] = @name
|
145
|
-
opts[:schema] = @data_source.schema
|
145
|
+
opts[:schema] = @data_source.schema.describe
|
146
146
|
opts[:update_url] = "/_update/#{@name}?sid=#{sid}"
|
147
147
|
opts[:sid] = sid
|
148
148
|
unless opts[:slice] # don't send any data if this is a sliced one
|
@@ -150,7 +150,7 @@ module OMF::Web
|
|
150
150
|
opts[:rows] = []
|
151
151
|
opts[:offset] = @data_source.offset
|
152
152
|
end
|
153
|
-
#puts "to_java2>>>>> #{opts.
|
153
|
+
#puts "to_java2>>>>> #{opts.inspect}"
|
154
154
|
|
155
155
|
%{
|
156
156
|
OML.data_sources.register(#{opts.to_json});
|