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



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

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
  false
end

.delete_file(file_pathname, moab_signature) ⇒ Boolean

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



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

def self.delete_file(file_pathname, moab_signature)
  if file_pathname.exist? && (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
  false
end

.prune_purl_dir(id) ⇒ Object



134
135
136
137
# File 'lib/dor/services/digital_stacks_service.rb', line 134

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



129
130
131
132
# File 'lib/dor/services/digital_stacks_service.rb', line 129

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’



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

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)
      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



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

def self.rename_file(old_pathname, new_pathname, moab_signature)
  if old_pathname.exist? && (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
  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.



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

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)
    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)
    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’.



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

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)
      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



121
122
123
124
125
# File 'lib/dor/services/digital_stacks_service.rb', line 121

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