aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--docs/customising/config.md16
-rw-r--r--perllib/FixMyStreet/App/Controller/Photo.pm9
-rw-r--r--perllib/FixMyStreet/App/Model/PhotoSet.pm20
-rw-r--r--perllib/FixMyStreet/PhotoStorage/FileSystem.pm5
-rw-r--r--t/app/controller/photo.t15
6 files changed, 54 insertions, 13 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9443c7afa..8f5195ee2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,8 @@
- Add Mark/View private reports permission #2306
- Open311 improvements:
- Fix bug in contact group handling. #2323
+ - Development improvements:
+ - Add option to symlink full size photos.
* v2.4.2 (6th November 2018)
- New features:
diff --git a/docs/customising/config.md b/docs/customising/config.md
index e0761cb8e..f9b2fc213 100644
--- a/docs/customising/config.md
+++ b/docs/customising/config.md
@@ -64,6 +64,7 @@ The following are all the configuration settings that you can change in `conf/ge
* <code><a href="#photo_storage_options">PHOTO_STORAGE_OPTIONS</a></code>
* For local filesystem storage:
* <code><a href="#upload_dir">UPLOAD_DIR</a></code>
+ * <code><a href="#symlink_full_size">SYMLINK_FULL_SIZE</a></code>
* For Amazon S3 storage:
* <code><a href="#bucket">BUCKET</a></code>
* <code><a href="#access_key">ACCESS_KEY</a></code>
@@ -1158,6 +1159,7 @@ ALLOWED_COBRANDS:
</p>
<ul>
<li><code><a href="#upload_dir">UPLOAD_DIR</a></code></li>
+ <li><code><a href="#symlink_full_size">SYMLINK_FULL_SIZE</a></code></li>
</ul>
<p>
For the <code>S3</code> backend, the following apply:
@@ -1197,6 +1199,20 @@ PHOTO_STORAGE_OPTIONS:
</dd>
<dt>
+ <a name="upload_dir"><code>SYMLINK_FULL_SIZE</code></a>
+ </dt>
+ <dd>
+ <p>
+ Defaults to false; if this is true, then requests for full size images
+ will be symlinked from the photo cache, not copied there. You can use this
+ if static files are being served by your web server.
+ </p>
+ <p>
+ Only applies when <code>PHOTO_STORAGE_BACKEND</code> is <code>FileSystem</code>.
+ </p>
+ </dd>
+
+ <dt>
<a name="bucket"><code>BUCKET</code></a>
</dt>
<dd>
diff --git a/perllib/FixMyStreet/App/Controller/Photo.pm b/perllib/FixMyStreet/App/Controller/Photo.pm
index 4ae25db24..5712350ed 100644
--- a/perllib/FixMyStreet/App/Controller/Photo.pm
+++ b/perllib/FixMyStreet/App/Controller/Photo.pm
@@ -5,8 +5,7 @@ use namespace::autoclean;
BEGIN {extends 'Catalyst::Controller'; }
use JSON::MaybeXS;
-use File::Path;
-use File::Slurp;
+use Path::Tiny;
use Try::Tiny;
use FixMyStreet::App::Model::PhotoSet;
@@ -81,8 +80,10 @@ sub output : Private {
my ( $self, $c, $photo ) = @_;
# Save to file
- File::Path::make_path( FixMyStreet->path_to( 'web', 'photo', 'c' )->stringify );
- File::Slurp::write_file( FixMyStreet->path_to( 'web', $c->req->path )->stringify, \$photo->{data} );
+ path(FixMyStreet->path_to('web', 'photo', 'c'))->mkpath;
+ my $out = FixMyStreet->path_to('web', $c->req->path);
+ my $symlink_exists = symlink($photo->{symlink}, $out) if $photo->{symlink};
+ path($out)->spew_raw($photo->{data}) unless $symlink_exists;
$c->res->content_type( $photo->{content_type} );
$c->res->body( $photo->{data} );
diff --git a/perllib/FixMyStreet/App/Model/PhotoSet.pm b/perllib/FixMyStreet/App/Model/PhotoSet.pm
index 21bde52d8..f209a2aed 100644
--- a/perllib/FixMyStreet/App/Model/PhotoSet.pm
+++ b/perllib/FixMyStreet/App/Model/PhotoSet.pm
@@ -16,8 +16,10 @@ use IPC::Cmd qw(can_run);
use IPC::Open3;
use MIME::Base64;
+use FixMyStreet;
use FixMyStreet::PhotoStorage;
+# Attached Catalyst app, if present, for feeding back errors during photo upload
has c => (
is => 'ro',
);
@@ -71,6 +73,15 @@ has storage => (
}
);
+has symlinkable => (
+ is => 'ro',
+ lazy => 1,
+ default => sub {
+ my $cfg = FixMyStreet->config('PHOTO_STORAGE_OPTIONS');
+ return $cfg ? $cfg->{SYMLINK_FULL_SIZE} : 0;
+ }
+);
+
=head2 C<ids>, C<num_images>, C<get_id>, C<all_ids>
C<$photoset-E<GT>ids> is an arrayref containing the fileid data.
@@ -184,9 +195,10 @@ has ids => ( # Arrayref of $fileid tuples (always, so post upload/raw data proc
sub get_raw_image {
my ($self, $index) = @_;
my $filename = $self->get_id($index);
- my ($photo, $type) = $self->storage->retrieve_photo($filename);
+ my ($photo, $type, $object) = $self->storage->retrieve_photo($filename);
if ($photo) {
return {
+ $object ? (object => $object) : (),
data => $photo,
content_type => "image/$type",
extension => $type,
@@ -203,6 +215,12 @@ sub get_image_data {
my $photo = $image->{data};
my $size = $args{size};
+
+ if ($self->symlinkable && $image->{object} && $size eq 'full') {
+ $image->{symlink} = delete $image->{object};
+ return $image;
+ }
+
if ( $size eq 'tn' ) {
$photo = _shrink( $photo, 'x100' );
} elsif ( $size eq 'fp' ) {
diff --git a/perllib/FixMyStreet/PhotoStorage/FileSystem.pm b/perllib/FixMyStreet/PhotoStorage/FileSystem.pm
index 772286d53..1d3fe5cfd 100644
--- a/perllib/FixMyStreet/PhotoStorage/FileSystem.pm
+++ b/perllib/FixMyStreet/PhotoStorage/FileSystem.pm
@@ -70,7 +70,8 @@ sub store_photo {
=head2 retrieve_photo
Fetches the file content of a particular photo from storage.
-Returns the binary blob and the filetype, if the photo exists in storage.
+Returns the binary blob, the filetype, and the file path, if
+the photo exists in storage.
=cut
@@ -81,7 +82,7 @@ sub retrieve_photo {
my $file = $self->get_file($fileid, $type);
if ($file->exists) {
my $photo = $file->slurp_raw;
- return ($photo, $type);
+ return ($photo, $type, $file);
}
}
diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t
index 19249611a..842daa0dc 100644
--- a/t/app/controller/photo.t
+++ b/t/app/controller/photo.t
@@ -98,12 +98,15 @@ subtest "Check photo uploading URL and endpoints work" => sub {
my $p = FixMyStreet::DB->resultset("Problem")->first;
- $mech->get_ok('/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg');
- $image_file = FixMyStreet->path_to('web/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg');
- ok -e $image_file, 'File uploaded to temp';
- $mech->get_ok('/photo/' . $p->id . '.jpeg');
- $image_file = FixMyStreet->path_to('web/photo/' . $p->id . '.jpeg');
- ok -e $image_file, 'File uploaded to temp';
+ foreach my $i (
+ '/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg',
+ '/photo/fulltemp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg',
+ '/photo/' . $p->id . '.jpeg',
+ '/photo/' . $p->id . '.full.jpeg') {
+ $mech->get_ok($i);
+ $image_file = FixMyStreet->path_to("web$i");
+ ok -e $image_file, 'File uploaded to temp';
+ }
my $res = $mech->get('/photo/0.jpeg');
is $res->code, 404, "got 404";
};