diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | docs/customising/config.md | 16 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Photo.pm | 9 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Model/PhotoSet.pm | 20 | ||||
-rw-r--r-- | perllib/FixMyStreet/PhotoStorage/FileSystem.pm | 5 | ||||
-rw-r--r-- | t/app/controller/photo.t | 15 |
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"; }; |