AWS-S3
view release on metacpan or search on metacpan
lib/AWS/S3/FileIterator.pm view on Meta::CPAN
# Advance to page X before proceding:
if ( ( !$s->{__fetched_first_page}++ ) && $s->page_number ) {
# Advance to $s->page_number
my $start_page = $s->page_number;
my $to_discard = $start_page * $s->page_size;
my $discarded = 0;
while ( 1 ) {
my $item = $s->_next
or last;
$discarded++ if $item->{key} =~ $s->pattern;
last if $discarded > $to_discard;
} # end while()
} # end if()
my @chunk = ();
while ( my $item = $s->_next() ) {
next unless $item->{key} =~ $s->pattern;
push @chunk, $item;
last if @chunk == $s->page_size;
} # end while()
my @out = map {
my $owner = AWS::S3::Owner->new( %{ $_->{owner} } );
delete $_->{owner};
AWS::S3::File->new( %$_, owner => $owner );
} @chunk;
$s->{page_number}++;
return unless @out;
wantarray ? @out : \@out;
} # end next_page()
sub _next {
my $s = shift;
if ( my $item = shift( @{ $s->{data} } ) ) {
return $item;
} else {
if ( my @chunk = $s->_fetch() ) {
push @{ $s->{data} }, @chunk;
return shift( @{ $s->{data} } );
} else {
return;
} # end if()
} # end if()
} # end _next()
sub _fetch {
my ( $s ) = @_;
my $path = $s->{bucket}->name . '/';
my %params = ();
$params{marker} = $s->{marker} if $s->{marker};
$params{prefix} = $s->{prefix} if $s->{prefix};
$params{max_keys} = 1000;
$params{delimiter} = $s->{delimiter} if $s->{delimiter};
my $type = 'ListBucket';
my $request = $s->{bucket}->s3->request( $type, %params, bucket => $s->{bucket}->name );
my $response = $request->request();
$s->{has_next} = ( $response->xpc->findvalue( '//s3:IsTruncated' ) || '' ) eq 'true' ? 1 : 0;
my @files = ();
foreach my $node ( $response->xpc->findnodes( '//s3:Contents' ) ) {
my ( $owner_node ) = $response->xpc->findnodes( './/s3:Owner', $node );
my $owner = {
id => $response->xpc->findvalue( './/s3:ID', $owner_node ),
display_name => $response->xpc->findvalue( './/s3:DisplayName', $owner_node )
};
my $etag = $response->xpc->findvalue( './/s3:ETag', $node );
push @files,
{
bucket => $s->{bucket},
key => $response->xpc->findvalue( './/s3:Key', $node ),
lastmodified => $response->xpc->findvalue( './/s3:LastModified', $node ),
etag => $response->xpc->findvalue( './/s3:ETag', $node ),
size => $response->xpc->findvalue( './/s3:Size', $node ),
owner => $owner,
};
} # end foreach()
if ( @files ) {
$s->{marker} = $files[-1]->{key};
} # end if()
return unless defined wantarray;
@files ? return @files : return;
} # end _fetch()
1;
__END__
=pod
=head1 NAME
AWS::S3::FileIterator - Easily access and iterate through your S3 files.
=head1 SYNOPSIS
# Iterate through all ".txt" files, 100 at a time:
my $iter = $bucket->files(
# Required params:
page_size => 100,
page_number => 1,
# Optional params:
pattern => qr(\.txt$),
prefix => 'notes',
);
while( my @files = $iter->next_page )
{
warn $iter->page_number, "\n";
foreach my $file ( @files )
{
print "\t", $file->key, "\n";
}# end foreach()
( run in 1.853 second using v1.01-cache-2.11-cpan-ecdf5575e8d )