Class: S4

Inherits:
Object
  • Object
show all
Defined in:
lib/s4.rb

Overview

Simpler AWS S3 library

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
"0.0.2"
SubResources =

sub-resource names which may appear in the query string and also must be signed against.

%w( acl location logging notification partNumber policy requestPayment torrent uploadId uploads versionId versioning versions website )
HeaderValues =

Header over-rides which may appear in the query string and also must be signed against.

%w( response-content-type response-content-language response-expires reponse-cache-control response-content-disposition response-content-encoding )

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(s3_url = ENV["S3_URL"]) ⇒ S4

Initialize a new S3 bucket connection.

Raises:

  • (ArgumentError)


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/s4.rb', line 54

def initialize(s3_url=ENV["S3_URL"])
  raise ArgumentError, "No S3 URL provided. You can set ENV['S3_URL'], too." if s3_url.nil? || s3_url.empty?

  begin
    url = URI(s3_url)
  rescue URI::InvalidURIError => e
    e.message << " The format is s3://access_key_id:[email protected]/bucket"
    raise e
  end

  @access_key_id = url.user
  @secret_access_key = URI.unescape(url.password || "")
  @host = url.host
  @bucket = url.path[1..-1]
end

Instance Attribute Details

#access_key_idObject (readonly)

Returns the value of attribute access_key_id.



18
19
20
# File 'lib/s4.rb', line 18

def access_key_id
  @access_key_id
end

#bucketObject (readonly)

Returns the value of attribute bucket.



18
19
20
# File 'lib/s4.rb', line 18

def bucket
  @bucket
end

#hostObject (readonly)

Returns the value of attribute host.



18
19
20
# File 'lib/s4.rb', line 18

def host
  @host
end

#secret_access_keyObject (readonly)

Returns the value of attribute secret_access_key.



18
19
20
# File 'lib/s4.rb', line 18

def secret_access_key
  @secret_access_key
end

Class Method Details

.connect(s3_url = ENV["S3_URL"]) ⇒ Object

Connect to an S3 bucket.

Pass your S3 connection parameters as URL, or read from ENV if none is passed.

S3_URL format is s3://<access key id>:<secret access key>@s3.amazonaws.com/<bucket>

i.e.

bucket = S4.connect #=> Connects to ENV["S3_URL"]
bucket = S4.connect("s3://0PN5J17HBGZHT7JJ3X82:[email protected]/bucket")


31
32
33
34
35
# File 'lib/s4.rb', line 31

def connect(s3_url=ENV["S3_URL"])
  new(s3_url).tap do |s4|
    s4.connect
  end
end

.create(s3_url = ENV["S3_URL"]) ⇒ Object

Create an S3 bucket.

See #connect for S3_URL parameters.

Will create the bucket on S3 and connect to it, or just connect if the bucket already exists and is owned by you.

i.e.

bucket = S4.create


46
47
48
49
50
# File 'lib/s4.rb', line 46

def create(s3_url=ENV["S3_URL"])
  new(s3_url).tap do |s4|
    s4.create
  end
end

Instance Method Details

#connectObject

Connect to the S3 bucket.

Since S3 doesn’t really require a persistent connection this really just makes sure that it can connect (i.e. the bucket exists and you own it).

Raises:

  • (NoSuchBucket)


74
75
76
# File 'lib/s4.rb', line 74

def connect
  raise NoSuchBucket.new(bucket) if request(uri("/", query: "location")).nil?
end

#createObject

Create the S3 bucket.



79
80
81
82
# File 'lib/s4.rb', line 79

def create
  uri = URI::HTTP.build(host: host, path: "/#{bucket}")
  request uri, Net::HTTP::Put.new(uri.request_uri)
end

#delete(name) ⇒ Object

Delete the object with the given name.



107
108
109
# File 'lib/s4.rb', line 107

def delete(name)
  request(uri = uri(name), Net::HTTP::Delete.new(uri.request_uri))
end

#download(name, destination = nil) ⇒ Object

Download the file with the given filename to the given destination.

i.e.

bucket.download("images/palm_trees.jpg", "./palm_trees.jpg")


96
97
98
99
100
101
102
103
104
# File 'lib/s4.rb', line 96

def download(name, destination=nil)
  get(name) do |response|
    File.open(destination || File.join(Dir.pwd, File.basename(name)), "wb") do |io|
      response.read_body do |chunk|
        io.write(chunk)
      end
    end
  end
end

#get(name, &block) ⇒ Object

Lower level object get which just yields the successful S3 response to the block. See #download if you want to simply copy a file from S3 to local.



86
87
88
89
90
# File 'lib/s4.rb', line 86

def get(name, &block)
  request(uri(name), &block)
rescue S4::Error => e
  raise e if e.status != "404"
end

#list(prefix = "") ⇒ Object

List bucket contents.

Optionally pass a prefix to list from (useful for paths).

i.e.

bucket.list("images/") #=> [ "birds.jpg", "bees.jpg" ]


140
141
142
# File 'lib/s4.rb', line 140

def list(prefix = "")
  REXML::Document.new(request(uri("", query: "prefix=#{prefix}"))).elements.collect("//Key", &:text)
end

#put(io, name) ⇒ Object



123
124
125
126
127
128
129
130
131
132
# File 'lib/s4.rb', line 123

def put(io, name)
  uri = uri(name)
  req = Net::HTTP::Put.new(uri.request_uri)

  req.body_stream = io
  req.add_field "Content-Length", io.size
  req.add_field "Content-Type", "application/x-www-form-urlencoded"

  request(URI::HTTP.build(host: host, path: "/#{bucket}/#{name}"), req)
end

#upload(name, destination = nil) ⇒ Object

Upload the file with the given filename to the given destination in your S3 bucket.

If no destination is given then uploads it with the same filename to the root of your bucket.

i.e.

bucket.upload("./images/1996_animated_explosion.gif", "website_background.gif")


119
120
121
# File 'lib/s4.rb', line 119

def upload(name, destination=nil)
  put File.open(name, "rb"), destination || File.basename(name)
end