Class: Bulkrax::FileFactory::InnerWorkings

Inherits:
Object
  • Object
show all
Includes:
Loggable
Defined in:
app/models/concerns/bulkrax/file_factory.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Loggable

#log_created, #log_deleted_fs, #log_updated

Constructor Details

#initialize(object_factory:) ⇒ InnerWorkings

Returns a new instance of InnerWorkings.



37
38
39
# File 'app/models/concerns/bulkrax/file_factory.rb', line 37

def initialize(object_factory:)
  @object_factory = object_factory
end

Instance Attribute Details

#object_factoryObject (readonly)

Returns the value of attribute object_factory.



41
42
43
# File 'app/models/concerns/bulkrax/file_factory.rb', line 41

def object_factory
  @object_factory
end

Instance Method Details

#destroy_existing_filesObject

Called if #replace_files is true Destroy all file_sets for this object Reload the object to ensure the remaining methods have the most up to date object



121
122
123
124
125
126
127
128
# File 'app/models/concerns/bulkrax/file_factory.rb', line 121

def destroy_existing_files
  return unless object.present? && object.file_sets.present?
  object.file_sets.each do |fs|
    Hyrax::Actors::FileSetActor.new(fs, user).destroy
  end
  @object = object.reload
  log_deleted_fs(object)
end

#file_attributes(update_files = false) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/models/concerns/bulkrax/file_factory.rb', line 57

def file_attributes(update_files = false)
  # NOTE: Unclear why we're changing a instance variable based on what was
  # passed, which itself is derived from the instance variable we're about
  # to change.  It's very easy to mutate the initialized @update_files if
  # you don't pass the parameter.
  object_factory.update_files = update_files
  hash = {}
  return hash if klass == Bulkrax.collection_model_class
  hash[:uploaded_files] = upload_ids if attributes[:file].present?
  hash[:remote_files] = new_remote_files if new_remote_files.present?
  hash
end

#file_pathsObject



104
105
106
# File 'app/models/concerns/bulkrax/file_factory.rb', line 104

def file_paths
  @file_paths ||= Array.wrap(attributes[:file])&.select { |file| File.exist?(file) }
end

#import_file(path) ⇒ Object



174
175
176
177
178
179
# File 'app/models/concerns/bulkrax/file_factory.rb', line 174

def import_file(path)
  u = Hyrax::UploadedFile.new
  u.user_id = user.id
  u.file = CarrierWave::SanitizedFile.new(path)
  update_filesets(u)
end

#import_filesArray<Integer>

Returns An array of Hyrax::UploadFile#id representing the files that we should be uploading.

Returns:

  • (Array<Integer>)

    An array of Hyrax::UploadFile#id representing the files that we should be uploading.



168
169
170
171
172
# File 'app/models/concerns/bulkrax/file_factory.rb', line 168

def import_files
  paths = file_paths.map { |path| import_file(path) }.compact
  set_removed_filesets if local_file_sets.present?
  paths
end

#import_files_filenamesObject

Retrieve the filenames for the files to be imported



114
115
116
# File 'app/models/concerns/bulkrax/file_factory.rb', line 114

def import_files_filenames
  file_paths.map { |f| f.split('/').last }
end

#local_file_setsObject



153
154
155
156
157
# File 'app/models/concerns/bulkrax/file_factory.rb', line 153

def local_file_sets
  # NOTE: we'll be mutating this list of file_sets via the import_files
  # method
  @local_file_sets ||= ordered_file_sets
end

#new_remote_filesObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'app/models/concerns/bulkrax/file_factory.rb', line 89

def new_remote_files
  return @new_remote_files if @new_remote_files

  # TODO: This code could first loop through all remote files and select
  # only the valid ones; then load the file_sets and do comparisons.
  file_sets = object_factory.class.file_sets_for(resource: object)
  @new_remote_files = parsed_remote_files.select do |file|
    # is the url valid?
    is_valid = file[:url]&.match(URI::ABS_URI)
    # does the file already exist
    is_existing = file_sets.detect { |f| f.import_url && f.import_url == file[:url] }
    is_valid && !is_existing
  end
end

#ordered_file_setsObject



159
160
161
162
163
# File 'app/models/concerns/bulkrax/file_factory.rb', line 159

def ordered_file_sets
  return [] if object.blank?

  Bulkrax.object_factory.ordered_file_sets_for(object)
end

#parsed_remote_filesObject

Its possible to get just an array of strings here, so we need to make sure they are all hashes



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/models/concerns/bulkrax/file_factory.rb', line 71

def parsed_remote_files
  return @parsed_remote_files if @parsed_remote_files.present?
  @parsed_remote_files = attributes[:remote_files] || []
  @parsed_remote_files = @parsed_remote_files.map do |file_value|
    if file_value.is_a?(Hash)
      file_value
    elsif file_value.is_a?(String)
      name = Bulkrax::Importer.safe_uri_filename(file_value)
      { url: file_value, file_name: name }
    else
      Rails.logger.error("skipped remote file #{file_value} because we do not recognize the type")
      nil
    end
  end
  @parsed_remote_files.delete(nil)
  @parsed_remote_files
end

#remove_file_set(file_set:) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'app/models/concerns/bulkrax/file_factory.rb', line 139

def remove_file_set(file_set:)
  # TODO: We need to consider the Valkyrie pathway
  file = file_set.files.first
  file.create_version
  opts = {}
  opts[:path] = file.id.split('/', 2).last
  opts[:original_name] = 'removed.png'
  opts[:mime_type] = 'image/png'

  file_set.add_file(File.open(Bulkrax.removed_image_path), opts)
  file_set.save
  ::CreateDerivativesJob.set(wait: 1.minute).perform_later(file_set, file.id)
end

#set_removed_filesetsObject



130
131
132
133
134
135
136
137
# File 'app/models/concerns/bulkrax/file_factory.rb', line 130

def set_removed_filesets
  local_file_sets.each do |fileset|
    # TODO: We need to consider the Valkyrie pathway
    next if fileset.is_a?(Valkyrie::Resource)

    remove_file_set(file_set: fileset)
  end
end

#update_file_set(file_set:, uploaded:) ⇒ NilClass

Returns indicating that we’ve successfully began work on the file_set.

Returns:

  • (NilClass)

    indicating that we’ve successfully began work on the file_set.



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'app/models/concerns/bulkrax/file_factory.rb', line 194

def update_file_set(file_set:, uploaded:)
  # TODO: We need to consider the Valkyrie pathway
  file = file_set.files.first
  uploaded_file = uploaded.file

  return nil if file.checksum.value == Digest::SHA1.file(uploaded_file.path).to_s

  file.create_version
  opts = {}
  opts[:path] = file.id.split('/', 2).last
  opts[:original_name] = uploaded_file.file.original_filename
  opts[:mime_type] = uploaded_file.content_type

  file_set.add_file(File.open(uploaded_file.to_s), opts)
  file_set.save
  ::CreateDerivativesJob.set(wait: 1.minute).perform_later(file_set, file.id)
  nil
end

#update_filesets(current_file) ⇒ Object



181
182
183
184
185
186
187
188
189
190
# File 'app/models/concerns/bulkrax/file_factory.rb', line 181

def update_filesets(current_file)
  if @update_files && local_file_sets.present?
    # NOTE: We're mutating local_file_sets as we process the updated file.
    fileset = local_file_sets.shift
    update_file_set(file_set: fileset, uploaded: current_file)
  else
    current_file.save
    current_file.id
  end
end

#upload_idsObject

Find existing files or upload new files. This assumes a Work will have unique file titles;

and that those file titles will not have changed

could filter by URIs instead (slower). When an uploaded_file already exists we do not want to pass its id in ‘file_attributes` otherwise it gets reuploaded by `work_actor`. support multiple files; ensure attributes is an Array



51
52
53
54
55
# File 'app/models/concerns/bulkrax/file_factory.rb', line 51

def upload_ids
  return [] if klass == Bulkrax.collection_model_class
  attributes[:file] = file_paths
  import_files
end

#work_files_filenamesObject

Retrieve the orginal filenames for the files to be imported



109
110
111
# File 'app/models/concerns/bulkrax/file_factory.rb', line 109

def work_files_filenames
  object.file_sets.map { |fn| fn.original_file.file_name.to_a }.flatten if object.present? && object.file_sets.present?
end