omf_web 1.2.5 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|