Last active
March 22, 2017 17:58
-
-
Save hellbunnie/55d6dce0e026ce5f842ac81b8a9eb277 to your computer and use it in GitHub Desktop.
Example using MOAB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# require the moab_versioning gem | |
require 'moab' | |
# Load an object to work with (in this case a Fedora object) | |
object = ActiveFedora::Base.find(your-object-id, {:cast => true}) | |
# Set our version | |
version = 1 | |
# Set up our MOAB directories | |
local_storage_dir = "/path/to/your/storage/directory" | |
version_string = 'v%04d' % version.to_s | |
version_path = File.join(local_storage_dir, object.id, version_string) | |
data_path = File.join(version_path, "data") | |
metadata_path = File.join(data_path, "metadata") | |
content_path = File.join(data_path, "content") | |
manifest_path = File.join(version_path, "manifests") | |
make_dir version_path | |
make_dir data_path | |
make_dir metadata_path | |
make_dir content_path | |
make_dir manifest_path | |
# Save the resource | |
File.write(File.join(metadata_path, 'resource.rdf'), object.resource.dump(:ttl) ) | |
# Save the permissions | |
File.write(File.join(metadata_path, 'permissions.rdf'), object.permissions.inspect ) | |
# Save any attached files | |
name = "descMetadata" | |
datastream = object.attached_files['name']) | |
data = datastream.content | |
File.write(File.join(metadata_path, "#{name.to_s}.xml"), data) unless data.nil? | |
# Now create the manifests | |
signature_catalog = Moab::SignatureCatalog.new(:digital_object_id => object.id, :version_id => 1) | |
version_inventory = Moab::FileInventory.new(:type => 'version', :version_id => version, :digital_object_id => object.id) | |
file_group = Moab::FileGroup.new(:group_id=>'metadata').group_from_directory(Pathname.new(metadata_path)) | |
version_inventory.groups << file_group | |
file_group = Moab::FileGroup.new(:group_id=>'content').group_from_directory(Pathname.new(content_path)) | |
version_inventory.groups << file_group | |
version_additions = signature_catalog.version_additions(version_inventory) | |
signature_catalog.update(version_inventory, Pathname.new( data_path )) | |
file_inventory_difference = Moab::FileInventoryDifference.new | |
file_inventory_difference.compare(Moab::FileInventory.new(), version_inventory) | |
signature_catalog.write_xml_file(Pathname.new(manifest_path)) | |
version_inventory.write_xml_file(Pathname.new(manifest_path)) | |
version_additions.write_xml_file(Pathname.new(manifest_path)) | |
file_inventory_difference.write_xml_file(Pathname.new(manifest_path)) | |
manifest_inventory = Moab::FileInventory.new(:type => 'manifests', :digital_object_id=>object.id, :version_id => version) | |
manifest_inventory.groups << Moab::FileGroup.new(:group_id=>'manifests').group_from_directory(manifest_path(object.id, recursive=false) | |
manifest_inventory.write_xml_file(Pathname.new(manifest_path)) | |
# Updating manifests on subsequent versions | |
# Update the version number | |
new_version = version + 1 | |
# Update the paths and create new MOAB directories | |
new_version_string = 'v%04d' % new_version.to_s | |
new_version_path = File.join(local_storage_dir, object.id, new_version_string) | |
new_data_path = File.join(new_version_path, "data") | |
new_metadata_path = File.join(new_data_path, "metadata") | |
new_content_path = File.join(new_data_path, "content") | |
new_manifest_path = File.join(new_version_path, "manifests") | |
make_dir new_version_path | |
make_dir new_data_path | |
make_dir new_metadata_path | |
make_dir new_content_path | |
make_dir new_manifest_path | |
# As for version 1 we should now save out all of our added or modified metadata and asset files | |
# Load the version inventory for the last version | |
last_version_inventory = Moab::FileInventory.new(:type => 'version', :version_id => last_version.to_i, :digital_object_id => object.id) | |
last_version_inventory.parse(Pathname.new(File.join(manifest_path, 'versionInventory.xml')).read) | |
# Create a new version inventory for the new version | |
# But beware! In order for it to know about files that were deleted, added, modified you need to first populate | |
# it with the information from the previous version of versionInventory.xml and then update it using the functions provided | |
version_inventory = Moab::FileInventory.new(:type => 'version', :version_id => last_version.to_i, :digital_object_id => object.id) | |
version_inventory.parse(Pathname.new(File.join(manifest_path,'versionInventory.xml')).read) | |
version_inventory.version_id = version_inventory.version_id + 1 | |
# For each added file we must create a signature and a File Instances and add this to the version inventory manifest | |
file = "name-of-your-new-file" | |
path = new_content|metadata_path | |
file_signature = Moab::FileSignature.new() | |
file_signature.signature_from_file(Pathname.new(File.join(path, file))) | |
file_instance = Moab::FileInstance.new() | |
file_instance.instance_from_file(Pathname.new(File.join(path, file)), Pathname.new(path)) | |
version_inventory.groups.find {|g| g.group_id == type.to_s }.add_file_instance(file_signature, file_instance) | |
# For each modified file we have to do the same, but remove the old version of the file first | |
file = "name-of-your-modified-file" | |
path = new_content|metadata_path | |
version_inventory.groups.find {|g| g.group_id == type.to_s }.remove_file_having_path(file) | |
file_signature = Moab::FileSignature.new() | |
file_signature.signature_from_file(Pathname.new(File.join(path, file))) | |
file_instance = Moab::FileInstance.new() | |
file_instance.instance_from_file(Pathname.new(File.join(path, file)), Pathname.new(path)) | |
version_inventory.groups.find {|g| g.group_id == type.to_s }.add_file_instance(file_signature, file_instance) | |
# For each deleted file we just have to delete it | |
file = "name-of-the-file-to-delete" | |
version_inventory.groups.find {|g| g.group_id == type.to_s }.remove_file_having_path(file) | |
# Update the rest of the manifest files | |
signature_catalog = Moab::SignatureCatalog.new(:digital_object_id => object.id) | |
signature_catalog.parse(Pathname.new(File.join(manifest_path,'signatureCatalog.xml')).read) # parse the old catalog | |
signature_catalog.update(version_inventory, Pathname.new( new_data_path )) | |
version_additions = signature_catalog.version_additions(version_inventory) | |
file_inventory_difference = Moab::FileInventoryDifference.new | |
file_inventory_difference.compare(last_version_inventory, version_inventory) | |
signature_catalog.write_xml_file(Pathname.new(new_manifest_path)) | |
version_inventory.write_xml_file(Pathname.new(new_manifest_path)) | |
version_additions.write_xml_file(Pathname.new(new_manifest_path)) | |
file_inventory_difference.write_xml_file(Pathname.new(new_manifest_path)) | |
# And finally create the manifest inventory | |
manifest_inventory = Moab::FileInventory.new(:type => 'manifests', :digital_object_id=>object.id, :version_id => new_version) | |
manifest_inventory.groups << Moab::FileGroup.new(:group_id=>'manifests').group_from_directory(new_manifest_path, recursive=false) | |
manifest_inventory.write_xml_file(Pathname.new(new_manifest_path)) | |
# We may also want to verify our manifests | |
aip_dir = File.join(local_storage_dir, object.id, version_string, "data") # Same as the data path above | |
storage_object = Moab::StorageObject.new(object.id, aip_dir) | |
storage_object_version = Moab::StorageObjectVersion.new(storage_object, version_id=version.to_i) | |
result = storage_object_version.verify_version_storage | |
result.verified.should be true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment