class Typingpool::Project::Remote::S3
Subclass for storing remote files on Amazon
Simple Storage Service (S3
)
Attributes
Returns the base URL, which is prepended to the remote files. This is either the 'url' attribute of the Config#amazon value passed to Project::Remote::S3.new
or, if that attribute is not set, the value returned by 'default_url' (e.g. “bucketname.s3.amazonaws.com”).
Public Class Methods
Takes a Config#amazon, extracts the needed params, and returns a Project::Remote::S3
instance. Raises an exception of type Error::File::Remote::S3
if any required params (key, secret, bucket) are missing from the config.
# File lib/typingpool/project/remote/s3.rb, line 14 def self.from_config(config_amazon) key = config_amazon.key or raise Error::File::Remote::S3, "Missing Amazon key in config" secret = config_amazon.secret or raise Error::File::Remote::S3, "Missing Amazon secret in config" bucket_name = config_amazon.bucket or raise Error::File::Remote::S3, "Missing Amazon bucket in config" url = config_amazon.url new(key, secret, bucket_name, url) end
Constructor. Takes an Amazon
AWS access key id, secret access key, bucket name, and optional URL prefix.
# File lib/typingpool/project/remote/s3.rb, line 48 def initialize(key, secret, bucket, url=nil) @key = key @secret = secret @bucket_name = bucket @url = url || default_url end
Takes an optional length for the random sequence, 16 by default, and an optional bucket name prefix, 'typingpool-' by default. Returns a string safe for use as both an S3
bucket and as a subdomain. Random charcters are drawn from [a-z0-9], though the first character in the returned string will always be a letter.
# File lib/typingpool/project/remote/s3.rb, line 28 def self.random_bucket_name(length=16, prefix='typingpool-') charset = [(0 .. 9).to_a, ('a' .. 'z').to_a].flatten if prefix.to_s.empty? && (length > 0) #ensure subdomain starts with a letter prefix = ('a' .. 'z').to_a[SecureRandom.random_number(26)] length -= 1 end random_sequence = (1 .. length).map{ charset[ SecureRandom.random_number(charset.count) ] } [prefix.to_s, random_sequence].join end
Public Instance Methods
The remote host (server) name, parsed from url
# File lib/typingpool/project/remote/s3.rb, line 56 def host URI.parse(@url).host end
The remote path (directory), pased from url
# File lib/typingpool/project/remote/s3.rb, line 61 def path URI.parse(@url).path end
Upload files/strings to S3
, optionally changing the names in the process.
==== Params
- io_streams
-
Enumerable collection of IO objects, like a File or StringIO instance. Each IO object must repond to the methods rewind, read, and eof? (so no pipes, sockets, etc)
- as
-
Optional if the io_streams are File instances. Array of file basenames, used to name the destination files. Default is the basename of the Files passed in as io_streams.
- &block
-
Optional. Passed an io_stream and destination name just before each upload
==== Returns
Array of URLs corresponding to the uploaded files.
# File lib/typingpool/project/remote/s3.rb, line 79 def put(io_streams, as=io_streams.map{|file| File.basename(file)}) batch(io_streams) do |stream, i| dest = as[i] yield(stream, dest) if block_given? begin s3.buckets[@bucket_name].objects[dest].write(stream, :acl => :public_read) rescue AWS::S3::Errors::NoSuchBucket s3.buckets.create(@bucket_name, :acl => :public_read) stream.rewind retry end #begin file_to_url(dest) end #batch end
Delete objects from S3
.
==== Params
- files
-
Enumerable collection of file names. Should NOT include the bucket name (path).
- &block
-
Optional. Passed a file name before each delete.
==== Returns
Nil
# File lib/typingpool/project/remote/s3.rb, line 101 def remove(files) batch(files) do |file, i| yield(file) if block_given? s3.buckets[@bucket_name].objects[file].delete end nil end
Protected Instance Methods
# File lib/typingpool/project/remote/s3.rb, line 111 def batch(io_streams) results = [] io_streams.each_with_index do |stream, i| begin results.push(yield(stream, i)) rescue AWS::S3::Errors::InvalidAccessKeyId raise Error::File::Remote::S3::Credentials, "S3 operation failed because your AWS access key ID is wrong. Double-check your config file." rescue AWS::S3::Errors::SignatureDoesNotMatch raise Error::File::Remote::S3::Credentials, "S3 operation failed with a signature error. This likely means your AWS secret access key is wrong." rescue AWS::Errors::Base => e raise Error::File::Remote::S3, "Your S3 operation failed with an Amazon error: #{e} (#{e.class})" end #begin end #io_streams.each_with_index results end
# File lib/typingpool/project/remote/s3.rb, line 134 def default_url "https://#{@bucket_name}.s3.amazonaws.com" end
# File lib/typingpool/project/remote/s3.rb, line 127 def s3 AWS::S3.new( :access_key_id => @key, :secret_access_key => @secret ) end