jam-cloud/ruby/lib/jam_ruby/lib/s3_manager.rb

150 lines
4.0 KiB
Ruby

require 'aws-sdk'
require 'active_support/all'
require 'openssl'
module JamRuby
class S3Manager
@@def_opts = { :expires => 3600 * 24, :secure => true } # 24 hours from now
S3_PREFIX = 's3://'
def initialize(aws_bucket, aws_key, aws_secret)
@aws_bucket = aws_bucket
@s3 = AWS::S3.new(:access_key_id => aws_key, :secret_access_key => aws_secret)
@aws_key = aws_key
@aws_secret = aws_secret
end
def s3_url(filename)
"#{S3_PREFIX}#{@aws_bucket}/#{filename}"
end
def s3_url?(filename)
filename.start_with? S3_PREFIX
end
def url(filename, options = @@def_opts)
"http#{options[:secure] ? "s" : ""}://s3.amazonaws.com/#{@aws_bucket}/#{filename}"
end
# XXX: the client can not support HTTPS atm!!! AGH Change the :url to => https://s3.jamkazam.com when client supports https
# is_native_client check?
def upload_sign(filename, content_md5, part_number, upload_id)
hdt = http_date_time
str_to_sign = "PUT\n#{content_md5}\n#{content_type}\n#{hdt}\n/#{@aws_bucket}/#{filename}?partNumber=#{part_number}&uploadId=#{upload_id}"
signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), @aws_secret, str_to_sign)).chomp
{ :datetime => hdt,
:md5 => content_md5,
:url => "http://s3.amazonaws.com/#{@aws_bucket}/#{filename}?partNumber=#{part_number}&uploadId=#{upload_id}",
:authorization => "AWS #{@aws_key}:#{signature}"
}
end
def sign_url(key, options = @@def_opts, operation = :read)
s3_bucket.objects[key].url_for(operation, options).to_s
end
def public_url(key, options = @@def_opts)
s3_bucket.objects[key].public_url(options).to_s
end
def presigned_post(key, options = @@def_opts)
s3_bucket.objects[key].presigned_post(options)
end
def multipart_upload_start(upload_filename)
s3_bucket.objects[upload_filename].multipart_upload.id
end
def multipart_upload_complete(upload_filename, upload_id)
s3_bucket.objects[upload_filename].multipart_uploads[upload_id].complete(:remote_parts)
end
def multipart_upload_abort(upload_filename, upload_id)
s3_bucket.objects[upload_filename].multipart_uploads[upload_id].abort
end
def multiple_upload_find_part(upload_filename, upload_id, part)
s3_bucket.objects[upload_filename].multipart_uploads[upload_id].parts[part]
end
def exists?(filename)
s3_bucket.objects[filename].exists?
end
def delete(filename)
s3_bucket.objects[filename].delete
end
def upload(key, filename, options={})
options[:file] = filename
s3_bucket.objects[key].write(options)
end
def cached_upload(key, filename, options={})
options[:file] = filename
options.merge({expires: 5.years.from_now})
s3_bucket.objects[key].write(filename, options)
end
def delete_folder(folder)
s3_bucket.objects.with_prefix(folder).delete_all
end
def download(key, filename)
File.open(filename, "wb") do |f|
s3_bucket.objects[key].read do |data|
f.write(data)
end
end
end
def read_all(key)
s = StringIO.new
s3_bucket.objects[key].read do |data|
s.write(data)
end
s.string
end
def list_files(prefix)
tree = s3_bucket.as_tree(prefix: prefix)
tree.children.select(&:leaf?).collect(&:key)
end
def list_directories(prefix = nil)
tree = s3_bucket.as_tree(prefix: prefix)
tree.children.select(&:branch?).collect(&:prefix)
end
def exists?(filename)
s3_bucket.objects[filename].exists?
end
def object(filename)
s3_bucket.objects[filename]
end
def length(filename)
s3_bucket.objects[filename].content_length
end
private
def s3_bucket
@s3.buckets[@aws_bucket]
end
def content_type
"audio/ogg"
end
def http_date_time
Time.now.strftime("%a, %d %b %Y %H:%M:%S %z")
end
end
end