Class: FileRenameMappingService

Inherits:
Object
  • Object
show all
Defined in:
app/services/file_rename_mapping_service.rb

Overview

We sometimes have data with filenames that contain characters that AWS S3 cannot handle. In those cases we want to:

  1. Rename the files to something that is AWS legal. Replace all illegal characters with a _ (underscore)

  2. Ensure there are no duplicate file names after the renaming by appending a (1), (2) at the end of the filename if the file has been renamed

  3. Keep a record of all of the file names as they originally existed and what they were renamed to

  4. The record goes into a file called files_renamed.txt, which contains a list of all files that have been renamed and what they were renamed to, along with a timestamp

  5. This files_renamed.txt file gets added to the dataset as a payload file, akin to a README.txt or license.txt

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(upload_snapshot:) ⇒ FileRenameMappingService

Returns a new instance of FileRenameMappingService.



14
15
16
17
18
19
# File 'app/services/file_rename_mapping_service.rb', line 14

def initialize(upload_snapshot:)
  @upload_snapshot = upload_snapshot
  @original_filenames = @upload_snapshot.files.map { |a| a["filename"] }
  @files = parse_files_to_rename
  @renamed_files = rename_files
end

Instance Attribute Details

#filesObject (readonly)

Returns the value of attribute files.



12
13
14
# File 'app/services/file_rename_mapping_service.rb', line 12

def files
  @files
end

#original_filenamesObject (readonly)

Returns the value of attribute original_filenames.



12
13
14
# File 'app/services/file_rename_mapping_service.rb', line 12

def original_filenames
  @original_filenames
end

#renamed_filesObject (readonly)

Returns the value of attribute renamed_files.



12
13
14
# File 'app/services/file_rename_mapping_service.rb', line 12

def renamed_files
  @renamed_files
end

#upload_snapshotObject (readonly)

Returns the value of attribute upload_snapshot.



12
13
14
# File 'app/services/file_rename_mapping_service.rb', line 12

def upload_snapshot
  @upload_snapshot
end

Instance Method Details

#parse_files_to_renameObject



21
22
23
24
25
26
27
# File 'app/services/file_rename_mapping_service.rb', line 21

def parse_files_to_rename
  files = []
  @original_filenames.each do |original_filename|
    files << FileRenameService.new(filename: original_filename)
  end
  files
end

#rename_dateObject

Format: “Sep 19 2023”



59
60
61
# File 'app/services/file_rename_mapping_service.rb', line 59

def rename_date
  Time.zone.now.strftime("%d %b %Y")
end

#rename_filesObject

Make a hash containing all files that need renaming. The key of the hash is the original filename. The value of the hash is the re-named file with an index number appended.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'app/services/file_rename_mapping_service.rb', line 32

def rename_files
  @upload_snapshot.with_lock do
    @upload_snapshot.reload
    rename_index = 1
    renamed_files = {}
    @files.each do |file|
      next unless file.needs_rename?
      new_filename = file.new_filename(rename_index)
      renamed_files[file.original_filename] = new_filename
      # Also update the filename in the MigrationSnapshot
      @upload_snapshot.rename(file.original_filename, new_filename)
      rename_index += 1
    end
    @upload_snapshot.save
    renamed_files
  end
end

#rename_needed?Boolean

A rename is needed if any of the original filenames need renaming

Returns:

  • (Boolean)


51
52
53
54
55
56
# File 'app/services/file_rename_mapping_service.rb', line 51

def rename_needed?
  @files.each do |file|
    return true if file.needs_rename?
  end
  false
end

#renaming_documentObject



63
64
65
66
67
68
69
70
71
72
# File 'app/services/file_rename_mapping_service.rb', line 63

def renaming_document
  message = "Some files have been renamed to comply with AWS S3 storage requirements\n"
  message += "Rename date: #{rename_date}\n"
  message += "Original Filename\t Renamed File\n"
  @files.each do |file|
    next unless file.needs_rename?
    message += "#{file.original_filename}\t#{@renamed_files[file.original_filename]}\n"
  end
  message
end