Class: RightAws::S3::Key

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bucket, name, data = nil, headers = {}, meta_headers = {}, last_modified = nil, e_tag = nil, size = nil, storage_class = nil, owner = nil) ⇒ Key

Create a new Key instance, but do not create the actual key. In normal use this method should not be called directly. Use RightAws::S3::Key.create or bucket.key() instead.



425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/s3/right_s3.rb', line 425

def initialize(bucket, name, data=nil, headers={}, meta_headers={}, 
               last_modified=nil, e_tag=nil, size=nil, storage_class=nil, owner=nil)
  raise 'Bucket must be a Bucket instance.' unless bucket.is_a?(Bucket)
  @bucket        = bucket
  @name          = name
  @data          = data
  @e_tag         = e_tag
  @size          = size.to_i
  @storage_class = storage_class
  @owner         = owner
  @last_modified = last_modified
  if @last_modified && !@last_modified.is_a?(Time) 
    @last_modified = Time.parse(@last_modified)
  end
  @headers, @meta_headers = self.class.split_meta(headers)
  @meta_headers.merge!(meta_headers)
end

Instance Attribute Details

#bucketObject (readonly)

Returns the value of attribute bucket.



378
379
380
# File 'lib/s3/right_s3.rb', line 378

def bucket
  @bucket
end

#dataObject

Return Key data. Retrieve this data from Amazon if it is the first time call. TODO TRB 6/19/07 What does the above mean? Clarify.



472
473
474
475
# File 'lib/s3/right_s3.rb', line 472

def data
  get if !@data and exists?
  @data
end

#e_tagObject (readonly)

Returns the value of attribute e_tag.



378
379
380
# File 'lib/s3/right_s3.rb', line 378

def e_tag
  @e_tag
end

#headersObject

Returns the value of attribute headers.



379
380
381
# File 'lib/s3/right_s3.rb', line 379

def headers
  @headers
end

#last_modifiedObject (readonly)

Returns the value of attribute last_modified.



378
379
380
# File 'lib/s3/right_s3.rb', line 378

def last_modified
  @last_modified
end

#meta_headersObject

Returns the value of attribute meta_headers.



379
380
381
# File 'lib/s3/right_s3.rb', line 379

def meta_headers
  @meta_headers
end

#nameObject (readonly)

Returns the value of attribute name.



378
379
380
# File 'lib/s3/right_s3.rb', line 378

def name
  @name
end

#ownerObject (readonly)

Returns the value of attribute owner.



378
379
380
# File 'lib/s3/right_s3.rb', line 378

def owner
  @owner
end

#sizeObject (readonly)

Returns the value of attribute size.



378
379
380
# File 'lib/s3/right_s3.rb', line 378

def size
  @size
end

#storage_classObject (readonly)

Returns the value of attribute storage_class.



378
379
380
# File 'lib/s3/right_s3.rb', line 378

def storage_class
  @storage_class
end

Class Method Details

.add_meta_prefix(meta_headers, prefix = S3Interface::AMAZON_METADATA_PREFIX) ⇒ Object



395
396
397
398
399
400
401
402
403
404
405
# File 'lib/s3/right_s3.rb', line 395

def self.add_meta_prefix(meta_headers, prefix=S3Interface::AMAZON_METADATA_PREFIX)
  meta = {}
  meta_headers.each do |meta_header, value|
    if meta_header[/#{prefix}/]
      meta[meta_header] = value
    else
      meta["#{S3Interface::AMAZON_METADATA_PREFIX}#{meta_header}"] = value
    end
  end
  meta
end

.create(bucket, name, data = nil, meta_headers = {}) ⇒ Object

Create a new Key instance, but do not create the actual key. The name is a String. Returns a new Key instance.

key = RightAws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
key.exists?                                                  #=> true | false
key.put('Woohoo!')                                           #=> true
key.exists?                                                  #=> true


417
418
419
# File 'lib/s3/right_s3.rb', line 417

def self.create(bucket, name, data=nil, meta_headers={})
  new(bucket, name, data, {}, meta_headers)
end

.split_meta(headers) ⇒ Object

Separate Amazon meta headers from other headers



383
384
385
386
387
388
389
390
391
392
393
# File 'lib/s3/right_s3.rb', line 383

def self.split_meta(headers) #:nodoc:
  hash = headers.dup
  meta = {}
  hash.each do |key, value|
    if key[/^#{S3Interface::AMAZON_METADATA_PREFIX}/]
      meta[key.gsub(S3Interface::AMAZON_METADATA_PREFIX,'')] = value
      hash.delete(key)
    end
  end
  [hash, meta]
end

Instance Method Details

#content_typeObject

Getter for the ‘content-type’ metadata



478
479
480
# File 'lib/s3/right_s3.rb', line 478

def content_type
  @headers['content-type'] if @headers
end

#copy(new_key_or_name) ⇒ Object

Create an object copy. Returns a destination RightAws::S3::Key instance.

# Key instance as destination
key1 = RightAws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
key2 = RightAws::S3::Key.create(bucket, 'logs/today/2.log') #=> #<RightAws::S3::Key:0xb7b5e240 ... >
key1.put('Olala!')   #=> true
key1.copy(key2)      #=> #<RightAws::S3::Key:0xb7b5e240 ... >
key1.exists?         #=> true
key2.exists?         #=> true
puts key2.data       #=> 'Olala!'

# String as destination
key = RightAws::S3::Key.create(bucket, 'logs/today/777.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
key.put('Olala!')                          #=> true
new_key = key.copy('logs/today/888.log')   #=> #<RightAws::S3::Key:0xb7b5e240 ... >
key.exists?                                #=> true
new_key.exists?                            #=> true


581
582
583
584
585
# File 'lib/s3/right_s3.rb', line 581

def copy(new_key_or_name)
  new_key_or_name = Key.create(@bucket, new_key_or_name.to_s) unless new_key_or_name.is_a?(Key)
  @bucket.s3.interface.copy(@bucket.name, @name, new_key_or_name.bucket.name, new_key_or_name.name)
  new_key_or_name
end

#decoded_meta_headers(key = nil) ⇒ Object

Helper to get and URI-decode a header metadata. Metadata have to be HTTP encoded (rfc2616) as we use the Amazon S3 REST api see docs.amazonwebservices.com/AmazonS3/latest/index.html?UsingMetadata.html



485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/s3/right_s3.rb', line 485

def decoded_meta_headers(key = nil)
  if key
    # Get one metadata value by its key
    URI.decode(@meta_headers[key.to_s])
  else
    # Get a hash of all metadata with a decoded value
    @decoded_meta_headers ||= begin
       = {}
      @meta_headers.each do |key, value|
        [key.to_sym] = URI.decode(value)
      end
      
    end
  end
end

#deleteObject

Remove key from bucket. Returns true.

key.delete #=> true


687
688
689
690
# File 'lib/s3/right_s3.rb', line 687

def delete
  raise 'Key name must be specified.' if @name.right_blank?
  @bucket.s3.interface.delete(@bucket, @name) 
end

#exists?Boolean

Check for existence of the key in the given bucket. Returns true or false.

key = RightAws::S3::Key.create(bucket,'logs/today/1.log')
key.exists?        #=> false
key.put('Woohoo!') #=> true
key.exists?        #=> true

Returns:

  • (Boolean)


678
679
680
# File 'lib/s3/right_s3.rb', line 678

def exists?
  @bucket.key(self).last_modified ? true : false
end

#full_name(separator = '/') ⇒ Object

Return the full S3 path to this key (bucket/key).

key.full_name #=> 'my_awesome_bucket/cool_key'


456
457
458
# File 'lib/s3/right_s3.rb', line 456

def full_name(separator='/')
  "#{@bucket.to_s}#{separator}#{@name}"
end

#get(headers = {}) ⇒ Object

Retrieve object data and attributes from Amazon. Returns a String.



504
505
506
507
508
509
510
# File 'lib/s3/right_s3.rb', line 504

def get(headers={})
  response = @bucket.s3.interface.get(@bucket.name, @name, headers)
  @data    = response[:object]
  @headers, @meta_headers = self.class.split_meta(response[:headers])
  refresh(false)
  @data
end

#granteesObject

Return a list of grantees.



694
695
696
# File 'lib/s3/right_s3.rb', line 694

def grantees
  Grantee::grantees(self)
end

#headObject

Updates headers and meta-headers from S3. Returns true.

key.meta_headers #=> {"family"=>"qwerty"}
key.head         #=> true
key.meta_headers #=> {"family"=>"qwerty", "name"=>"asdfg"}


645
646
647
648
# File 'lib/s3/right_s3.rb', line 645

def head
  @headers, @meta_headers = self.class.split_meta(@bucket.s3.interface.head(@bucket, @name))
  true
end

#move(new_key_or_name) ⇒ Object

Move an object to other location. Returns a destination RightAws::S3::Key instance.

# Key instance as destination
key1 = RightAws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
key2 = RightAws::S3::Key.create(bucket, 'logs/today/2.log') #=> #<RightAws::S3::Key:0xb7b5e240 ... >
key1.put('Olala!')   #=> true
key1.move(key2)      #=> #<RightAws::S3::Key:0xb7b5e240 ... >
key1.exists?         #=> false
key2.exists?         #=> true
puts key2.data       #=> 'Olala!'

# String as destination
key = RightAws::S3::Key.create(bucket, 'logs/today/777.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
key.put('Olala!')                          #=> true
new_key = key.move('logs/today/888.log')   #=> #<RightAws::S3::Key:0xb7b5e240 ... >
key.exists?                                #=> false
new_key.exists?                            #=> true


605
606
607
608
609
# File 'lib/s3/right_s3.rb', line 605

def move(new_key_or_name)
  new_key_or_name = Key.create(@bucket, new_key_or_name.to_s) unless new_key_or_name.is_a?(Key)
  @bucket.s3.interface.move(@bucket.name, @name, new_key_or_name.bucket.name, new_key_or_name.name)
  new_key_or_name
end

Return a public link to a key.

key.public_link #=> 'https://s3.amazonaws.com:443/my_awesome_bucket/cool_key'


464
465
466
467
# File 'lib/s3/right_s3.rb', line 464

def public_link
  params = @bucket.s3.interface.params
  "#{params[:protocol]}://#{params[:server]}:#{params[:port]}/#{full_name('/')}"
end

#put(data = nil, perms = nil, headers = {}, &blck) ⇒ Object

Store object data on S3. Parameter data is a String or S3Object instance. Returns true.

key = RightAws::S3::Key.create(bucket, 'logs/today/1.log')
key.data = 'Qwerty'
key.put             #=> true
 ...
key.put('Olala!')   #=> true


522
523
524
525
526
527
# File 'lib/s3/right_s3.rb', line 522

def put(data=nil, perms=nil, headers={}, &blck)
  headers['x-amz-acl'] = perms if perms
  @data = data || @data
  meta  = self.class.add_meta_prefix(@meta_headers)
  @bucket.s3.interface.put(@bucket.name, @name, @data, meta.merge(headers), &blck)
end

#put_multipart(data = nil, perms = nil, headers = {}, part_size = nil) ⇒ Object

Store object data on S3 using the Multipart Upload API. This is useful if you do not know the file size upfront (for example reading from pipe or socket) or if you are transmitting data over an unreliable network.

Parameter data is an object which responds to :read or an object which can be converted to a String prior to upload. Parameter part_size determines the size of each part sent (must be > 5MB per Amazon’s API requirements)

If data is a stream the caller is responsible for calling close() on the stream after this methods returns

Returns true.

upload_data = StringIO.new('My sample data')
key = RightAws::S3::Key.create(bucket, 'logs/today/1.log')
key.data = upload_data
key.put_multipart(:part_size => 5*1024*1024)             #=> true


544
545
546
547
548
549
# File 'lib/s3/right_s3.rb', line 544

def put_multipart(data=nil, perms=nil, headers={}, part_size=nil)
  headers['x-amz-acl'] = perms if perms
  @data = data || @data
  meta  = self.class.add_meta_prefix(@meta_headers)
  @bucket.s3.interface.store_object_multipart({:bucket => @bucket.name, :key => @name, :data => @data, :headers => meta.merge(headers), :part_size => part_size})
end

#refresh(head = true) ⇒ Object

Retrieve key info from bucket and update attributes. Refresh meta-headers (by calling head method) if head is set. Returns true if the key exists in bucket and false otherwise.

key = RightAws::S3::Key.create(bucket, 'logs/today/1.log')
key.e_tag        #=> nil
key.meta_headers #=> {}
key.refresh      #=> true
key.e_tag        #=> '12345678901234567890bf11094484b6'
key.meta_headers #=> {"family"=>"qwerty", "name"=>"asdfg"}


622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
# File 'lib/s3/right_s3.rb', line 622

def refresh(head=true)
  new_key        = @bucket.key(self)
  @last_modified = new_key.last_modified
  @e_tag         = new_key.e_tag
  @size          = new_key.size
  @storage_class = new_key.storage_class
  @owner         = new_key.owner
  if @last_modified
    self.head
    true
  else
    @headers = @meta_headers = {}
    false
  end
end

#reload_metaObject

Reload meta-headers only. Returns meta-headers hash.

key.reload_meta   #=> {"family"=>"qwerty", "name"=>"asdfg"}


654
655
656
# File 'lib/s3/right_s3.rb', line 654

def reload_meta
  @meta_headers = self.class.split_meta(@bucket.s3.interface.head(@bucket, @name)).last
end

#rename(new_name) ⇒ Object

Rename an object. Returns new object name.

key = RightAws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
key.rename('logs/today/2.log')   #=> 'logs/today/2.log'
puts key.name                    #=> 'logs/today/2.log'
key.exists?                      #=> true


558
559
560
561
# File 'lib/s3/right_s3.rb', line 558

def rename(new_name)
  @bucket.s3.interface.rename(@bucket.name, @name, new_name)
  @name = new_name
end

#save_meta(meta_headers) ⇒ Object

Replace meta-headers by new hash at S3. Returns new meta-headers hash.

key.reload_meta   #=> {"family"=>"qwerty", "name"=>"asdfg"}
key.save_meta     #=> {"family"=>"oops", "race" => "troll"}
key.reload_meta   #=> {"family"=>"oops", "race" => "troll"}


664
665
666
667
668
# File 'lib/s3/right_s3.rb', line 664

def save_meta(meta_headers)
  meta = self.class.add_meta_prefix(meta_headers)
  @bucket.s3.interface.copy(@bucket.name, @name, @bucket.name, @name, :replace, meta)
  @meta_headers = self.class.split_meta(meta)[1]
end

#to_sObject

Return key name as a String.

key = RightAws::S3::Key.create(bucket, 'logs/today/1.log') #=> #<RightAws::S3::Key:0xb7b1e240 ... >
puts key                                                   #=> 'logs/today/1.log'


448
449
450
# File 'lib/s3/right_s3.rb', line 448

def to_s
  @name.to_s
end