lib/bagit/valid.rb in bagit-0.3.2 vs lib/bagit/valid.rb in bagit-0.3.4
- old
+ new
@@ -1,29 +1,45 @@
require 'validatable'
+require 'open-uri'
+require 'cgi'
+require 'logger'
module BagIt
class Bag
include Validatable
validates_true_for :consistency, :logic => Proc.new { consistent? }
validates_true_for :completeness, :logic => Proc.new { complete? }
end
module Validity
-
+ def decode_filename(s)
+ s = s.gsub('%0D',"\r")
+ s = s.gsub('%0A',"\n")
+ return s
+ end
+
# Return true if the manifest cover all files and all files are
# covered.
def complete?
+ logger = Logger.new(STDOUT)
+ if manifest_files == []
+ errors.add :completeness, "there are no manifest files"
+ end
+
unmanifested_files.each do |file|
+ logger.error("#{file} is present but not manifested".red)
errors.add :completeness, "#{file} is present but not manifested"
end
empty_manifests.each do |file|
+ logger.error("#{file} is manifested but not present".red)
errors.add :completeness, "#{file} is manifested but not present"
end
tag_empty_manifests.each do |file|
+ logger.error("#{file} is a manifested tag but not present".red)
errors.add :completeness, "#{file} is a manifested tag but not present"
end
errors.on(:completeness).nil?
end
@@ -31,44 +47,53 @@
# Return true if all manifested files message digests match.
def consistent?
(manifest_files|tagmanifest_files).each do |mf|
# get the algorithm implementation
File.basename(mf) =~ /manifest-(.+).txt$/
- algo = case $1
+ manifest_type = $1
+ algo = case manifest_type
when /sha1/i
Digest::SHA1
when /md5/i
Digest::MD5
+ when /sha256/i
+ Digest::SHA256
+ when /sha384/i
+ Digest::SHA384
+ when /sha512/i
+ Digest::SHA512
else
- :unknown
+ raise ArgumentError.new("Algorithm #{manifest_type} is not supported.")
end
# Check every file in the manifest
File.open(mf) do |io|
io.each_line do |line|
expected, path = line.chomp.split /\s+/, 2
- file = File.join(bag_dir, path)
+ file = File.join(bag_dir, decode_filename(path))
+
if File.exist? file
+
actual = algo.file(file).hexdigest
if expected != actual
+
errors.add :consistency, "expected #{file} to have #{algo}: #{expected}, actual is #{actual}"
end
end
end
end
end
-
errors.on(:consistency).nil?
end
# Checks for validity against Payload-Oxum
def valid_oxum?
bag_info["Payload-Oxum"] == payload_oxum
end
protected
-
+
# Returns all files in the instance that are not manifested
def unmanifested_files
mfs = manifested_files.map { |f| File.join bag_dir, f }
bag_files.reject { |f| mfs.member? f }
end
@@ -95,10 +120,10 @@
files = File.open(mf) do |io|
io.readlines.map do |line|
digest, path = line.chomp.split /\s+/, 2
- path
+ decode_filename(path)
end
end
(acc + files).uniq