2018-03-25 16:15:39 +00:00
|
|
|
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
2018-03-25 17:30:42 +00:00
|
|
|
module ChunkedUploader
|
|
|
|
class S3
|
|
|
|
MINIMUMBUFFER_SIZE = 5.megabytes
|
|
|
|
|
2018-06-05 18:55:56 +00:00
|
|
|
S3_BUCKET_NAME = Settings.aws.bucket_name
|
2018-03-25 17:30:42 +00:00
|
|
|
|
|
|
|
# Upload a string to s3 using chunks instead of all as one string. This is useful reducing memory usage on huge files
|
|
|
|
# @param [Enumerable<String>] chunk_enum an enumerable of strings.
|
|
|
|
# @param [String] path the path to the object on your S3 bucket
|
|
|
|
# @returns the url to your uploaded file
|
|
|
|
def self.upload(path,chunk_enum, metadata={})
|
|
|
|
s3 = AWS::S3.new
|
|
|
|
bucket = s3.buckets[S3_BUCKET_NAME]
|
|
|
|
object = bucket.objects[path]
|
|
|
|
io = StringIO.new('', 'w')
|
|
|
|
content_type = metadata[:content_type] ? metadata[:content_type] : nil
|
|
|
|
begin
|
|
|
|
object.multipart_upload(:acl => :public_read, :content_type => content_type) do |upload|
|
|
|
|
chunk_enum.each do |chunk|
|
|
|
|
export_returned = io.write(chunk)
|
|
|
|
if (io.size >= MINIMUMBUFFER_SIZE)
|
|
|
|
upload.add_part(io.string)
|
|
|
|
io.reopen('')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
upload.add_part(io.string)
|
|
|
|
end
|
|
|
|
object.public_url.to_s
|
|
|
|
rescue => e
|
|
|
|
io.close
|
|
|
|
raise e
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|