Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

s3 and renameFile #299

Open
smakman opened this issue Mar 1, 2018 · 12 comments
Open

s3 and renameFile #299

smakman opened this issue Mar 1, 2018 · 12 comments

Comments

@smakman
Copy link

smakman commented Mar 1, 2018

I'm trying to rename files before uploading to S3, using:

dropzoneOptions: {
  renameFile (file) {
    file.name = new Date().getTime() + '_' + file.name; // results in Uncaught TypeError: Cannot assign to read only property 'name' of object '#<File>'
    // or 
    file.upload.filename = new Date().getTime() + '_' + file.name; // results in Uncaught TypeError: Cannot set property 'filename' of undefined
  }
}

Is it even possible to rename files before they get uploaded to S3? Or this there another way to avoid files with the same name from being overwritten in S3?

@rowanwins
Copy link
Owner

Gday @smakman

Sorry for the slow reply. I've not looked at this before but my understanding doing a bit of googling is that this needs to be used something like

renameFile : function(filename, file) {
    return 'SomeNewFilename'
}

let me know if that works...

@smakman
Copy link
Author

smakman commented Mar 12, 2018

No worries @rowanwins. The renameFile function only receives one argument containing the file object. And it doesn't work either when returning some new value.

@rowanwins
Copy link
Owner

Righto just had a bit more a play and this appears to work

        renameFile(file) {
            return file.renameFilename = "YourNewfileName"
        },

Idea stolen from here. Not terribly intuitive but appears to work 🤷

@smakman
Copy link
Author

smakman commented Mar 12, 2018

Doesn't work either on my end. I can see a property called renameFilename is set on the file object, which wasn't there before, but it doesn't get used.

@shinwang1
Copy link

I'm curious @smakman , are you getting an large string appended to your filename when you upload to s3? I'm uploading a lot of files to my web app, and the string length is causing 500 errors for the server.

@HoukasaurusRex
Copy link

Accessing the fileName value in the fileMeta object from within this.on('sending', ()=>{}) seems to work for me:

$('#myDropzone').dropzone({
    const date = new Date().getTime();
    init() {
        // Send file starts
        self.on('sending', (file) => {
          file.fileMeta = {
            fileName: '${date} ${file.name}',
            size: file.size,
            date
          };
    }
});

@rowanwins
Copy link
Owner

Thanks for chiming in @pterobyte . I wonder if you could do something hooking into the sending event emitted from the vue component, see example here.

@vesper8
Copy link

vesper8 commented May 27, 2018

can't get this to work at all... tried so many solutions including using the event you just referenced @rowanwins

@pterobyte the code you shared doesn't work for me, it doesn't appear to be valid syntax and is it even compatible with vue-dropzone?

dropzone does support file renaming and the function doesn't throw an error or anything, but the filename that is uploaded to S3 is always whatever the filename is.. seems like there's nom way to change it

this might have to do with the implementation of direct-to-s3 in this package

if anyone figures it out please reply..

@vesper8
Copy link

vesper8 commented May 27, 2018

I did just noticed something

renameFile doesn't work with sendFileToServer set to true, but it does work when set to false (the file is properly renamed before uploaded to S3)

@mariusa
Copy link

mariusa commented Aug 28, 2018

This works for me:


import vue2Dropzone from 'vue2-dropzone'
import 'vue2-dropzone/dist/vue2Dropzone.min.css'

export default {
...
}

function renameFile (file) {
    l("renameFile", file)
    return "something." + file.name.toLowerCase().split('.').pop()
}

However, we also need to access the vue instance data, eg. this.user
These aren't available outside of export

How can renameFile be used as a vue instance method, similar to s3UploadSuccess(), so that we can access vue data ?

@humbugz
Copy link

humbugz commented May 14, 2019

An old issue, but for anyone else who happens upon this as I did:

As far as I can tell, renameFile() does not work when uploading directly to S3.

There is one possible solution that is fairly easy though: Since the S3 upload destination is determined by your signed URL, you can rename the file in your signing method.

Your signing process has steps for creating the policy and form data, such as (PHP example):

$policy = [
            'expiration' => gmdate('Y-m-d\TG:i:s\Z', strtotime('+3 hours')),
            'conditions' => [
                ['bucket' => $s3Bucket],
                ['acl' => $acl],
                ['starts-with', '$key', ''],
                ['starts-with', '$Content-Type', ''],
                ['starts-with', '$Content-Length', ''],
                ['success_action_status' => $successStatus],
                ['x-amz-credential' => $credentials],
                ['x-amz-algorithm' => $algorithm],
                ['x-amz-date' => $date],
                ['x-amz-expires' => $expires],
                ['key' => $fileName],
            ]
        ];

Whatever you assign as the file name to 'key' is what will be used on the S3 side. Rename it before setting key and S3 will store the renamed version of whatever you are uploading regardless of the source file name.

One catch: dropzone's UI will show the original file name despite it being renamed on the S3 side.

Hope that helps someone...

@techpeace
Copy link

To follow on @humbugz answer, the following post was helpful for determining a Rails solution:

module Attachable
  extend ActiveSupport::Concern

  included do
    after_save :sanitize_attachment_uri!

    # Sanitize the URL of an uploaded file to ensure background
    # images function in CSS.
    #
    # @return [void]
    def sanitize_attachment_uri!
      return unless attachment.attached?

      new_filename =
        attachment.filename.to_s.split('.').first.parameterize +
        attachment.filename.extension

      attachment.blob.update!(filename: new_filename)
    end
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants