class NewspaperWorks::Data::WorkFiles

Attributes

assigned[RW]
unassigned[RW]
work[RW]

Public Class Methods

new(work) click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 14
def initialize(work)
  @work = work
  @assigned = []
  @unassigned = []
  @derivatives = nil
end
of(work) click to toggle source

alternate constructor spelling:

# File lib/newspaper_works/data/work_files.rb, line 10
def self.of(work)
  new(work)
end

Public Instance Methods

[](name_or_id)
Alias for: get
assign(path) click to toggle source

Assign a path to assigned queue for attachment @param path [String] Path to source file

# File lib/newspaper_works/data/work_files.rb, line 92
def assign(path)
  path = normalize_path(path)
  validate_path(path)
  @assigned.push(path)
end
commit!() click to toggle source

commit pending changes to work files

beginning with removals, then with new assignments
# File lib/newspaper_works/data/work_files.rb, line 110
def commit!
  commit_unassigned
  commit_assigned
end
derivatives(fileset: nil) click to toggle source

Derivatives for specified fileset or first fileset found.

The `WorkDerivatives` adapter as assign/commmit! semantics just
like `WorkFiles`, and also acts like a hash/mapping of
destination names (usually file extension) to path of saved
derviative.  Always returns same instance (memoized after first
use) of `WorkDerivatives`.

@return [NewspaperWorks::Data::WorkDerviatives] derivatives adapter

# File lib/newspaper_works/data/work_files.rb, line 28
def derivatives(fileset: nil)
  fileset ||= @fileset
  return @derivatives unless @derivatives.nil?
  if fileset.nil?
    # for the deferred assignement case, we have no fileset yet...
    work_file = NewspaperWorks::Data::WorkFile.of(work, nil, self)
    return work_file.derivatives
  end
  # Otherwise, delegate actual construction to WorkFile.derivatives:
  @derivatives = values[0].derivatives
end
entries() click to toggle source

Array of [id, WorkFile] for each primary file @return [Array<Array>] key/value pairs for primary files of work

# File lib/newspaper_works/data/work_files.rb, line 70
def entries
  filesets.map { |fs| [fs.id, self[fs.id]] }
end
get(name_or_id) click to toggle source

Get a WorkFile adapter representing primary file, either by name or id @param name_or_id [String] Fileset id or work-local file name @return [NewspaperWorks::Data::WorkFile] adapter for persisted

primary file
# File lib/newspaper_works/data/work_files.rb, line 85
def get(name_or_id)
  return get_by_fileset_id(name_or_id) if keys.include?(name_or_id)
  get_by_filename(name_or_id)
end
Also aliased as: []
keys() click to toggle source

List of fileset (not file) id keys, presumes system like Hyrax

is only keeping a 1:1 between fileset and contained PCDM file,
because derivatives are not stored in the FileSet.

@return [String] fileset ids

# File lib/newspaper_works/data/work_files.rb, line 57
def keys
  filesets.map(&:id)
end
names() click to toggle source

List of local file names for attachments, based on original ingested

or uploaded file name.

@return [Array<String>]

# File lib/newspaper_works/data/work_files.rb, line 77
def names
  filesets.map(&method(:original_name))
end
state() click to toggle source

Assignment state @return [String] A label describing the state of assignment queues

# File lib/newspaper_works/data/work_files.rb, line 42
def state
  return 'dirty' unless @assigned.empty? && @unassigned.empty?
  return 'empty' if keys.empty?
  # TODO: implement 'pending' as intermediate state between 'dirty'
  #   and saved, where we look for saved state that matches what was
  #   previously assigned in THIS instance.  We can only know that
  #   changes initiated by this instance in this thread are pending
  #   because there's no global storage for the assignment queue.
  'saved'
end
unassign(name_or_id) click to toggle source

Assign a name or id to unassigned queue for deletion – OR – remove a

path from queue of assigned items

@param name_or_id [String] Fileset id, local file name, or source path

# File lib/newspaper_works/data/work_files.rb, line 101
def unassign(name_or_id)
  # if name_or_id is queued path, remove from @assigned queue:
  @assigned.delete(name_or_id) if @assigned.include?(name_or_id)
  # if name_or_id is known id or name, remove
  @unassigned.push(name_or_id) if include?(name_or_id)
end
values() click to toggle source

List of WorkFile for each primary file @return [Array<NewspaperWorks::Data::WorkFile>] adapter for persisted

primary file
# File lib/newspaper_works/data/work_files.rb, line 64
def values
  keys.map(&method(:get))
end

Private Instance Methods

commit_assigned() click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 167
def commit_assigned
  return if @assigned.nil? || @assigned.empty?
  ensure_depositor
  remote_files = @assigned.map do |path|
    { url: path_to_uri(path), file_name: File.basename(path) }
  end
  attrs = { remote_files: remote_files }
  # Create an environment for actor stack:
  env = Hyrax::Actors::Environment.new(@work, Ability.new(user), attrs)
  # Invoke default Hyrax actor stack middleware:
  Hyrax::CurationConcern.actor.create(env)
end
commit_unassigned() click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 151
def commit_unassigned
  # for each (name or) id to be removed from work, use actor to destroy
  @unassigned.each do |id|
    # "actor" here is simply a multi-adapter of Fileset, User
    # Calling destroy will:
    #   1. unlink fileset from work, and save work
    #   2. Destroy fileset:
    #     - :before_destroy callback will delegate derivative cleanup
    #       to derivatives service component(s).
    #     - Remove fileset from storage/persistence layers
    #     - Invoke (logging or other) :after_destroy callback
    Hyrax::Actors::FileSetActor.new(get(id).fileset, user).destroy
    work.reload
  end
end
ensure_depositor() click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 146
def ensure_depositor
  return unless @work.depositor.nil?
  @work.depositor = user.user_key
end
filesets() click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 136
def filesets
  # file sets with non-nil original file contained:
  work.members.select { |m| m.class == FileSet && m.original_file }
end
get_by_filename(name) click to toggle source

Get one WorkFile object based on filename in metadata

# File lib/newspaper_works/data/work_files.rb, line 126
def get_by_filename(name)
  r = filesets.select { |fs| original_name(fs) == name }
  # checkout first match
  r.empty? ? nil : NewspaperWorks::Data::WorkFile.of(work, r[0], self)
end
get_by_fileset_id(id) click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 119
def get_by_fileset_id(id)
  nil unless keys.include?(id)
  fileset = FileSet.find(id)
  NewspaperWorks::Data::WorkFile.of(work, fileset, self)
end
original_name(fileset) click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 132
def original_name(fileset)
  fileset.original_file.original_name
end
user() click to toggle source
# File lib/newspaper_works/data/work_files.rb, line 141
def user
  return User.find_by(email: work.depositor) unless work.depositor.nil?
  defined?(current_user) ? current_user : User.batch_user
end