Class: OMF::Web::IRodsContentRepository

Inherits:
ContentRepository show all
Defined in:
lib/omf-web/content/irods_repository.rb

Overview

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

Constant Summary collapse

@@irods_repositories =
{}

Constants inherited from ContentRepository

ContentRepository::MIME_TYPE, ContentRepository::REPO_PLUGINS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ContentRepository

absolute_path_for, create, create_content_proxy_for, create_url, #exist?, find_files, find_repo_for, #mime_type_for_file, #path, read_content, #read_only?, reference_dir, reference_dir=, register_mime_type, register_repo, #to_s

Constructor Details

#initialize(name, opts) ⇒ IRodsContentRepository

Returns a new instance of IRodsContentRepository.



48
49
50
51
52
53
54
55
# File 'lib/omf-web/content/irods_repository.rb', line 48

def initialize(name, opts)
  super
  unless @top_dir
    raise "No top_dir defined (#{opts.keys.inspect})"
  end
  @url_prefix = "irods:#{name}:"
  @ticket = opts[:ticket]
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



46
47
48
# File 'lib/omf-web/content/irods_repository.rb', line 46

def name
  @name
end

#top_dirObject (readonly)

Returns the value of attribute top_dir.



46
47
48
# File 'lib/omf-web/content/irods_repository.rb', line 46

def top_dir
  @top_dir
end

Class Method Details

.[](name) ⇒ Object

Return the repository which is referenced to by elements in ‘opts’.



21
22
23
24
25
26
# File 'lib/omf-web/content/irods_repository.rb', line 21

def self.[](name)
  unless repo = @@irods_repositories[name.to_sym]
    raise "Unknown iRODS repo '#{name}'"
  end
  repo
end

.register_file_repo(name, top_dir, is_primary = false) ⇒ Object

Register an existing directory to the system. It will be consulted for all content url’s starting with ‘irods:top_dir:’. If ‘is_primary’ is set to true, it will become the default repo for all newly created content in this app.



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/omf-web/content/irods_repository.rb', line 34

def self.register_file_repo(name, top_dir, is_primary = false)
  name = name.to_sym
  if @@irods_repositories[name]
    warn "Ignoring repeated registration of iRODS rep '#{name}'"
    return
  end
  repo = @@irods_repositories[name] = self.new(name, top_dir)
  if is_primary
    @@primary_repository = repo
  end
end

Instance Method Details

#_find_files(search_pattern, dir, res, mime_type) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/omf-web/content/irods_repository.rb', line 113

def _find_files(search_pattern, dir, res, mime_type)
  dir.list.each do |e|
    if e.directory?
      _find_files(search_pattern, e, res, mime_type)
    else
      path = e.path
      if path.match(search_pattern)
        mt = mime_type_for_file(path)
        # subselect mime type in class method
        #next if mime_type != nil && !File.fnmatch(mime_type, mt)
        res << {:url => get_url_for_path(path), :path => path, #:name => 'foo',
                :mime_type => mt}
      end
    end
  end
  res
end

#_get_path(content_descr) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/omf-web/content/irods_repository.rb', line 167

def _get_path(content_descr)
  #puts ">>>GET PATH #{content_descr.inspect}"
  if content_descr.is_a? String
    path = content_descr.to_s
    if path.start_with? 'irods:'
      path = File.join(@top_dir, path.split(':')[2])
    end
  elsif content_descr.is_a? Hash
    descr = content_descr
    unless path = descr[:path]
      if url = descr[:url]
        path = File.join(@top_dir, url.split(':')[2]) # irods:repo_name:path
      end
    end
    unless path
      raise "Missing 'path' or 'url' in content description (#{descr.inspect})"
    end
    path = path.to_s
  else
    raise "Unsupported type '#{content_descr.class}'"
  end
  unless path
    raise "Can't find path information in '#{content_descr.inspect}'"
  end
  return path
end

#absolute_path(content_descr) ⇒ Object

HACK ALERT!!!

This method may be called by an entity which wants to access the content directly through the file system. In the absence of a FUSE mounted iRODS repo, we ‘iget’ the resource to a temporary directory and return that path. The calling entity needs to be aware that any changes to that file will NOT show up in iRODS without an iput.

This should really NOT be necessary. Use FUSE



152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/omf-web/content/irods_repository.rb', line 152

def absolute_path(content_descr)
  path = _get_path(content_descr)

  require 'etc'
  tmp_dir = "#{Dir::tmpdir}/LabWiki-#{Etc.getlogin}"
  # unless Dir.exists? tmp_dir
    # Dir.mkdir tmp_dir, 0700
  # end

  target = File.join(tmp_dir, path)
  IRODS4r::ICommands.export(path, target, true, @ticket)
  target
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



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

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

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

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



102
103
104
105
106
107
108
109
110
111
# File 'lib/omf-web/content/irods_repository.rb', line 102

def find_files(search_pattern, opts = {})
  begin
    dir = IRODS4r.find(@top_dir, {}, @ticket)
  rescue IRODS4r::IRODS4rException
    return []
  end
  res = []
  _find_files(search_pattern, dir, res, opts[:mime_type])
  res
end

#get_url_for_path(path) ⇒ Object

Return a URL for a path in this repo



134
135
136
137
138
139
140
# File 'lib/omf-web/content/irods_repository.rb', line 134

def get_url_for_path(path)
  # puts "PATH>>>>> '#{path}:#{path.class}'-'#{@top_dir}:#{@top_dir.class}'"
  if m = path.match("#{@top_dir}(.*)")
    path = m[1]
  end
  url = @url_prefix + path
end

#read(content_descr) ⇒ Object



91
92
93
94
95
96
# File 'lib/omf-web/content/irods_repository.rb', line 91

def read(content_descr)
  path = _get_path(content_descr)
  #puts "READ PATHS>>> #{path}"
  f = IRODS4r::File.create(path, false, ticket: @ticket)
  f.read()
end

#write(content_descr, content, message) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/omf-web/content/irods_repository.rb', line 82

def write(content_descr, content, message)
  raise ReadOnlyContentRepositoryException.new if @read_only

  path = _get_path(content_descr)
  #puts "WRITE PATHS>>> #{path}"
  f = IRODS4r::File.create(path, false, ticket: @ticket)
  f.write(content)
end