janko / uppy-s3_multipart

Provides Ruby endpoints for AWS S3 multipart uploads in Uppy
https://uppy.io/docs/aws-s3/
MIT License
65 stars 21 forks source link

Allow to customize the key generation used in the companion app #29

Closed RobertAudi closed 1 year ago

RobertAudi commented 1 year ago

Right now the generated key only preserves the original file extension, it replaces everything before by a random string:

https://github.com/janko/uppy-s3_multipart/blob/404c511859b4f3755b0274dc5f0b29f6e65c2644/lib/uppy/s3_multipart/app.rb#L42-L45

It is possible to specify multiple prefixes but it can only be done once when the app is mounted and can't be changed at runtime.

One use case is to be able to upload files in "a directory tree" defined by Uppy. For example:

audits/             <- The name of a resource
├── 42/             <- The ID of a specific resource
│  ├── users/       <- The category of uploaded files
│  │  ├── ACME\ Europe___<RANDOM STRING>.csv
│  │  └── ACME\ Asia___<RANDOM STRING>.csv
│  └── terms/
│     ├── ACME\ Europe___<RANDOM STRING>.csv
│     └── ACME\ Americas___<RANDOM STRING>.csv
└── 73/
   ├── offers/
   │  ├── Apple___<RANDOM STRING>.csv
   │  └── Google___<RANDOM STRING>.csv
   └── misc/
      ├── Apple___<RANDOM STRING>.csv
      └── Google___<RANDOM STRING>.csv

What I had to do is port the Roda app to a Rails controller just to modify the key generation like so:

      filename = params["filename"]
      file_extension = File.extname(filename)
      filepath = filename.gsub(/#{Regexp.escape(file_extension)}\z/, "")
      key = [params["prefix"], "#{filepath}__#{SecureRandom.hex}#{file_extension}"].compact_blank.join("/")
janko commented 1 year ago

You should be able to override the default multipart upload key as follows:

Shrine.plugin :uppy_s3_multipart, options: {
  create_multipart_upload: -> (request) do
     filename = request.params["filename"]
     file_extension = File.extname(filename)
     filepath = filename.gsub(/#{Regexp.escape(file_extension)}\z/, "")
     key = [request.params["prefix"], "#{filepath}__#{SecureRandom.hex}#{file_extension}"].compact_blank.join("/")

    { key: key }
  end
}