diff options
Diffstat (limited to 'app/services/bulk_imports/uploads_export_service.rb')
-rw-r--r-- | app/services/bulk_imports/uploads_export_service.rb | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/app/services/bulk_imports/uploads_export_service.rb b/app/services/bulk_imports/uploads_export_service.rb new file mode 100644 index 00000000000..32cc48c152c --- /dev/null +++ b/app/services/bulk_imports/uploads_export_service.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module BulkImports + class UploadsExportService + include Gitlab::ImportExport::CommandLineUtil + + BATCH_SIZE = 100 + + def initialize(portable, export_path) + @portable = portable + @export_path = export_path + end + + def execute + portable.uploads.find_each(batch_size: BATCH_SIZE) do |upload| # rubocop: disable CodeReuse/ActiveRecord + uploader = upload.retrieve_uploader + + next unless upload.exist? + next unless uploader.file + + subdir_path = export_subdir_path(upload) + mkdir_p(subdir_path) + download_or_copy_upload(uploader, File.join(subdir_path, uploader.filename)) + rescue Errno::ENAMETOOLONG => e + # Do not fail entire export process if downloaded file has filename that exceeds 255 characters. + # Ignore raised exception, skip such upload, log the error and keep going with the export instead. + Gitlab::ErrorTracking.log_exception(e, portable_id: portable.id, portable_class: portable.class.name, upload_id: upload.id) + end + end + + private + + attr_reader :portable, :export_path + + def export_subdir_path(upload) + subdir = if upload.path == avatar_path + 'avatar' + else + upload.try(:secret).to_s + end + + File.join(export_path, subdir) + end + + def avatar_path + @avatar_path ||= portable.avatar&.upload&.path + end + end +end |