Эта ветка довольно старая, но я недавно столкнулся с этой проблемой и хотел заявить о своих 2cents ...
Полное хлопот (кажется), чтобы аккуратно перечислить папки, заданные путем в корзине S3. Большинство современных оболочек гемов вокруг S3 API (официальный AWS-SDK, S3) неправильно анализируют возвращаемый объект (в частности CommonPrefixes), поэтому трудно получить список папок (кошмары с разделителями).
Вот быстрое решение для тех, кто использует драгоценный камень S3 ... Извините, это не один размер подходит всем, но это лучшее, что я хотел сделать.
https://github.com/qoobaa/s3/issues/61
Фрагмент кода:
module S3
class Bucket
# this method recurses if the response coming back
# from S3 includes a truncation flag (IsTruncated == 'true')
# then parses the combined response(s) XML body
# for CommonPrefixes/Prefix AKA directories
def directory_list(options = {}, responses = [])
options = {:delimiter => "/"}.merge(options)
response = bucket_request(:get, :params => options)
if is_truncated?(response.body)
directory_list(options.merge({:marker => next_marker(response.body)}), responses << response.body)
else
parse_xml_array(responses + [response.body], options)
end
end
private
def parse_xml_array(xml_array, options = {}, clean_path = true)
names = []
xml_array.each do |xml|
rexml_document(xml).elements.each("ListBucketResult/CommonPrefixes/Prefix") do |e|
if clean_path
names << e.text.gsub((options[:prefix] || ''), '').gsub((options[:delimiter] || ''), '')
else
names << e.text
end
end
end
names
end
def next_marker(xml)
marker = nil
rexml_document(xml).elements.each("ListBucketResult/NextMarker") {|e| marker ||= e.text }
if marker.nil?
raise StandardError
else
marker
end
end
def is_truncated?(xml)
is_truncated = nil
rexml_document(xml).elements.each("ListBucketResult/IsTruncated") {|e| is_truncated ||= e.text }
is_truncated == 'true'
end
end
end