Skip to content

Instantly share code, notes, and snippets.

@no-reply
Created February 13, 2013 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save no-reply/4949442 to your computer and use it in GitHub Desktop.
Save no-reply/4949442 to your computer and use it in GitHub Desktop.
Some bag code for Hydra. Uses https://github.com/no-reply/bagit
require 'bagit'
module Hybag
module Baggable
def write_bag(path = '')
raise Exception if self.pid == '__DO_NOT_USE__'
# delete any existing bags before making a new one
self.delete_bag(path)
path = bag_dir(path)
FileUtils.mkdir_p path unless File.directory? path
bag = BagIt::Bag.new(path)
#TODO: Writing to bag files is naive; reads file out and writes it.
# Possibly there is a better way to do this.
# add the datastreams to the bag, then manifest
datastreams.each do |label, ds|
unless ds.content.nil?
label = label + mime_extension(ds)
if bag_contents.include? ds
bag.add_file(label) { |f|
f.puts ds.content
}
elsif bag_tags.include? ds
bag.add_tag_file(label) { |f|
f.puts ds.content
}
elsif bag_fedora_tags.values.include? ds
bag.add_tag_file('fedora/' + label) { |f|
f.puts ds.content
}
end
end
end
bag.manifest!
return bag
end
# just an alias for the export job's perform method against self
def queue_bag_export(path = '')
Resque.enqueue(Exporter, self.pid, path)
end
def delete_bag(path = '')
bag_path = bag_dir(path)
FileUtils.rm_rf bag_path if File.directory? bag_path
end
private
# create a safe cross-platform bag path
def bag_dir(path)
# TODO: make bag directory configurable?
path = Rails.root.join("tmp/bags", path) unless path.to_s.starts_with? Rails.root.join("tmp/bags").to_s
return File.join(path, self.pid).gsub(/:/, "_")
end
#TODO: allow selection of specific content datastreams to bag
# to ignore thumbnails and other derivitives, for example.
# return all content files for bag
def bag_contents
self.datastreams.reject { |label, ds| bag_tags.include?(label) or bag_fedora_tags.include?(label) }
end
# return all non-fedora tag files
def bag_tags
self.metadata_streams
end
# return fedora tag files
def bag_fedora_tags
self.datastreams.select { |label, ds| ds.is_a?(ActiveFedora::RelsExtDatastream) or ds.dsid == "DC"}
end
def mime_extension(ds)
if ds.kind_of?(ActiveFedora::NtriplesRDFDatastream)
ext = 'nt'
else
ext = MIME::Types[ds.mimeType].first.extensions[0]
end
return '.' + ext
end
end
end
module Hybag
class Exporter
@queue = :hybag_export
def self.perform(id, path='')
object = ActiveFedora::Base.find(id).adapt_to_cmodel
object.write_bag(path)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment