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;
|