2012-12-14 8 views
9

Quando faccio per un singolo file funziona:Come copiare un'intera "cartella" in un altro percorso usando S3 con sdk?

aws_s3 = AWS::S3.new(S3_CONFIG) 
    bucket = aws_s3.buckets[S3_CONFIG["bucket"]] 

    object = bucket.objects["user/1/photos/image_1.jpg"] 
    new_object = bucket.objects["users/1/photos/image_1.jpg"] 
    object.copy_to new_object, {:acl => :public_read} 

Ma voglio spostare l'intero "/ foto cartella" tiri No Such Key. Probabilmente le chiavi s3 sono solo il percorso completo per ogni file. Come farlo?

aws_s3 = AWS::S3.new(S3_CONFIG) 
    bucket = aws_s3.buckets[S3_CONFIG["bucket"]] 

    object = bucket.objects["user/1/photos"] 
    new_object = bucket.objects["users/1/photos"] 
    object.copy_to new_object, {:acl => :public_read} 

Grazie!

risposta

4

fatto:

bucket.objects.with_prefix("user/1/photos").each do |object| 
    ... 
end 
+7

È meglio fornire una spiegazione per la risposta anziché fornire semplicemente il codice. Ciò fornisce ulteriori informazioni nel caso in cui altri utenti abbiano un problema simile ma non identico. – Guvante

+0

la spiegazione è usare aws con_prefix ... – Luccas

+0

Ottenuto automaticamente contrassegnato come post di bassa qualità, non si è notato che si stava rispondendo alla propria domanda. Un modo è di fornire una citazione dell'uso with_prefix da un documento API o simile (con un collegamento). Ma se credi che il codice sia sufficiente per rispondere alla domanda, è la tua domanda in questo caso. – Guvante

0

avevo bisogno codice aggiuntivo per ottenere questo lavoro. Fondamentalmente recidere la base dal prefisso di origine, quindi aggiungere che al prefisso destinazione:

"cartella"
def copy_files_s3(bucket_name, source, destination) 
    source_bucket = @s3.buckets[bucket_name] 
    source_bucket.objects.with_prefix(source).each do |source_object| 
    new_file_name = source_object.key.dup 
    new_file_name.slice! source 
    new_object = source_bucket.objects["#{destination}#{new_file_name}"] 
    source_object.copy_to new_object, {acl: :public_read} 
    end 
end 
1

A non è un oggetto in S3, è per questo che non si può ottenere con il tasto, ma la cartella path è in realtà un prefisso per tutte le chiavi degli oggetti contenuti nella cartella.

Un'altra cosa importante, è necessario url codificare i tasti altrimenti si potrebbe finire con un errore di chiave sconosciuta.

require 'aws-sdk' 
require 'aws-sdk-s3' 
require 'securerandom' 
require 'uri' 
require "erb" 
include ERB::Util 

def copy_folder(folder, destination) 
    bucket_name = 'your_bucket' 
    credentials = Aws::Credentials.new('key', 'secret') 
    s3_client = Aws::S3::Client.new(region:'the_region', credentials: credentials) 
    enumerate_keys_with_prefix(source).each do |source_object| 
     source_key = url_encode(source_object.key) 
     destination_key = source_object.key.dup.sub(source, "") 
     s3_client.copy_object({bucket: bucket_name, copy_source: bucket_name+'/'+source_key, key: destination+'/'+destination_key, acl: "public-read"}) 
    end 
end 

def enumerate_keys_with_prefix(prefix) 
    bucket_name = 'your_bucket' 
    credentials = Aws::Credentials.new('key', 'secret') 
    s3 = Aws::S3::Resource.new(region:'the_region', credentials:credentials) 
    return s3.bucket(bucket_name).objects(prefix: prefix) 
end 
Problemi correlati