<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package FixMyStreet::PhotoStorage::S3;

use Moose;
use parent 'FixMyStreet::PhotoStorage';

use Net::Amazon::S3;
use Try::Tiny;


has client =&gt; (
    is =&gt; 'ro',
    lazy =&gt; 1,
    default =&gt; sub {
        my $key = FixMyStreet-&gt;config('PHOTO_STORAGE_OPTIONS')-&gt;{ACCESS_KEY};
        my $secret = FixMyStreet-&gt;config('PHOTO_STORAGE_OPTIONS')-&gt;{SECRET_KEY};

        my $s3 = Net::Amazon::S3-&gt;new(
            aws_access_key_id     =&gt; $key,
            aws_secret_access_key =&gt; $secret,
            retry                 =&gt; 1,
        );
        return Net::Amazon::S3::Client-&gt;new( s3 =&gt; $s3 );
    },
);

has bucket =&gt; (
    is =&gt; 'ro',
    lazy =&gt; 1,
    default =&gt; sub {
        shift-&gt;client-&gt;bucket( name =&gt; FixMyStreet-&gt;config('PHOTO_STORAGE_OPTIONS')-&gt;{BUCKET} );
    },
);

has region =&gt; (
    is =&gt; 'ro',
    lazy =&gt; 1,
    default =&gt; sub {
        return FixMyStreet-&gt;config('PHOTO_STORAGE_OPTIONS')-&gt;{REGION};
    },
);

has prefix =&gt; (
    is =&gt; 'ro',
    lazy =&gt; 1,
    default =&gt; sub {
        my $self = shift;
        my $prefix = FixMyStreet-&gt;config('PHOTO_STORAGE_OPTIONS')-&gt;{PREFIX};
        return "" unless $prefix;
        $prefix =~ s#/$##;
        return "$prefix/";
    },
);

sub init {
    my $self = shift;

    return 1 if $self-&gt;_bucket_exists();

    if ( FixMyStreet-&gt;config('PHOTO_STORAGE_OPTIONS')-&gt;{CREATE_BUCKET} ) {
        my $name = $self-&gt;bucket-&gt;name;
        try {
            $self-&gt;client-&gt;create_bucket(
                name =&gt; $name,
                location_constraint =&gt; $self-&gt;region,
            );
        } catch {
            warn "\x1b[31mCouldn't create S3 bucket '$name'\x1b[0m\n";
            return;
        };

        return 1 if $self-&gt;_bucket_exists();

        warn "\x1b[31mCouldn't create S3 bucket '$name'\x1b[0m\n";
        return;
    } else {
        my $bucket = $self-&gt;bucket-&gt;name;
        warn "\x1b[31mS3 bucket '$bucket' doesn't exist and CREATE_BUCKET is not set.\x1b[0m\n";
        return;
    }
}

sub _bucket_exists {
    my $self = shift;
    my $name = $self-&gt;bucket-&gt;name;
    my @buckets = $self-&gt;client-&gt;buckets;
    return grep { $_-&gt;name eq $name } @buckets;
}

sub get_object {
    my ($self, $key) = @_;
    return $self-&gt;bucket-&gt;object( key =&gt; $key );
}

sub store_photo {
    my ($self, $photo_blob) = @_;

    my $type = $self-&gt;detect_type($photo_blob) || 'jpeg';
    my $fileid = $self-&gt;get_fileid($photo_blob);
    my $key = $self-&gt;prefix . "$fileid.$type";

    my $object = $self-&gt;get_object($key);
    $object-&gt;put($photo_blob);

    return $key;
}


sub retrieve_photo {
    my ($self, $key) = @_;

    my $object = $self-&gt;get_object($key);
    if ($object-&gt;exists) {
        return ($object-&gt;get);
    }

}

1;
</pre></body></html>