aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/PhotoStorage/S3.pm
blob: 45325e9dcad5a551b1aa689e073e9813c0d3d4b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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;