Class: PresignedUploadService
- Inherits:
-
Object
- Object
- PresignedUploadService
- Includes:
- Singleton
- Defined in:
- app/services/presigned_upload_service.rb
Constant Summary collapse
- BUCKET_NAME =
Wasabi S3 configuration (reusing existing Dragonfly config)
'heatwave-assets-usc1'- REGION =
'us-central-1'- ENDPOINT =
'https://s3.us-central-1.wasabisys.com'
Instance Method Summary collapse
-
#create_upload_from_s3_key(s3_key:, file_name:, content_type:, file_size:, category: 'photo', resource_type: nil, resource_id: nil) ⇒ Object
Create Upload record after successful direct upload.
-
#generate_presigned_url(file_name:, content_type:, file_size:, category: 'photo', resource_type: nil, resource_id: nil) ⇒ Object
Generate presigned URL for direct upload to Wasabi.
-
#initialize ⇒ PresignedUploadService
constructor
A new instance of PresignedUploadService.
Constructor Details
#initialize ⇒ PresignedUploadService
Returns a new instance of PresignedUploadService.
13 14 15 16 17 18 19 20 21 22 |
# File 'app/services/presigned_upload_service.rb', line 13 def initialize @s3_client = Aws::S3::Client.new( access_key_id: S3_DATASTORE_ACCESS_KEY, secret_access_key: S3_DATASTORE_SECRET_KEY, region: REGION, endpoint: ENDPOINT, force_path_style: true ) @s3_presigner = Aws::S3::Presigner.new(client: @s3_client) end |
Instance Method Details
#create_upload_from_s3_key(s3_key:, file_name:, content_type:, file_size:, category: 'photo', resource_type: nil, resource_id: nil) ⇒ Object
Create Upload record after successful direct upload
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 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 |
# File 'app/services/presigned_upload_service.rb', line 49 def create_upload_from_s3_key(s3_key:, file_name:, content_type:, file_size:, category: 'photo', resource_type: nil, resource_id: nil) # Extract the Dragonfly UID from the full S3 key # S3 key format: secure_assets/development/YYYY/MM/DD/HH/MM/SS/UUID/filename.ext # Dragonfly UID format: YYYY/MM/DD/HH/MM/SS/UUID/filename.ext (relative to root_path) # Remove secure_assets/env prefix (Dragonfly's root_path will add it back when generating URLs) dragonfly_uid = s3_key.gsub(%r{^secure_assets/#{Rails.env}/}, '') Rails.logger.info "S3 key: #{s3_key}" Rails.logger.info "Extracted Dragonfly UID: #{dragonfly_uid}" # Create Upload record upload = Upload.new( category: category, resource_type: resource_type, resource_id: resource_id, attachment_name: file_name, attachment_mime_type: content_type, attachment_size: file_size ) # Set expiration date upload.expiration_date = 7.days.from_now # Create Upload record by bypassing Dragonfly validation # Since the file is already in S3, we'll create the record directly begin # Create the record without validation to bypass attachment requirement upload.save(validate: false) # Manually set the UID and other fields upload.update_columns( attachment_uid: dragonfly_uid, # Use the relative path as the UID attachment_name: file_name, attachment_mime_type: content_type, attachment_size: file_size ) Rails.logger.info "Upload record created for S3 key: #{s3_key}, Dragonfly UID: #{dragonfly_uid}, ID: #{upload.id}" # Optionally, trigger any post-upload processing process_upload(upload) upload rescue StandardError => e Rails.logger.error "Failed to create Upload record: #{e.}\n#{e.backtrace&.first(5)&.join("\n")}" ErrorReporting.error(e, message: "PresignedUploadService#create_upload_from_s3_key failed for key: #{s3_key}") nil end end |
#generate_presigned_url(file_name:, content_type:, file_size:, category: 'photo', resource_type: nil, resource_id: nil) ⇒ Object
Generate presigned URL for direct upload to Wasabi
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'app/services/presigned_upload_service.rb', line 25 def generate_presigned_url(file_name:, content_type:, file_size:, category: 'photo', resource_type: nil, resource_id: nil) # file_size is passed for consistency but not used in presigned URL generation # Could be used for content_length_range validation in the future # Generate a unique key for the file key = generate_file_key(file_name, category, resource_type, resource_id) # Generate presigned URL for PUT request presigned_url = @s3_presigner.presigned_url( :put_object, bucket: BUCKET_NAME, key: key, expires_in: 3600, # 1 hour content_type: content_type ) { presigned_url: presigned_url, key: key, bucket: BUCKET_NAME, region: REGION } end |