Class: OMF::Web::ContentRepository

Inherits:
Base::LObject
  • Object
show all
Defined in:
lib/omf-web/content/repository.rb

Overview

This class provides an interface to a particular content repository. It retrieves, archives and versions content.

Constant Summary collapse

MIME_TYPE =
{
  :js => 'text/javascript',
  :md => 'text/markup',
  :rb => 'text/ruby',
  :oedl => 'text/ruby',
  :r => 'text/r',
  :svg => 'text/svg',
  :txt => 'text'
}
REPO_PLUGINS =
{
  git: lambda do |name, opts|
          require 'omf-web/content/git_repository'
          return GitContentRepository.new(name, opts)
      end,
  file: lambda do |name, opts|
          require 'omf-web/content/file_repository'
          return FileContentRepository.new(name, opts)
      end,
  irods: lambda do |name, opts|
          require 'omf-web/content/irods_repository'
          return IRodsContentRepository.new(name, opts)
      end,
  static: lambda do |name, opts|
          require 'omf-web/content/static_repository'
          return StaticContentRepository.new(name, opts)
      end
}
@@primary_repository =

Repo to be used for all newly created content

nil
@@repositories =
{}
@@reference_dir =

Prepand this path if ‘top_dir’ starts with ‘.’

nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, opts) ⇒ ContentRepository

params opts [Hash] opts read_only [Boolean] If true, write will fail opts create_if_not_exists [Boolean]



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/omf-web/content/repository.rb', line 203

def initialize(name, opts)
  @name = name
  @url_prefix = "#{@name}:"
  @read_only = (opts[:read_only] == true)

  if @top_dir = opts[:top_dir]
    if @top_dir.start_with?('.') && ContentRepository.reference_dir
      @top_dir = File.join(ContentRepository.reference_dir, @top_dir)
    end
    @top_dir = File.expand_path(@top_dir)
    debug "Creating repo '#{name} with top dir: #{@top_dir}"

    _create_if_not_exists if opts[:create_if_not_exists]
  end
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



198
199
200
# File 'lib/omf-web/content/repository.rb', line 198

def name
  @name
end

#top_dirObject (readonly)

Returns the value of attribute top_dir.



198
199
200
# File 'lib/omf-web/content/repository.rb', line 198

def top_dir
  @top_dir
end

Class Method Details

.absolute_path_for(url) ⇒ Object



136
137
138
# File 'lib/omf-web/content/repository.rb', line 136

def self.absolute_path_for(url)
  find_repo_for(url).absolute_path(url)
end

.create(name, opts) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/omf-web/content/repository.rb', line 85

def self.create(name, opts)
  raise "ArgumentMismatch: Expected Hash, but got #{opts}" unless opts.is_a? Hash

  unless type = opts[:type]
    raise "Missing type in repo opts (#{opts})"
  end
  unless repo_creator = REPO_PLUGINS[type.to_sym]
    raise "Unknown repository type '#{type}'"
  end
  r = repo_creator.call(name, opts)
end

.create_content_proxy_for(url_or_descr, opts = {}) ⇒ Object

Load content described by either a hash or a straightforward url and return a ‘ContentProxy’ holding it.

@return: Content proxy



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/omf-web/content/repository.rb', line 107

def self.create_content_proxy_for(url_or_descr, opts = {})
  if url_or_descr.is_a? ContentProxy
    return url_or_descr
  end
  debug "self.create_content_proxy_for: '#{url_or_descr.inspect}'"

  if url_or_descr.is_a? String
    url = url_or_descr
  else
    if (text = url_or_descr[:text])
      # a bit of a hack for small static text blocks
      # Much better for maintenance is to use a separate file
      require 'omf-web/content/static_repository'
      url = OMF::Web::StaticContentRepository.create_from_text(url_or_descr, opts)
      #url = repo.url # "static:-"
    else
      url = url_or_descr[:url]
    end
  end
  unless url
    throw "Can't find url in '#{url_or_descr.inspect}"
  end

  repo = find_repo_for(url, opts)
  #puts ">>>>>> FOUND REPO: #{repo} for url #{url}"
  repo.create_content_proxy_for(url_or_descr)
end

.create_url(path, strictly_new = true) ⇒ Object

Create a URL for a file with ‘path’ in the user’s primary repository. If ‘strictly_new’ is true, returns nil if ‘path’ already exists.



189
190
191
192
# File 'lib/omf-web/content/repository.rb', line 189

def self.create_url(path, strictly_new = true)
  # TODO: Need to add code to select proper repository
  return GitContentRepository.create_url(path, strictly_new)
end

.find_files(selector, opts = {}) ⇒ Object

Find files whose file name matches ‘selector’.

Supported options:

* :max - Maximum numbers of matches to return
* :mime_type - Only return files with that specific mime type.
* :repo_iterator [Iterator] - Iterator over repos to search


169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/omf-web/content/repository.rb', line 169

def self.find_files(selector, opts = {})
  fsa = (opts[:repo_iterator] || [@@primary_repository]).map do |repo|
    repo.find_files(selector, opts)
  end

  fs = fsa.flatten
  if (mt = opts[:mime_type])
    fs = fs.select { |f| File.fnmatch(mt, f[:mime_type]) }
  end

  if (max = opts[:max])
    fs = fs[0, max]
  end
  fs
end

.find_repo_for(url, opts = {}) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/omf-web/content/repository.rb', line 144

def self.find_repo_for(url, opts = {})
  parts = url.split(':')
  name = (parts[parts.length == 2 ? 0 : 1]).to_sym # old style: git:name:path, new style: name:path

  repo = nil
  #puts "REPO SELECTOR: >>>>>>>>> #{opts[:repo_iterator]}"
  if opts[:repo_iterator]
    repo = opts[:repo_iterator].find {|r| r.name == name}
  else
    repo = @@repositories[name.to_sym]
  end
  unless repo
    raise "Unknown repo '#{name}'"
  end
  return repo
end

.read_content(url, opts) ⇒ Object



140
141
142
# File 'lib/omf-web/content/repository.rb', line 140

def self.read_content(url, opts)
  find_repo_for(url, opts).read(url)
end

.reference_dirObject



60
61
62
# File 'lib/omf-web/content/repository.rb', line 60

def self.reference_dir
  @@reference_dir
end

.reference_dir=(dir) ⇒ Object

Prepand this path if ‘top_dir’ starts with ‘.’



56
57
58
# File 'lib/omf-web/content/repository.rb', line 56

def self.reference_dir=(dir)
  @@reference_dir = dir
end

.register_mime_type(mapping) ⇒ Object



194
195
196
# File 'lib/omf-web/content/repository.rb', line 194

def self.register_mime_type(mapping)
  MIME_TYPE.merge!(mapping)
end

.register_repo(name, opts) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/omf-web/content/repository.rb', line 64

def self.register_repo(name, opts)
  raise "ArgumentMismatch: Expected Hash, but got #{opts}" unless opts.is_a? Hash

  name = name.to_sym
  if @@repositories[name]
    warn "Ignoring repeated registration of repo '#{name}'"
    return
  end

  # unless type = opts[:type]
    # raise "Missing type in repo opts (#{opts})"
  # end
  # unless repo_creator = REPO_PLUGINS[type.to_sym]
    # raise "Unknown repository type '#{type}'"
  # end

  @@repositories[name] = r = create(name, opts)
  @@primary_repository = r if opts[:is_primary]
  r
end

Instance Method Details

#_get_path(content_descr) ⇒ Object



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/omf-web/content/repository.rb', line 297

def _get_path(content_descr)
  if content_descr.is_a? String
    # Old style (file:name:path) vs. new style (name:path)
    path = content_descr.split(':')[-1]
    unless path
      raise "Can't find path information in '#{content_descr.inspect}'"
    end
  elsif content_descr.is_a? Hash
    if (url = content_descr[:url])
      path = url.split(':')[-1]
    else
      path = content_descr[:path]
    end
    unless path
      raise "Missing 'path' or 'url' in content description (#{content_descr.inspect})"
    else
      path = path.to_s
    end
  else
    raise "Unsupported type '#{content_descr.class}'"
  end

  return path
end

#absolute_path(content_descr) ⇒ Object



288
289
290
291
# File 'lib/omf-web/content/repository.rb', line 288

def absolute_path(content_descr)
  path = _get_path(content_descr)
  File.join(@top_dir, path)
end

#create_content_proxy_for(content_descr) ⇒ Object

Load content described by either a hash or a straightforward path and return a ‘ContentProxy’ holding it.

If descr is true, return nil if file for which proxy is requested already exists.

@return: Content proxy



227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/omf-web/content/repository.rb', line 227

def create_content_proxy_for(content_descr)
  path = _get_path(content_descr)
  # TODO: Make sure that key is really unique across multiple repositories - why?
  descr = descr ? descr.dup : {}
  url = get_url_for_path(path)
  descr[:url] = url
  descr[:path] = path
  descr[:name] = url # Should be something human digestable
  if (descr[:strictly_new])
    return nil if exist?(path)
  end
  proxy = ContentProxy.create(descr, self)
  return proxy
end

#exist?(path) ⇒ Boolean

Returns:

  • (Boolean)


258
259
260
261
262
# File 'lib/omf-web/content/repository.rb', line 258

def exist?(path)
  Dir.chdir(@top_dir) do
    return nil if File.exist?(path)
  end
end

#find_files(search_pattern, opts = {}) ⇒ Object

Return an array of file names which are in the repository and match ‘search_pattern’



246
247
248
# File 'lib/omf-web/content/repository.rb', line 246

def find_files(search_pattern, opts = {})
  raise "Missing implementation"
end

#get_url_for_path(path) ⇒ Object

Return a URL for a path in this repo



324
325
326
# File 'lib/omf-web/content/repository.rb', line 324

def get_url_for_path(path)
  @url_prefix + path
end

#mime_type_for_file(content_descriptor) ⇒ Object



264
265
266
267
268
269
270
271
# File 'lib/omf-web/content/repository.rb', line 264

def mime_type_for_file(content_descriptor)
  fname = content_descriptor
  if content_descriptor.is_a? Hash
    fname = content_descriptor[:path]
  end
  ext = fname.split('.')[-1]
  mt = MIME_TYPE[ext.to_sym] || 'text'
end

#path(content_descr) ⇒ Object



293
294
295
# File 'lib/omf-web/content/repository.rb', line 293

def path(content_descr)
  path = _get_path(content_descr)
end

#read(content_descr) ⇒ Object



273
274
275
276
277
278
279
280
281
282
# File 'lib/omf-web/content/repository.rb', line 273

def read(content_descr)
  path = _get_path(content_descr)
  Dir.chdir(@top_dir) do
    unless File.readable?(path)
      raise "Cannot read file '#{path}'"
    end
    content = File.open(path).read
    return content
  end
end

#read_only?Boolean

Return true if repo is read only. Any attempts to write to a read only repo will result in a ‘ReadOnlyContentRepositoryException’ exception.

Returns:

  • (Boolean)


254
255
256
# File 'lib/omf-web/content/repository.rb', line 254

def read_only?
  @read_only
end

#to_sObject

Make the repo references less verbose



329
330
331
332
# File 'lib/omf-web/content/repository.rb', line 329

def to_s
  #"\#<#{self.class}-#{@name} - #{@top_dir}>"
  "\#<#{self.class}-#{@name}>"
end

#write(content_descr, content, message) ⇒ Object



284
285
286
# File 'lib/omf-web/content/repository.rb', line 284

def write(content_descr, content, message)
  raise "Missing implementation"
end