2012-02-14 6 views

Respuesta

6

Tiene razón, el SDK oficial le permite modificar los metadatos del objeto sin cargarlo nuevamente. Lo que hace es copy the object, pero está en el servidor, por lo que no necesita descargar el archivo y volver a subirlo.

Una envoltura sería fácil de implementar, algo así como

bucket.objects.each do |object| 
    object.metadata['content-type'] = 'application/json' 
end 
+0

Más discusión sobre esto aquí: http://groups.google.com/group/ruby-fog/browse_thread/thread/e632fc61405bf04c –

+2

esto agrega solo metadatos con x-amz-meta- prefix. ¿Hay alguna forma de agregar solo un metadato normal de tipo de contenido? – serengeti12

4

Para los futuros lectores, he aquí una muestra completa de cambiar las cosas mediante el rubí v1 AWS-SDK (ver también este Gist para un v2 AWS-SDK de la muestra):

# Using v1 of Ruby aws-sdk as currently v2 seems not able to do this (broken?). 
require 'aws-sdk-v1' 

key = YOUR_AWS_KEY 
secret = YOUR_AWS_SECRET 
region = YOUR_AWS_REGION 

AWS.config(access_key_id: key, secret_access_key: secret, region: region) 
s3 = AWS::S3.new 
bucket = s3.buckets[bucket_name] 
bucket.objects.with_prefix('images/').each do |obj| 
    puts obj.key 
    # Add metadata: {} to next line for more metadata. 
    obj.copy_from(obj.key, content_type: obj.content_type, cache_control: 'max-age=1576800000', acl: :public_read) 
end 
+0

Su Gist dice que la muestra v2 no parece funcionar, y sugiere que podría ser un error en el SDK ... ¿Supongo que aún no lo ha resuelto? – scottb

+0

No. Simplemente pruebe la esencia con la última versión de v2 :) – joost

+0

versión v2 no funciona para mí tampoco. He comentado la esencia de mi solución (volver a cargar cada archivo). –

5

En la versión 2 del API, puede utilizar Object#copy_from() o Object.copy_to() con los :metadata y :metadata_directive => 'REPLACE' opciones para actualizar los metadatos de un objeto sin necesidad de descargarlo desde S3.

El código en Joost's gist tiros este error:

Aws::S3::Errors::InvalidRequest: This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.

Esto es porque por defecto AWS ignora el :metadata suministrado con una operación de copia ya que copia los metadatos. Debemos establecer la opción :metadata_directive => 'REPLACE' si queremos actualizar los metadatos en contexto.

Ver http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#copy_from-instance_method

Aquí hay una, fragmento completo trabajando código que recientemente he utilizado para llevar a cabo las operaciones de actualización de metadatos:

require 'aws-sdk' 

# S3 setup boilerplate 
client = Aws::S3::Client.new(
    :region => 'us-east-1', 
    :access_key_id => ENV['AWS_ACCESS_KEY'], 
    :secret_access_key => ENV['AWS_SECRET_KEY'], 
) 
s3 = Aws::S3::Resource.new(:client => client) 

# Get an object reference 
object = s3.bucket('my-bucket-name').object('my-object/key') 

# Create our new metadata hash. This can be any hash; in this example we update 
# existing metadata with a new key-value pair. 
new_metadata = object.metadata.merge('MY_NEW_KEY' => 'MY_NEW_VALUE') 

# Use the copy operation to replace our metadata 
object.copy_to(object, 
    :metadata => new_metadata, 

    # IMPORTANT: normally S3 copies the metadata along with the object. 
    # we must supply this directive to replace the existing metadata with 
    # the values we supply 
    :metadata_directive => "REPLACE", 
) 

Para una fácil reutilización:

def update_metadata(s3_object, new_metadata = {}) 
    s3_object.copy_to(s3_object, 
    :metadata => new_metadata 
    :metadata_directive => "REPLACE" 
) 
end 
+0

Para agregar control de caché use: object.copy_to (object, cache_control: 'public, max-age = 333333', metadata_directive: 'REPLACE') –

1

buscándole esto parece funcionar para mí

obj.copy_to(obj, :metadata_directive=>"REPLACE", :acl=>"public-read",:content_type=>"text/plain") 
Cuestiones relacionadas