diff options
author | Dave Arter <davea@mysociety.org> | 2018-09-20 16:15:38 +0100 |
---|---|---|
committer | Dave Arter <davea@mysociety.org> | 2018-09-28 16:19:47 +0100 |
commit | 07bc1188dc149e05b61e0d93ecf3ef1c26dc8690 (patch) | |
tree | 1ac3c9d0148b3f98ff29985e8c760740bb8d2548 /perllib | |
parent | 561e01b9b51b62e2566d80cd63d308f9a4f82822 (diff) |
Add S3 photo storage backend
Diffstat (limited to 'perllib')
-rw-r--r-- | perllib/FixMyStreet.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/PhotoStorage/S3.pm | 122 |
2 files changed, 124 insertions, 0 deletions
diff --git a/perllib/FixMyStreet.pm b/perllib/FixMyStreet.pm index c8d22fe50..d10ce93aa 100644 --- a/perllib/FixMyStreet.pm +++ b/perllib/FixMyStreet.pm @@ -113,12 +113,14 @@ sub override_config($&) { ); FixMyStreet::Map::reload_allowed_maps() if $config->{MAP_TYPE}; + $FixMyStreet::PhotoStorage::instance = undef if $config->{PHOTO_STORAGE_BACKEND}; $code->(); $override_guard->restore(); mySociety::MaPit::configure() if $config->{MAPIT_URL}; FixMyStreet::Map::reload_allowed_maps() if $config->{MAP_TYPE}; + $FixMyStreet::PhotoStorage::instance = undef if $config->{PHOTO_STORAGE_BACKEND}; } =head2 dbic_connect_info diff --git a/perllib/FixMyStreet/PhotoStorage/S3.pm b/perllib/FixMyStreet/PhotoStorage/S3.pm new file mode 100644 index 000000000..45325e9dc --- /dev/null +++ b/perllib/FixMyStreet/PhotoStorage/S3.pm @@ -0,0 +1,122 @@ +package FixMyStreet::PhotoStorage::S3; + +use Moose; +use parent 'FixMyStreet::PhotoStorage'; + +use Net::Amazon::S3; +use Try::Tiny; + + +has client => ( + is => 'ro', + lazy => 1, + default => sub { + my $key = FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{ACCESS_KEY}; + my $secret = FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{SECRET_KEY}; + + my $s3 = Net::Amazon::S3->new( + aws_access_key_id => $key, + aws_secret_access_key => $secret, + retry => 1, + ); + return Net::Amazon::S3::Client->new( s3 => $s3 ); + }, +); + +has bucket => ( + is => 'ro', + lazy => 1, + default => sub { + shift->client->bucket( name => FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{BUCKET} ); + }, +); + +has region => ( + is => 'ro', + lazy => 1, + default => sub { + return FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{REGION}; + }, +); + +has prefix => ( + is => 'ro', + lazy => 1, + default => sub { + my $self = shift; + my $prefix = FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{PREFIX}; + return "" unless $prefix; + $prefix =~ s#/$##; + return "$prefix/"; + }, +); + +sub init { + my $self = shift; + + return 1 if $self->_bucket_exists(); + + if ( FixMyStreet->config('PHOTO_STORAGE_OPTIONS')->{CREATE_BUCKET} ) { + my $name = $self->bucket->name; + try { + $self->client->create_bucket( + name => $name, + location_constraint => $self->region, + ); + } catch { + warn "\x1b[31mCouldn't create S3 bucket '$name'\x1b[0m\n"; + return; + }; + + return 1 if $self->_bucket_exists(); + + warn "\x1b[31mCouldn't create S3 bucket '$name'\x1b[0m\n"; + return; + } else { + my $bucket = $self->bucket->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->bucket->name; + my @buckets = $self->client->buckets; + return grep { $_->name eq $name } @buckets; +} + +sub get_object { + my ($self, $key) = @_; + return $self->bucket->object( key => $key ); +} + +sub store_photo { + my ($self, $photo_blob) = @_; + + my $type = $self->detect_type($photo_blob) || 'jpeg'; + my $fileid = $self->get_fileid($photo_blob); + my $key = $self->prefix . "$fileid.$type"; + + my $object = $self->get_object($key); + $object->put($photo_blob); + + return $key; +} + + +sub retrieve_photo { + my ($self, $key) = @_; + + my $object = $self->get_object($key); + if ($object->exists) { + my ($fileid, $type) = split /\./, $key; + return ($object->get, $type); + } + +} + +sub validate_key { $_[1] } + + +1; |