omf_web 1.2.5 → 1.2.6
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/lib/omf-web/content/content_proxy.rb +28 -15
- data/lib/omf-web/content/file_repository.rb +16 -57
- data/lib/omf-web/content/git_repository.rb +2 -121
- data/lib/omf-web/content/irods_repository.rb +2 -0
- data/lib/omf-web/content/repository.rb +121 -10
- data/lib/omf-web/content/static_repository.rb +3 -3
- data/lib/omf-web/rack/content_handler.rb +8 -6
- data/lib/omf-web/theme.rb +16 -2
- data/lib/omf-web/thin/logging.rb +13 -4
- data/lib/omf-web/version.rb +1 -1
- data/lib/omf-web/widget/text/maruku/output/to_html.rb +29 -23
- data/lib/omf-web/widget/text/maruku.rb +20 -5
- data/omf_web.gemspec +1 -1
- data/share/htdocs/graph/js/code_mirror.js +2 -1
- data/share/htdocs/vendor/VERSION_MAP.yaml +1 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/LICENSE-MIT +22 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/README.md +26 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/bootstrap/jquery.smartmenus.bootstrap.css +103 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/bootstrap/jquery.smartmenus.bootstrap.js +72 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/bootstrap/jquery.smartmenus.bootstrap.min.js +3 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/keyboard/jquery.smartmenus.keyboard.js +192 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/keyboard/jquery.smartmenus.keyboard.min.js +3 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/current-item-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/main-item-hover-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/main-menu-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/sub-item-hover-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/vertical-main-item-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/sm-blue.css +409 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-clean/sm-clean.css +315 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-core-css.css +23 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-mint/sm-mint.css +320 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-simple/sm-simple.css +218 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/jquery.smartmenus.js +1041 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/jquery.smartmenus.min.js +3 -0
- metadata +218 -229
@@ -5,31 +5,34 @@ require 'omf_web'
|
|
5
5
|
|
6
6
|
module OMF::Web
|
7
7
|
|
8
|
+
# TODO: Is this really the right description???
|
9
|
+
#
|
8
10
|
# This object maintains synchronization between a JS DataSource object
|
9
11
|
# in a web browser and the corresponding +OmlTable+ in this server.
|
10
12
|
#
|
11
13
|
#
|
12
14
|
class ContentProxy < OMF::Base::LObject
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@@proxies[url.to_s]
|
16
|
+
def self.[](key)
|
17
|
+
#key = Digest::MD5.hexdigest(url)
|
18
|
+
OMF::Web::SessionStore[key, :content_proxy]
|
18
19
|
end
|
19
20
|
|
21
|
+
# content_descriptor: url, mime_type, name
|
20
22
|
def self.create(content_descr, repo)
|
21
|
-
unless
|
22
|
-
raise "Missing ':
|
23
|
+
unless url = content_descr[:url]
|
24
|
+
raise "Missing ':url' in content descriptor '#{content_descr.inspect}'"
|
23
25
|
end
|
24
|
-
|
26
|
+
key = Digest::MD5.hexdigest(url)
|
27
|
+
|
28
|
+
if proxy = OMF::Web::SessionStore[key, :content_proxy]
|
25
29
|
return proxy
|
26
30
|
end
|
27
|
-
debug "Create content proxy for '#{
|
28
|
-
|
31
|
+
debug "Create content proxy for '#{url}' (#{content_descr.inspect})"
|
32
|
+
self.new(key, content_descr, repo)
|
29
33
|
end
|
30
34
|
|
31
|
-
attr_reader :content_descriptor, :content_url, :
|
32
|
-
|
35
|
+
attr_reader :content_descriptor, :content_url, :name, :mime_type, :repository
|
33
36
|
|
34
37
|
def on_get(req)
|
35
38
|
c = content()
|
@@ -71,20 +74,30 @@ module OMF::Web
|
|
71
74
|
@repository.create_content_proxy_for(url)
|
72
75
|
end
|
73
76
|
|
77
|
+
def read_only?
|
78
|
+
@repository.read_only?
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
"\#<#{self.class} - #@name>"
|
83
|
+
end
|
84
|
+
|
74
85
|
private
|
75
86
|
|
76
|
-
def initialize(content_descriptor, repository)
|
87
|
+
def initialize(key, content_descriptor, repository)
|
88
|
+
@key = key
|
77
89
|
@content_descriptor = content_descriptor
|
78
90
|
@repository = repository
|
79
91
|
#@path = File.join(repository.top_dir, content_handle) # requires 1.9 File.absolute_path(@content_handle, @repository.top_dir)
|
80
92
|
|
81
|
-
|
82
|
-
@content_url = "/_content/#{
|
93
|
+
#@content_id = content_descriptor[:url_key]
|
94
|
+
@content_url = "/_content/#{key}" # That most likley should come from the content handler
|
83
95
|
|
84
96
|
@mime_type = @content_descriptor[:mime_type] ||= repository.mime_type_for_file(content_descriptor)
|
85
97
|
@name = content_descriptor[:name]
|
86
98
|
|
87
|
-
|
99
|
+
OMF::Web::SessionStore[key, :content_proxy] = self
|
100
|
+
#@@proxies[@content_id] = self
|
88
101
|
end
|
89
102
|
|
90
103
|
end
|
@@ -14,34 +14,7 @@ module OMF::Web
|
|
14
14
|
|
15
15
|
def initialize(name, opts)
|
16
16
|
super
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
# Load content described by either a hash or a straightforward path
|
21
|
-
# and return a 'ContentProxy' holding it.
|
22
|
-
#
|
23
|
-
# If descr[:strictly_new] is true, return nil if file for which proxy is requested
|
24
|
-
# already exists.
|
25
|
-
#
|
26
|
-
# @return: Content proxy
|
27
|
-
#
|
28
|
-
def create_content_proxy_for(content_descr)
|
29
|
-
path = _get_path(content_descr)
|
30
|
-
# TODO: Make sure that key is really unique across multiple repositories
|
31
|
-
descr = descr ? descr.dup : {}
|
32
|
-
url = @url_prefix + path
|
33
|
-
key = Digest::MD5.hexdigest(url)
|
34
|
-
descr[:url] = url
|
35
|
-
descr[:url_key] = key
|
36
|
-
descr[:path] = path
|
37
|
-
descr[:name] = url # Should be something human digestable
|
38
|
-
if (descr[:strictly_new])
|
39
|
-
Dir.chdir(@top_dir) do
|
40
|
-
return nil if File.exist?(path)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
proxy = ContentProxy.create(descr, self)
|
44
|
-
return proxy
|
17
|
+
#@url_prefix = "file:#{name}:"
|
45
18
|
end
|
46
19
|
|
47
20
|
def write(content_descr, content, message)
|
@@ -60,36 +33,22 @@ module OMF::Web
|
|
60
33
|
end
|
61
34
|
end
|
62
35
|
|
63
|
-
# Return a URL for a path in this repo
|
64
36
|
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
path = descr[:path]
|
81
|
-
end
|
82
|
-
unless path
|
83
|
-
raise "Missing 'path' or 'url' in content description (#{descr.inspect})"
|
84
|
-
end
|
85
|
-
path = path.to_s
|
86
|
-
else
|
87
|
-
raise "Unsupported type '#{content_descr.class}'"
|
88
|
-
end
|
89
|
-
unless path
|
90
|
-
raise "Can't find path information in '#{content_descr.inspect}'"
|
91
|
-
end
|
92
|
-
return path
|
37
|
+
# Return an array of file names which are in the repository and
|
38
|
+
# match 'search_pattern'
|
39
|
+
#
|
40
|
+
def find_files(search_pattern, opts = {})
|
41
|
+
Dir.chdir(@top_dir)
|
42
|
+
Dir.glob("**/*#{search_pattern}*").map do |path|
|
43
|
+
next if File.directory?(path)
|
44
|
+
mt = mime_type_for_file(path)
|
45
|
+
{
|
46
|
+
name: path,
|
47
|
+
url: get_url_for_path(path),
|
48
|
+
mime_type: mt,
|
49
|
+
size: File.size(path)
|
50
|
+
}
|
51
|
+
end.compact
|
93
52
|
end
|
94
53
|
|
95
54
|
end # class
|
@@ -14,94 +14,16 @@ 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
|
28
|
-
|
29
|
-
# Register an existing GIT repo to the system. It will be
|
30
|
-
# consulted for all content url's strarting with
|
31
|
-
# 'git:_top_dir_:'. If 'is_primary' is set to true, it will
|
32
|
-
# become the default repo for all newly created content
|
33
|
-
# in this app.
|
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
|
46
|
-
|
47
|
-
# def self.read_content(url, opts)
|
48
|
-
# unless (a = url.split(':')).length == 3
|
49
|
-
# raise "Expected 'git:some_name:some_path', but got '#{url}'"
|
50
|
-
# end
|
51
|
-
# git, name, path = a
|
52
|
-
# unless (repo = @@repositories['git:' + name])
|
53
|
-
# raise "Unknown git repository '#{name}'"
|
54
|
-
# end
|
55
|
-
# repo.read(path)
|
56
|
-
# end
|
57
|
-
|
58
17
|
attr_reader :name, :top_dir
|
59
18
|
|
60
19
|
def initialize(name, opts)
|
61
20
|
super
|
62
21
|
@repo = Grit::Repo.new(@top_dir)
|
63
|
-
@url_prefix = "git:#{@name}:"
|
64
|
-
end
|
65
|
-
|
66
|
-
#
|
67
|
-
# Create a URL for a file with 'path' in.
|
68
|
-
# If 'strictly_new' is true, returns nil if 'path' already exists.
|
69
|
-
#
|
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
|
75
|
-
|
76
|
-
|
77
|
-
# Load content described by either a hash or a straightforward path
|
78
|
-
# and return a 'ContentProxy' holding it.
|
79
|
-
#
|
80
|
-
# If descr[:strictly_new] is true, return nil if file for which proxy is requested
|
81
|
-
# already exists.
|
82
|
-
#
|
83
|
-
# @return: Content proxy
|
84
|
-
#
|
85
|
-
def create_content_proxy_for(content_descr)
|
86
|
-
path = _get_path(content_descr)
|
87
|
-
# TODO: Make sure that key is really unique across multiple repositories
|
88
|
-
url = @url_prefix + path
|
89
|
-
key = Digest::MD5.hexdigest(url)
|
90
|
-
descr = {}
|
91
|
-
descr[:url] = url
|
92
|
-
descr[:url_key] = key
|
93
|
-
descr[:path] = path
|
94
|
-
descr[:name] = url # Should be something human digestable
|
95
|
-
if (descr[:strictly_new])
|
96
|
-
Dir.chdir(@top_dir) do
|
97
|
-
return nil if File.exist?(path)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
proxy = ContentProxy.create(descr, self)
|
101
|
-
return proxy
|
102
22
|
end
|
103
23
|
|
104
24
|
def write(content_descr, content, message)
|
25
|
+
raise ReadOnlyContentRepositoryException.new if @read_only
|
26
|
+
|
105
27
|
path = _get_path(content_descr)
|
106
28
|
Dir.chdir(@top_dir) do
|
107
29
|
d_name = File.dirname(path)
|
@@ -125,8 +47,6 @@ module OMF::Web
|
|
125
47
|
@url_prefix + path
|
126
48
|
end
|
127
49
|
|
128
|
-
|
129
|
-
|
130
50
|
#
|
131
51
|
# Return an array of file names which are in the repository and
|
132
52
|
# match 'search_pattern'
|
@@ -136,10 +56,6 @@ module OMF::Web
|
|
136
56
|
tree = @repo.tree
|
137
57
|
res = []
|
138
58
|
fs = _find_files(search_pattern, tree, nil, res)
|
139
|
-
|
140
|
-
# if (mt = opts[:mime_type])
|
141
|
-
# fs = fs.select { |f| File.fnmatch(mt, f[:mime_type]) }
|
142
|
-
# end
|
143
59
|
fs
|
144
60
|
end
|
145
61
|
|
@@ -160,44 +76,9 @@ module OMF::Web
|
|
160
76
|
#:id => Base64.encode64(long_name).gsub("\n", ''),
|
161
77
|
size: e.size, blob: e.id}
|
162
78
|
end
|
163
|
-
# name = e.name
|
164
|
-
# if File.fnmatch(search_pattern, long_name)
|
165
|
-
# res << long_name
|
166
|
-
# end
|
167
79
|
end
|
168
80
|
end
|
169
81
|
res
|
170
82
|
end
|
171
|
-
|
172
|
-
def _get_path(content_descr)
|
173
|
-
if content_descr.is_a? String
|
174
|
-
path = content_descr.to_s
|
175
|
-
if path.start_with? 'git:'
|
176
|
-
path = path.split(':')[2]
|
177
|
-
end
|
178
|
-
elsif content_descr.is_a? Hash
|
179
|
-
descr = content_descr
|
180
|
-
if (url = descr[:url])
|
181
|
-
path = url.split(':')[2] # git:repo_name:path
|
182
|
-
else
|
183
|
-
path = descr[:path]
|
184
|
-
end
|
185
|
-
unless path
|
186
|
-
raise "Missing 'path' or 'url' in content description (#{descr.inspect})"
|
187
|
-
end
|
188
|
-
path = path.to_s
|
189
|
-
else
|
190
|
-
raise "Unsupported type '#{content_descr.class}'"
|
191
|
-
end
|
192
|
-
unless path
|
193
|
-
raise "Can't find path information in '#{content_descr.inspect}'"
|
194
|
-
end
|
195
|
-
if path.start_with? '/'
|
196
|
-
# Remove leading '/' .. need to stay within git directory tree
|
197
|
-
path = path[1 .. -1]
|
198
|
-
end
|
199
|
-
return path
|
200
|
-
end
|
201
|
-
|
202
83
|
end # class
|
203
84
|
end # module
|
@@ -80,6 +80,8 @@ module OMF::Web
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def write(content_descr, content, message)
|
83
|
+
raise ReadOnlyContentRepositoryException.new if @read_only
|
84
|
+
|
83
85
|
path = _get_path(content_descr)
|
84
86
|
#puts "WRITE PATHS>>> #{path}"
|
85
87
|
f = IRODS4r::File.create(path, false, ticket: @ticket)
|
@@ -49,6 +49,18 @@ module OMF::Web
|
|
49
49
|
@@primary_repository = nil
|
50
50
|
@@repositories = {}
|
51
51
|
|
52
|
+
# Prepand this path if 'top_dir' starts with '.'
|
53
|
+
@@reference_dir = nil
|
54
|
+
|
55
|
+
# Prepand this path if 'top_dir' starts with '.'
|
56
|
+
def self.reference_dir=(dir)
|
57
|
+
@@reference_dir = dir
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.reference_dir
|
61
|
+
@@reference_dir
|
62
|
+
end
|
63
|
+
|
52
64
|
def self.register_repo(name, opts)
|
53
65
|
raise "ArgumentMismatch: Expected Hash, but got #{opts}" unless opts.is_a? Hash
|
54
66
|
|
@@ -58,28 +70,45 @@ module OMF::Web
|
|
58
70
|
return
|
59
71
|
end
|
60
72
|
|
73
|
+
# unless type = opts[:type]
|
74
|
+
# raise "Missing type in repo opts (#{opts})"
|
75
|
+
# end
|
76
|
+
# unless repo_creator = REPO_PLUGINS[type.to_sym]
|
77
|
+
# raise "Unknown repository type '#{type}'"
|
78
|
+
# end
|
79
|
+
|
80
|
+
@@repositories[name] = r = create(opts)
|
81
|
+
@@primary_repository = r if opts[:is_primary]
|
82
|
+
r
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.create(name, opts)
|
86
|
+
raise "ArgumentMismatch: Expected Hash, but got #{opts}" unless opts.is_a? Hash
|
87
|
+
|
61
88
|
unless type = opts[:type]
|
62
89
|
raise "Missing type in repo opts (#{opts})"
|
63
90
|
end
|
64
91
|
unless repo_creator = REPO_PLUGINS[type.to_sym]
|
65
92
|
raise "Unknown repository type '#{type}'"
|
66
93
|
end
|
67
|
-
|
68
|
-
@@primary_repository = r if opts[:is_primary]
|
69
|
-
r
|
94
|
+
r = repo_creator.call(name, opts)
|
70
95
|
end
|
71
96
|
|
72
97
|
|
98
|
+
|
73
99
|
# Load content described by either a hash or a straightforward url
|
74
100
|
# and return a 'ContentProxy' holding it.
|
75
101
|
#
|
102
|
+
# @params
|
103
|
+
# - :repo_iterator: Iterator over available repos
|
104
|
+
#
|
76
105
|
# @return: Content proxy
|
77
106
|
#
|
78
107
|
def self.create_content_proxy_for(url_or_descr, opts = {})
|
79
|
-
debug "self.create_content_proxy_for: '#{url_or_descr.inspect}'"
|
80
108
|
if url_or_descr.is_a? ContentProxy
|
81
109
|
return url_or_descr
|
82
110
|
end
|
111
|
+
debug "self.create_content_proxy_for: '#{url_or_descr.inspect}'"
|
83
112
|
|
84
113
|
if url_or_descr.is_a? String
|
85
114
|
url = url_or_descr
|
@@ -98,7 +127,8 @@ module OMF::Web
|
|
98
127
|
throw "Can't find url in '#{url_or_descr.inspect}"
|
99
128
|
end
|
100
129
|
|
101
|
-
repo = find_repo_for(url)
|
130
|
+
repo = find_repo_for(url, opts)
|
131
|
+
#puts ">>>>>> FOUND REPO: #{repo} for url #{url}"
|
102
132
|
repo.create_content_proxy_for(url_or_descr)
|
103
133
|
end
|
104
134
|
|
@@ -108,13 +138,21 @@ module OMF::Web
|
|
108
138
|
end
|
109
139
|
|
110
140
|
def self.read_content(url, opts)
|
111
|
-
find_repo_for(url).read(url)
|
141
|
+
find_repo_for(url, opts).read(url)
|
112
142
|
end
|
113
143
|
|
114
|
-
def self.find_repo_for(url)
|
144
|
+
def self.find_repo_for(url, opts = {})
|
115
145
|
parts = url.split(':')
|
116
|
-
name = parts[1]
|
117
|
-
|
146
|
+
name = (parts[parts.length == 2 ? 0 : 1]).to_sym # old style: git:name:path, new style: name:path
|
147
|
+
|
148
|
+
repo = nil
|
149
|
+
#puts "REPO SELECTOR: >>>>>>>>> #{opts[:repo_iterator]}"
|
150
|
+
if opts[:repo_iterator]
|
151
|
+
repo = opts[:repo_iterator].find {|r| r.name == name}
|
152
|
+
else
|
153
|
+
repo = @@repositories[name.to_sym]
|
154
|
+
end
|
155
|
+
unless repo
|
118
156
|
raise "Unknown repo '#{name}'"
|
119
157
|
end
|
120
158
|
return repo
|
@@ -160,13 +198,41 @@ module OMF::Web
|
|
160
198
|
# opts read_only [Boolean] If true, write will fail
|
161
199
|
def initialize(name, opts)
|
162
200
|
@name = name
|
201
|
+
@url_prefix = "#{@name}:"
|
163
202
|
@read_only = (opts[:read_only] == true)
|
164
203
|
|
165
204
|
if @top_dir = opts[:top_dir]
|
205
|
+
if @top_dir.start_with?('.') && ContentRepository.reference_dir
|
206
|
+
@top_dir = File.join(ContentRepository.reference_dir, @top_dir)
|
207
|
+
end
|
166
208
|
@top_dir = File.expand_path(@top_dir)
|
209
|
+
debug "Creating repo '#{name} with top dir: #{@top_dir}"
|
167
210
|
end
|
168
211
|
end
|
169
212
|
|
213
|
+
# Load content described by either a hash or a straightforward path
|
214
|
+
# and return a 'ContentProxy' holding it.
|
215
|
+
#
|
216
|
+
# If descr[:strictly_new] is true, return nil if file for which proxy is requested
|
217
|
+
# already exists.
|
218
|
+
#
|
219
|
+
# @return: Content proxy
|
220
|
+
#
|
221
|
+
def create_content_proxy_for(content_descr)
|
222
|
+
path = _get_path(content_descr)
|
223
|
+
# TODO: Make sure that key is really unique across multiple repositories - why?
|
224
|
+
descr = descr ? descr.dup : {}
|
225
|
+
url = get_url_for_path(path)
|
226
|
+
descr[:url] = url
|
227
|
+
descr[:path] = path
|
228
|
+
descr[:name] = url # Should be something human digestable
|
229
|
+
if (descr[:strictly_new])
|
230
|
+
return nil if exist?(path)
|
231
|
+
end
|
232
|
+
proxy = ContentProxy.create(descr, self)
|
233
|
+
return proxy
|
234
|
+
end
|
235
|
+
|
170
236
|
#
|
171
237
|
# Return an array of file names which are in the repository and
|
172
238
|
# match 'search_pattern'
|
@@ -175,6 +241,19 @@ module OMF::Web
|
|
175
241
|
raise "Missing implementation"
|
176
242
|
end
|
177
243
|
|
244
|
+
# Return true if repo is read only. Any attempts to write to
|
245
|
+
# a read only repo will result in a 'ReadOnlyContentRepositoryException'
|
246
|
+
# exception.
|
247
|
+
#
|
248
|
+
def read_only?
|
249
|
+
@read_only
|
250
|
+
end
|
251
|
+
|
252
|
+
def exist?(path)
|
253
|
+
Dir.chdir(@top_dir) do
|
254
|
+
return nil if File.exist?(path)
|
255
|
+
end
|
256
|
+
end
|
178
257
|
|
179
258
|
def mime_type_for_file(content_descriptor)
|
180
259
|
fname = content_descriptor
|
@@ -209,10 +288,42 @@ module OMF::Web
|
|
209
288
|
path = _get_path(content_descr)
|
210
289
|
end
|
211
290
|
|
291
|
+
def _get_path(content_descr)
|
292
|
+
if content_descr.is_a? String
|
293
|
+
# Old style (file:name:path) vs. new style (name:path)
|
294
|
+
path = content_descr.split(':')[-1]
|
295
|
+
unless path
|
296
|
+
raise "Can't find path information in '#{content_descr.inspect}'"
|
297
|
+
end
|
298
|
+
elsif content_descr.is_a? Hash
|
299
|
+
if (url = content_descr[:url])
|
300
|
+
path = url.split(':')[-1]
|
301
|
+
else
|
302
|
+
path = content_descr[:path]
|
303
|
+
end
|
304
|
+
unless path
|
305
|
+
raise "Missing 'path' or 'url' in content description (#{content_descr.inspect})"
|
306
|
+
else
|
307
|
+
path = path.to_s
|
308
|
+
end
|
309
|
+
else
|
310
|
+
raise "Unsupported type '#{content_descr.class}'"
|
311
|
+
end
|
312
|
+
|
313
|
+
return path
|
314
|
+
end
|
315
|
+
|
316
|
+
#
|
212
317
|
# Return a URL for a path in this repo
|
213
318
|
#
|
214
319
|
def get_url_for_path(path)
|
215
|
-
|
320
|
+
@url_prefix + path
|
321
|
+
end
|
322
|
+
|
323
|
+
# Make the repo references less verbose
|
324
|
+
def to_s
|
325
|
+
#"\#<#{self.class}-#{@name} - #{@top_dir}>"
|
326
|
+
"\#<#{self.class}-#{@name}>"
|
216
327
|
end
|
217
328
|
end # class
|
218
329
|
end # module
|
@@ -33,7 +33,7 @@ module OMF::Web
|
|
33
33
|
# @return: Content proxy
|
34
34
|
#
|
35
35
|
def create_content_proxy_for(content_descr)
|
36
|
-
debug "CREATE
|
36
|
+
debug "CREATE CONTENT PROXY: #{content_descr}"
|
37
37
|
if content_descr.is_a? String
|
38
38
|
content_descr = {text: content_descr}
|
39
39
|
end
|
@@ -57,7 +57,7 @@ module OMF::Web
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def write(content_descr, content, message)
|
60
|
-
raise
|
60
|
+
raise ReadOnlyContentRepositoryException.new
|
61
61
|
end
|
62
62
|
|
63
63
|
def mime_type_for_file(content_descriptor)
|
@@ -72,4 +72,4 @@ module OMF::Web
|
|
72
72
|
|
73
73
|
|
74
74
|
end # class
|
75
|
-
end # module
|
75
|
+
end # module
|
@@ -4,9 +4,9 @@ require 'omf-web/rack/rack_exceptions'
|
|
4
4
|
require 'omf-web/content/content_proxy'
|
5
5
|
|
6
6
|
module OMF::Web::Rack
|
7
|
-
|
7
|
+
|
8
8
|
class ContentHandler < OMF::Base::LObject
|
9
|
-
|
9
|
+
|
10
10
|
def call(env)
|
11
11
|
req = ::Rack::Request.new(env)
|
12
12
|
begin
|
@@ -17,6 +17,8 @@ module OMF::Web::Rack
|
|
17
17
|
end
|
18
18
|
method = "on_#{req.request_method().downcase}"
|
19
19
|
body, headers = c_proxy.send(method.to_sym, req)
|
20
|
+
rescue OMF::Web::ReadOnlyContentRepositoryException
|
21
|
+
return [403, {"Content-Type" => 'text'}, "Read-only repository"]
|
20
22
|
rescue MissingArgumentException => mex
|
21
23
|
debug mex
|
22
24
|
return [412, {"Content-Type" => 'text'}, [mex.to_s]]
|
@@ -28,12 +30,12 @@ module OMF::Web::Rack
|
|
28
30
|
if headers.kind_of? String
|
29
31
|
headers = {"Content-Type" => headers}
|
30
32
|
end
|
31
|
-
[200, headers, [body]]
|
33
|
+
[200, headers, [body]]
|
32
34
|
end
|
33
35
|
end # ContentHandler
|
34
|
-
|
36
|
+
|
35
37
|
end # OMF:Web
|
36
38
|
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
+
|
41
|
+
|
data/lib/omf-web/theme.rb
CHANGED
@@ -38,6 +38,20 @@ module OMF::Web::Theme
|
|
38
38
|
@@search_order = search_order if search_order
|
39
39
|
end
|
40
40
|
|
41
|
+
# Return a named renderer for this theme initialised with 'widget'
|
42
|
+
#
|
43
|
+
def self.create_renderer(name, widget)
|
44
|
+
name = name.to_sym
|
45
|
+
@@search_order.each do |theme|
|
46
|
+
if tr = @@additional_renderers[theme.to_s]
|
47
|
+
if klass = tr[name]
|
48
|
+
#self.require(name)
|
49
|
+
return klass.new(widget)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
raise "Can't find class implementing renderer '#{name}' in '#{@@search_order.join(', ')}'"
|
54
|
+
end
|
41
55
|
|
42
56
|
def self.require(name)
|
43
57
|
name = name.to_sym
|
@@ -57,6 +71,6 @@ module OMF::Web::Theme
|
|
57
71
|
#puts ">>>> #{le}"
|
58
72
|
end
|
59
73
|
end
|
60
|
-
raise "Can't find theme component '#{name}' in '#{@@search_order.join(', ')}"
|
74
|
+
raise "Can't find theme component '#{name}' in '#{@@search_order.join(', ')}'"
|
61
75
|
end
|
62
|
-
end
|
76
|
+
end
|
data/lib/omf-web/thin/logging.rb
CHANGED
@@ -23,10 +23,13 @@ module Thin
|
|
23
23
|
|
24
24
|
# Log a message to the console
|
25
25
|
def log(msg)
|
26
|
-
|
26
|
+
_logger.info(msg)
|
27
27
|
end
|
28
28
|
module_function :log
|
29
29
|
public :log
|
30
|
+
alias :log_info log
|
31
|
+
|
32
|
+
|
30
33
|
|
31
34
|
# Log a message to the console if tracing is activated
|
32
35
|
def trace(msg=nil)
|
@@ -36,18 +39,20 @@ module Thin
|
|
36
39
|
|
37
40
|
|
38
41
|
return unless msg
|
39
|
-
|
42
|
+
_logger.debug(msg)
|
40
43
|
end
|
41
44
|
module_function :trace
|
42
45
|
public :trace
|
46
|
+
alias :log_trace trace
|
43
47
|
|
44
48
|
# Log a message to the console if debugging is activated
|
45
49
|
def debug(msg=nil)
|
46
50
|
return unless msg
|
47
|
-
|
51
|
+
_logger.debug(msg)
|
48
52
|
end
|
49
53
|
module_function :debug
|
50
54
|
public :debug
|
55
|
+
alias :log_debug debug
|
51
56
|
|
52
57
|
# Log an error backtrace if debugging is activated
|
53
58
|
#
|
@@ -58,9 +63,13 @@ module Thin
|
|
58
63
|
def log_error(*args)
|
59
64
|
e = args.last
|
60
65
|
e ||= $!
|
61
|
-
|
66
|
+
_logger.error(e)
|
62
67
|
end
|
63
68
|
module_function :log_error
|
64
69
|
public :log_error
|
70
|
+
|
71
|
+
def _logger()
|
72
|
+
@logger ||= OMF::Base::Loggable.logger(:thin)
|
73
|
+
end
|
65
74
|
end
|
66
75
|
end
|