Class: Typingpool::Project::Remote::S3

Inherits:
Typingpool::Project::Remote show all
Defined in:
lib/typingpool/project/remote/s3.rb

Overview

Subclass for storing remote files on Amazon Simple Storage Service (S3)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Typingpool::Project::Remote

#file_to_url, #remove_urls, #url_basename

Constructor Details

#initialize(key, secret, bucket, url = nil) ⇒ S3

Constructor. Takes an Amazon AWS access key id, secret access key, bucket name, and optional URL prefix.



48
49
50
51
52
53
# 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

Instance Attribute Details

#urlObject (readonly)

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”).



44
45
46
# File 'lib/typingpool/project/remote/s3.rb', line 44

def url
  @url
end

Class Method Details

.from_config(config_amazon) ⇒ Object

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.



14
15
16
17
18
19
20
# 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

.random_bucket_name(length = 16, prefix = 'typingpool-') ⇒ Object

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.



28
29
30
31
32
33
34
35
36
37
# 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

Instance Method Details

#hostObject

The remote host (server) name, parsed from #url



56
57
58
# File 'lib/typingpool/project/remote/s3.rb', line 56

def host
  URI.parse(@url).host
end

#pathObject

The remote path (directory), pased from #url



61
62
63
# File 'lib/typingpool/project/remote/s3.rb', line 61

def path
  URI.parse(@url).path
end

#put(io_streams, as = io_streams.map{|file| File.basename(file)}) ⇒ Object

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.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 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

#remove(files) ⇒ Object

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



101
102
103
104
105
106
107
# 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