Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery-File-Upload rename file before upload

I'm using the lib jQuery-File-Upload to upload a file on my aws s3 bucket. My problem is I would like to rename my file before the upload because if there is special characters on the filename, the url returned by aws is not correct and I can't open it in my controller rails.

Is there a way to override a function in the lib to rename the file?

Thanks,

like image 495
Kaëris Avatar asked Oct 31 '22 01:10

Kaëris


1 Answers

I ran into a similar challenge after following the Heroku tutorial. I wanted to remove spaces from the filename and add a folder prefix based on the current project. In order to change the filename before uploading to S3, I added a submit callback where I modified the name on the client side.

fileInput.fileupload({
    ...
    submit: function (e, data) {
        // Get the original filename
        var fileName = data.originalFiles[0].name
        // Get the prefix from the form 
        var keyPrefix = form.data('key-start')
        // Combine the prefix and the original filename with start/end whitespace removed
        var fullFileName = keyPrefix + fileName.trim();
        // Replace whitespaces with underscores
        // At this step you could replace other special characters as well
        var newFileName = fullFileName.replace(/\s+/g, '_');
        // Update the form data with the new key value
        $(form.data('form-data')).attr("key", newFileName);
        // Set the form data
        data.formData = form.data('form-data');
    },
    ...
});

Since I changed the filename, I needed to ensure that S3 knows that as well. The tutorial suggested key value in the controller set_s3_direct_post method is:

key: "uploads/#{SecureRandom.uuid}/${filename}"

The key method requires that the filename match what is provided when the post URL is created (which it wouldn't because I'm not using the dynamic ${filename} value and I don't know the final filename when the direct post URL is created to specify it). I used the key_starts_with method so that I could specify the project folder prefix (with spaces removed) and S3 would just evaluate that for a match:

key_starts_with: "#{(current_project.name).strip.split(' ').join('_')}/"

My final set_s3_direct_post method was:

def set_s3_direct_post
    @s3_direct_post = S3_BUCKET.presigned_post(key_starts_with: "#{(current_project.name).strip.split(' ').join('_')}/", success_action_status: '201', acl: 'public-read')
end

More details on key_starts_with can be found in the AWS SDK for Ruby.

For reference, here is my form with the added key-start data value:

<%= simple_form_for @asset, html: {class: 'directUpload new_asset', data: { 'form-data' => (@s3_direct_post.fields), 'key-start' => "#{current_project.name}/#{SecureRandom.hex(4)}_" , 'url' => @s3_direct_post.url, 'host' => URI.parse(@s3_direct_post.url).host  } } , :url => project_assets_path(current_project) do |f| %>
    <%= f.input :name %>
    <%= f.input :file, as: :file %>
    <%= f.button :submit, "Add File", class: "addFileButton" %>
<% end %> 

In my case, I was only using this for single file uploads and only wanted to ensure spaces were removed from the filename (I was one of two users of this upload form, so special characters or other issues with the filename weren't a concern).

like image 169
Matt S Avatar answered Nov 15 '22 06:11

Matt S