class DPN::Bagit::Bag

A wrapper for an unserialized Bag-It bag on disk. Does not support serialized bags. Once created, a Bag object will not change with changes made to the underlying filesystem bag; in that case, a new Bag object should be created.

Public Class Methods

new(_location) click to toggle source
# File lib/dpn/bagit/bag.rb, line 12
  def initialize(_location)
    @settings = DPN::Bagit::Settings.instance.config
    @bag = ::BagIt::Bag.new(_location)
    @location = _location
    @cachedValidity = nil
    @cachedFixity = nil
    @cachedSize = nil
    @validationErrors = []
    @dpnObjectID = nil

    @dpnInfo = DPNInfoTxt.new(self.dpn_info_file_location())
    @dpnObjectID = @dpnInfo[:dpnObjectID]
    @dpnObjectID ||= File.basename(_location)
end

Public Instance Methods

empty?() click to toggle source

Returns true if the Bag contains no files. @return [Boolean] True if empty, false otherwise.

# File lib/dpn/bagit/bag.rb, line 162
def empty?()
  return @bag.empty?
end
errors() click to toggle source

Returns validation errors. The list is not populated until a call to {#isValid?} has been made. @return [Array<String>] The errors.

# File lib/dpn/bagit/bag.rb, line 155
def errors()
  return @dpnInfo.getErrors() + @validationErrors
end
fixity(algorithm) click to toggle source

Get the net fixity of the Bag. @param algorithm [Symbol] Algorithm to use. @return [String] The fixity of the tagmanifest-<alg>.txt file.

# File lib/dpn/bagit/bag.rb, line 32
def fixity(algorithm)
  if @cachedFixity == nil
    case algorithm
      when :sha256
        digest = Digest::SHA256
        path = File.join(@location, "tagmanifest-sha256.txt")
        if File.exists?(path)
          @cachedFixity = digest.file(path).hexdigest
        else
          @cachedFixity = ""
          @cachedValidity = false
        end
      else
        raise ArgumentError, "Unknown algorithm."
    end

  end
  return @cachedFixity
end
location() click to toggle source

Returns the local file location of the Bag. @return [String] The location, which can be relative or absolute.

# File lib/dpn/bagit/bag.rb, line 71
def location()
  return @location
end
size() click to toggle source

Returns the total size of the Bag. @return [Fixnum] Apparent size of the Bag in bytes.

# File lib/dpn/bagit/bag.rb, line 55
def size()
  if @cachedSize == nil
    size = 0
    Find.find(self.location) do |f|
      if File.file?(f) or File.directory?(f)
        size += File.size(f)
      end
    end
    @cachedSize = size
  end
  return @cachedSize
end
uuid() click to toggle source

Returns the uuid of the bag, according to dpn-info.txt. @return [String]

# File lib/dpn/bagit/bag.rb, line 78
def uuid()
  return @dpnObjectID
end
valid?() click to toggle source

Checks that all required files are present, no extraneous files are present, and all file digests match manifests. @return [Boolean] True if valid, false otherwise.

# File lib/dpn/bagit/bag.rb, line 86
def valid?()
  if @cachedValidity == nil
    if @bag.valid? == false
      @validationErrors.push(@bag.errors.full_messages)
    end

    if File.exists?(@bag.fetch_txt_file) == true
      @validationErrors.push("The file fetch.txt is present and unsupported.")
    end

    if Pathname.new(@bag.bag_dir).basename.to_s != @dpnInfo[:dpnObjectID]
      @validationErrors.push("The name of the root directory does not match the #{@settings[:bag][:dpn_info][:dpnObjectID][:name]}.")
    end

    if File.exists?(@bag.manifest_file("sha256")) == true
      if File.readable?(@bag.manifest_file("sha256")) == false
        @validationErrors.push("The file manifest-sha256.txt exists but cannot be read.")
      end
    else
      @validationErrors.push("The file manifest-sha256.txt does not exist.")
    end

    if File.exists?(@bag.tagmanifest_file("sha256")) == true
      if File.readable?(@bag.tagmanifest_file("sha256")) == false
        @validationErrors.push("The file tagmanifest-sha256.txt exists but cannot be read.")
      end
    else
      @validationErrors.push("The file tagmanifest-sha256.txt does not exist.")
    end

    if @dpnInfo[:version].to_i <= 0
      @validationErrors.push("Version must be > 0.")
    end

    uuidValidator = DPN::Bagit::UUID4Validator.new(true)
    if uuidValidator.isValid?(@dpnInfo[:dpnObjectID]) == false
      @validationErrors.push("#{@settings[:bag][:dpn_info][:dpnObjectID][:name]} with value \"#{@dpnInfo[:dpnObjectID]}\" is not a valid UUIDv4.")
    end

    if uuidValidator.isValid?(@dpnInfo[:firstVersionObjectID]) == false
      @validationErrors.push("#{@settings[:bag][:dpn_info][:firstVersionObjectID][:name]} with value \"#{@dpnInfo[:firstVersionObjectID]}\" is not a valid UUIDv4.")
    end

    @dpnInfo[:rightsObjectIDs].each do |id|
      if uuidValidator.isValid?(id) == false
        @validationErrors.push("#{@settings[:bag][:dpn_info][:rightsObjectIDs][:name]} value of \"#{id}\" is not a valid UUIDv4.")
      end
    end

    @dpnInfo[:interpretiveObjectIDs].each do |id|
      if uuidValidator.isValid?(id) == false
        @validationErrors.push("#{@settings[:bag][:dpn_info][:interpretiveObjectIDs][:name]} value of \"#{id}\" is not a valid UUIDv4.")
      end
    end


    if @validationErrors.empty? == true and @dpnInfo.getErrors.empty? == true
      @cachedValidity = true
    else
      @cachedValidity = false
    end
  end

  return @cachedValidity
end

Protected Instance Methods

dpn_info_file_location() click to toggle source

Get the path of the dpn-info.txt file for this bag. @return [String]

# File lib/dpn/bagit/bag.rb, line 169
def dpn_info_file_location()
  return File.join(@bag.bag_dir, @settings[:bag][:dpn_dir], @settings[:bag][:dpn_info][:name])
end