Module: Ddr::Models::FileManagement

Extended by:
ActiveSupport::Concern
Included in:
Base
Defined in:
lib/ddr/models/file_management.rb

Defined Under Namespace

Classes: FileToAdd

Constant Summary collapse

EXTERNAL_FILE_PERMISSIONS =
0644

Instance Method Summary collapse

Instance Method Details

#add_external_datastream(dsid, opts = {}) ⇒ Object



127
128
129
130
131
132
133
# File 'lib/ddr/models/file_management.rb', line 127

def add_external_datastream dsid, opts={}
  klass = self.class.datastream_class_for_name(dsid)
  datastream = create_datastream(klass, dsid, controlGroup: "E")
  add_datastream(datastream)
  self.class.build_datastream_accessor(dsid)
  datastream
end

#add_external_file(file, dsid, opts = {}) ⇒ Object

Normally this method should not be called directly. Call ‘add_file` with dsid for external datastream id, or with `:external=>true` option if no spec for dsid.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ddr/models/file_management.rb', line 65

def add_external_file file, dsid, opts={}
  file_path = Ddr::Utils.file_path(file) # raises ArgumentError

  # Retrieve or create the datastream
  ds = datastreams.include?(dsid) ? datastreams[dsid] : add_external_datastream(dsid)

  unless ds.external?
    raise ArgumentError, "Cannot add external file to datastream with controlGroup \"#{ds.controlGroup}\"" 
  end

  if ds.dsLocation_changed?
    raise Ddr::Models::Error, "Cannot add external file to datastream when dsLocation change is pending."
  end

  # Set the MIME type
  # The :mime_type option will be present when called from `add_file`.
  # The fallback is there in case `add_external_file` is called directly.
  ds.mimeType = opts[:mime_type] || Ddr::Utils.mime_type_for(file, file_path)

  # Copy the file to storage unless we're using the original
  if opts[:use_original]
    raise Ddr::Models::Error, "Cannot add file to repository that is owned by another user." unless File.owned?(file_path)
    store_path = file_path
  else
    # generate new storage path for file
    store_path = create_external_file_path!(ds)
    # copy the original file to the storage location
    FileUtils.cp file_path, store_path
  end

  # set appropriate permissions on the file
  set_external_file_permissions!(store_path)

  # set dsLocation to file URI for storage path
  ds.dsLocation = Ddr::Utils.path_to_uri(store_path)
end

#add_file(file, dsid, opts = {}) ⇒ Object

add_file(file, dsid, opts={})

Comparable to Hydra::ModelMethods#add_file(file, dsid, file_name)

Options:

:mime_type - Explicit mime type to set (otherwise discerned from file path or name)

:original_name - A String value will be understood as the original name of the file.
                 `false` or `nil` indicate that the file basename is not the original 
                 name. Default processing will take the file basename as the original 
                 name.

:external - Add to file to external datastream. Not required for datastream specs
            where :control_group=>"E".

:use_original - For external datastream file, do not copy file to new file path,
                but use in place (set dsLocation to file URI for current path.


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ddr/models/file_management.rb', line 42

def add_file file, dsid, opts={}
  opts[:mime_type] ||= Ddr::Utils.mime_type_for(file)

  # @file_to_add is set for callbacks to access the data
  original_name = opts.fetch(:original_name, Ddr::Utils.file_name_for(file))
  self.file_to_add = FileToAdd.new(file, dsid, original_name)

  run_callbacks(:add_file) do
    if opts.delete(:external) || datastreams.include?(dsid) && datastreams[dsid].external?
      add_external_file(file, dsid, opts)
    else
      file = File.new(file, "rb") if Ddr::Utils.file_path?(file)
      # ActiveFedora method accepts file-like objects, not paths
      add_file_datastream(file, dsid: dsid, mimeType: opts[:mime_type]) 
    end
  end

  # clear the instance data
  self.file_to_add = nil
end

#create_external_file_path!(ds) ⇒ Object

Create directory (if necessary) for newly generated file path and return path



103
104
105
106
107
# File 'lib/ddr/models/file_management.rb', line 103

def create_external_file_path! ds
  file_path = generate_external_file_path(ds)
  FileUtils.mkdir_p(File.dirname(file_path))
  file_path
end

#external_datastream_file_pathsObject



123
124
125
# File 'lib/ddr/models/file_management.rb', line 123

def external_datastream_file_paths
  external_datastreams.map(&:file_paths).flatten
end

#external_datastreamsObject



119
120
121
# File 'lib/ddr/models/file_management.rb', line 119

def external_datastreams
  datastreams.values.select { |ds| ds.external? }
end

#generate_external_file_path(ds) ⇒ Object

Generates a new external file storage location

> #external_file_store/1/e/69/1e691815-0631-4f9b-8e23-2dfb2eec9c70



114
115
116
117
# File 'lib/ddr/models/file_management.rb', line 114

def generate_external_file_path ds
  file_name = generate_external_file_name(ds)
  File.join(external_file_store(ds.dsid), generate_external_directory_subpath, file_name)
end