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
115
116
# 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
    # Change permissions
    FileUtils.chmod 'u=rw,go=r', 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



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? && (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_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



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

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



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

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.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 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)
    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’.



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

def self.shelve_to_stacks(workspace_content_pathname, stacks_object_pathname, content_diff)
  return false if workspace_content_pathname.nil?

  i[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