Class: Dor::DigitalStacksService

Inherits:
Object
  • Object
show all
Defined in:
lib/dor/services/digital_stacks_service.rb

Class Method Summary collapse

Class Method Details

.copy_file(workspace_pathname, stacks_pathname, moab_signature) ⇒ Boolean

Copy a file to stacks, but only if it does not yet exist with the expected signature


103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/dor/services/digital_stacks_service.rb', line 103

def self.copy_file(workspace_pathname, stacks_pathname, moab_signature)
  if stacks_pathname.exist?
    file_signature = Moab::FileSignature.new.signature_from_file(stacks_pathname)
    stacks_pathname.delete if (file_signature != moab_signature)
  end
  unless stacks_pathname.exist?
    stacks_pathname.parent.mkpath
    FileUtils.cp workspace_pathname.to_s, stacks_pathname.to_s
    return true
  end
  return false
end

.delete_file(file_pathname, moab_signature) ⇒ Boolean

Delete a file, but only if it exists and matches the expected signature


26
27
28
29
30
31
32
33
34
35
# File 'lib/dor/services/digital_stacks_service.rb', line 26

def self.delete_file(file_pathname, moab_signature)
  if file_pathname.exist? and (file_pathname.size == moab_signature.size)
    file_signature = Moab::FileSignature.new.signature_from_file(file_pathname)
    if (file_signature == moab_signature)
      file_pathname.delete
      return true
    end
  end
  return false
end

.prune_purl_dir(id) ⇒ Object


136
137
138
139
# File 'lib/dor/services/digital_stacks_service.rb', line 136

def self.prune_purl_dir(id)
  druid = DruidTools::PurlDruid.new(id, Dor::Config.stacks.local_document_cache_root)
  druid.prune!
end

.prune_stacks_dir(id) ⇒ Object

Assumes the digital stacks storage root is mounted to the local file system TODO since this is delegating to the Druid, this method may not be necessary


131
132
133
134
# File 'lib/dor/services/digital_stacks_service.rb', line 131

def self.prune_stacks_dir(id)
  stacks_druid_tree = DruidTools::StacksDruid.new(id, Config.stacks.local_stacks_root)
  stacks_druid_tree.prune!
end

.remove_from_stacks(stacks_object_pathname, content_diff) ⇒ Object

Delete files from stacks that have change type 'deleted', 'copydeleted', or 'modified'


11
12
13
14
15
16
17
18
19
20
# File 'lib/dor/services/digital_stacks_service.rb', line 11

def self.remove_from_stacks(stacks_object_pathname, content_diff)
  [:deleted, :copydeleted, :modified].each do |change_type|
    subset = content_diff.subset(change_type) # {Moab::FileGroupDifferenceSubset}
    subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
      moab_signature = moab_file.signatures.first # {Moab::FileSignature}
      file_pathname = stacks_object_pathname.join(moab_file.basis_path)
      self.delete_file(file_pathname, moab_signature)
    end
  end
end

.rename_file(old_pathname, new_pathname, moab_signature) ⇒ Boolean

Rename a file, but only if it exists and has the expected signature


67
68
69
70
71
72
73
74
75
76
77
# File 'lib/dor/services/digital_stacks_service.rb', line 67

def self.rename_file(old_pathname, new_pathname, moab_signature)
  if old_pathname.exist? and (old_pathname.size == moab_signature.size)
    file_signature = Moab::FileSignature.new.signature_from_file(old_pathname)
    if (file_signature == moab_signature)
      new_pathname.parent.mkpath
      old_pathname.rename(new_pathname)
      return true
    end
  end
  return false
end

.rename_in_stacks(stacks_object_pathname, content_diff) ⇒ Object

Rename files from stacks that have change type 'renamed' using an intermediate temp filename. The 2-step renaming allows chained or cyclic renames to occur without file collisions.


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/dor/services/digital_stacks_service.rb', line 41

def self.rename_in_stacks(stacks_object_pathname, content_diff)
  subset = content_diff.subset(:renamed) # {Moab::FileGroupDifferenceSubset

  # 1st Pass - rename files from original name to checksum-based name
  subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
    moab_signature = moab_file.signatures.first # {Moab::FileSignature}
    original_pathname = stacks_object_pathname.join(moab_file.basis_path)
    temp_pathname = stacks_object_pathname.join(moab_signature.checksums.values.last)
    self.rename_file(original_pathname, temp_pathname, moab_signature)
  end

  # 2nd Pass - rename files from checksum-based name to new name
  subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
    moab_signature = moab_file.signatures.first # {Moab::FileSignature}
    temp_pathname = stacks_object_pathname.join(moab_signature.checksums.values.last)
    new_pathname = stacks_object_pathname.join(moab_file.other_path)
    self.rename_file(temp_pathname, new_pathname, moab_signature)
  end

end

.shelve_to_stacks(workspace_content_pathname, stacks_object_pathname, content_diff) ⇒ Object

Add files to stacks that have change type 'added', 'copyadded' or 'modified'.


83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/dor/services/digital_stacks_service.rb', line 83

def self.shelve_to_stacks(workspace_content_pathname, stacks_object_pathname, content_diff)
  return false if workspace_content_pathname.nil?
  [:added, :copyadded, :modified,].each do |change_type|
    subset = content_diff.subset(change_type) # {Moab::FileGroupDifferenceSubset
    subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
      moab_signature = moab_file.signatures.last # {Moab::FileSignature}
      filename = (change_type == :modified) ? moab_file.basis_path : moab_file.other_path
      workspace_pathname = workspace_content_pathname.join(filename)
      stacks_pathname = stacks_object_pathname.join(filename)
      self.copy_file(workspace_pathname, stacks_pathname, moab_signature)
    end
  end
  true
end

.transfer_to_document_store(id, content, filename) ⇒ void

This method returns an undefined value.

Create a file inside the content directory under the stacks.local_document_cache_root


123
124
125
126
127
# File 'lib/dor/services/digital_stacks_service.rb', line 123

def self.transfer_to_document_store(id, content, filename)
  druid = DruidTools::PurlDruid.new id, Config.stacks.local_document_cache_root
  druid.content_dir # create the druid tree if it doesn't exist yet
  File.open(File.join(druid.content_dir, filename), 'w') { |f| f.write content }
end