diff options
author | Matthew Somerville <matthew@mysociety.org> | 2016-04-20 15:32:00 +0100 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2016-04-20 15:32:00 +0100 |
commit | 193697bde57ef2cfd0a46bb5a85fa98727378297 (patch) | |
tree | e8dd78b7202b78e3483ac65924e054a23127a594 /perllib/FixMyStreet/App | |
parent | f35b7eba0db02d16fa0aad5a78ee479165217e20 (diff) | |
parent | b7099e8e513fe64ec183b1403515f46a7cc25f19 (diff) |
Merge remote-tracking branch 'origin/1302-support-pngs'
Diffstat (limited to 'perllib/FixMyStreet/App')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Open311.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Photo.pm | 14 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Rss.pm | 9 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Model/PhotoSet.pm | 79 |
4 files changed, 63 insertions, 41 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Open311.pm b/perllib/FixMyStreet/App/Controller/Open311.pm index f35dc64a5..4f1727b1a 100644 --- a/perllib/FixMyStreet/App/Controller/Open311.pm +++ b/perllib/FixMyStreet/App/Controller/Open311.pm @@ -284,7 +284,7 @@ sub output_requests : Private { my $display_photos = $c->cobrand->allow_photo_display($problem); if ($display_photos && $problem->photo) { my $url = $c->cobrand->base_url(); - my $imgurl = $url . "/photo/$id.full.jpeg"; + my $imgurl = $url . $problem->photos->[0]->{url_full}; $request->{'media_url'} = [ $imgurl ]; } push(@problemlist, $request); diff --git a/perllib/FixMyStreet/App/Controller/Photo.pm b/perllib/FixMyStreet/App/Controller/Photo.pm index bfb1c5535..59f54bad7 100644 --- a/perllib/FixMyStreet/App/Controller/Photo.pm +++ b/perllib/FixMyStreet/App/Controller/Photo.pm @@ -29,12 +29,12 @@ Display a photo =cut -sub during :LocalRegex('^([0-9a-f]{40})\.(temp|fulltemp)\.jpeg$') { +sub during :LocalRegex('^(temp|fulltemp)\.([0-9a-f]{40}\.(?:jpeg|png|gif|tiff))$') { my ( $self, $c ) = @_; - my ( $hash, $size ) = @{ $c->req->captures }; + my ( $size, $filename ) = @{ $c->req->captures }; my $photoset = FixMyStreet::App::Model::PhotoSet->new({ - data_items => [ $hash ] + data_items => [ $filename ] }); $size = $size eq 'temp' ? 'default' : 'full'; @@ -43,7 +43,7 @@ sub during :LocalRegex('^([0-9a-f]{40})\.(temp|fulltemp)\.jpeg$') { $c->forward( 'output', [ $photo ] ); } -sub index :LocalRegex('^(c/)?(\d+)(?:\.(\d+))?(?:\.(full|tn|fp))?\.jpeg$') { +sub index :LocalRegex('^(c/)?(\d+)(?:\.(\d+))?(?:\.(full|tn|fp))?\.(?:jpeg|png|gif|tiff)$') { my ( $self, $c ) = @_; my ( $is_update, $id, $photo_number, $size ) = @{ $c->req->captures }; @@ -79,10 +79,10 @@ sub output : Private { # 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 ); + File::Slurp::write_file( FixMyStreet->path_to( 'web', $c->req->path )->stringify, \$photo->{data} ); - $c->res->content_type( 'image/jpeg' ); - $c->res->body( $photo ); + $c->res->content_type( $photo->{content_type} ); + $c->res->body( $photo->{data} ); } sub no_photo : Private { diff --git a/perllib/FixMyStreet/App/Controller/Rss.pm b/perllib/FixMyStreet/App/Controller/Rss.pm index 6047f063b..d708aa71c 100755 --- a/perllib/FixMyStreet/App/Controller/Rss.pm +++ b/perllib/FixMyStreet/App/Controller/Rss.pm @@ -6,6 +6,8 @@ use POSIX qw(strftime); use URI::Escape; use XML::RSS; +use FixMyStreet::App::Model::PhotoSet; + use mySociety::Gaze; use mySociety::Locale; use mySociety::MaPit; @@ -277,8 +279,13 @@ sub add_row : Private { $item{category} = ent($row->{category}) if $row->{category}; if ($c->cobrand->allow_photo_display($row) && $row->{photo}) { + # Bit yucky as we don't have full objects here + my $photoset = FixMyStreet::App::Model::PhotoSet->new({ db_data => $row->{photo} }); + my $first_fn = $photoset->get_id(0); + my ($hash, $format) = split /\./, $first_fn; + my $cachebust = substr($hash, 0, 8); my $key = $alert_type->item_table eq 'comment' ? 'c/' : ''; - $item{description} .= ent("\n<br><img src=\"". $base_url . "/photo/$key$row->{id}.jpeg\">"); + $item{description} .= ent("\n<br><img src=\"". $base_url . "/photo/$key$row->{id}.0.$format?$cachebust\">"); } if ( $row->{used_map} ) { diff --git a/perllib/FixMyStreet/App/Model/PhotoSet.pm b/perllib/FixMyStreet/App/Model/PhotoSet.pm index 54457bae9..41d02d2a7 100644 --- a/perllib/FixMyStreet/App/Model/PhotoSet.pm +++ b/perllib/FixMyStreet/App/Model/PhotoSet.pm @@ -49,7 +49,7 @@ has data_items => ( # either a) split from db_data or b) provided by photo uploa my $self = shift; my $data = $self->db_data or return []; - return [$data] if (_jpeg_magic($data)); + return [$data] if (detect_type($data)); return [ split ',' => $data ]; }, @@ -70,10 +70,12 @@ has upload_dir => ( }, ); -sub _jpeg_magic { - $_[0] =~ /^\x{ff}\x{d8}/; # JPEG - # NB: should we also handle \x{89}\x{50} (PNG, 15 results in live DB) ? - # and \x{49}\x{49} (Tiff, 3 results in live DB) ? +sub detect_type { + return 'jpeg' if $_[0] =~ /^\x{ff}\x{d8}/; + return 'png' if $_[0] =~ /^\x{89}\x{50}/; + return 'tiff' if $_[0] =~ /^II/; + return 'gif' if $_[0] =~ /^GIF/; + return ''; } =head2 C<ids>, C<num_images>, C<get_id>, C<all_ids> @@ -106,15 +108,17 @@ has ids => ( # Arrayref of $fileid tuples (always, so post upload/raw data proc my $part = $_; if (blessed $part and $part->isa('Catalyst::Request::Upload')) { - # check that the photo is a jpeg my $upload = $part; my $ct = $upload->type; $ct =~ s/x-citrix-//; # Thanks, Citrix + my ($type) = $ct =~ m{image/(jpeg|pjpeg|gif|tiff|png)}; + $type = 'jpeg' if $type && $type eq 'pjpeg'; # Had a report of a JPEG from an Android 2.1 coming through as a byte stream - unless ( $ct eq 'image/jpeg' || $ct eq 'image/pjpeg' || $ct eq 'application/octet-stream' ) { + $type = 'jpeg' if !$type && $ct eq 'application/octet-stream'; + unless ( $type ) { my $c = $self->c; $c->log->info('Bad photo tried to upload, type=' . $ct); - $c->stash->{photo_error} = _('Please upload a JPEG image only'); + $c->stash->{photo_error} = _('Please upload an image only'); return (); } @@ -139,12 +143,13 @@ has ids => ( # Arrayref of $fileid tuples (always, so post upload/raw data proc # get the photo into a variable my $photo_blob = eval { my $filename = $upload->tempname; - my $out = `jhead -se -autorot $filename 2>&1`; + my $out; + $out = `jhead -se -autorot $filename 2>&1` if $type eq 'jpeg'; unless (defined $out) { my ($w, $h, $err) = Image::Size::imgsize($filename); - die _("Please upload a JPEG image only") . "\n" if !defined $w || $err ne 'JPG'; + die _("Please upload an image only") . "\n" if !defined $w || $err !~ /JPG|GIF|PNG|TIF/; } - die _("Please upload a JPEG image only") . "\n" if $out && $out =~ /Not JPEG:/; + die _("Please upload an image only") . "\n" if $out && $out =~ /Not JPEG:/; my $photo = $upload->slurp; }; if ( my $error = $@ ) { @@ -157,29 +162,30 @@ has ids => ( # Arrayref of $fileid tuples (always, so post upload/raw data proc # we have an image we can use - save it to the upload dir for storage my $fileid = $self->get_fileid($photo_blob); - my $file = $self->get_file($fileid); + my $file = $self->get_file($fileid, $type); $upload->copy_to( $file ); - return $fileid; + return $file->basename; } - if (_jpeg_magic($part)) { + if (my $type = detect_type($part)) { my $photo_blob = $part; my $fileid = $self->get_fileid($photo_blob); - my $file = $self->get_file($fileid); + my $file = $self->get_file($fileid, $type); $file->spew_raw($photo_blob); - return $fileid; + return $file->basename; } - if (length($part) == 40) { - my $fileid = $part; - my $file = $self->get_file($fileid); + my ($fileid, $type) = split /\./, $part; + $type ||= 'jpeg'; + if (length($fileid) == 40) { + my $file = $self->get_file($fileid, $type); if ($file->exists) { - $fileid; + $file->basename; } else { - warn "File $fileid doesn't exist"; + warn "File $part doesn't exist"; (); } } else { - warn sprintf "Received bad photo hash of length %d", length($part); + warn sprintf "Received bad photo hash of length %d", length($fileid); (); } }); @@ -193,18 +199,23 @@ sub get_fileid { } sub get_file { - my ($self, $fileid) = @_; + my ($self, $fileid, $type) = @_; my $cache_dir = $self->upload_dir; - return path( $cache_dir, "$fileid.jpeg" ); + return path( $cache_dir, "$fileid.$type" ); } -sub get_raw_image_data { +sub get_raw_image { my ($self, $index) = @_; - my $fileid = $self->get_id($index); - my $file = $self->get_file($fileid); + my $filename = $self->get_id($index); + my ($fileid, $type) = split /\./, $filename; + my $file = $self->get_file($fileid, $type); if ($file->exists) { my $photo = $file->slurp_raw; - return $photo; + return { + data => $photo, + content_type => "image/$type", + extension => $type, + }; } } @@ -212,8 +223,9 @@ sub get_image_data { my ($self, %args) = @_; my $num = $args{num} || 0; - my $photo = $self->get_raw_image_data( $num ) + my $image = $self->get_raw_image( $num ) or return; + my $photo = $image->{data}; my $size = $args{size}; if ( $size eq 'tn' ) { @@ -226,7 +238,10 @@ sub get_image_data { $photo = _shrink( $photo, $args{default} || '250x250' ); } - return $photo; + return { + data => $photo, + content_type => $image->{content_type}, + }; } sub delete_cached { @@ -266,8 +281,8 @@ sub rotate_image { my @images = $self->all_ids; return if $index > $#images; - my $image_data = $self->get_raw_image_data($index); - $images[$index] = _rotate_image( $image_data, $direction ); + my $image = $self->get_raw_image($index); + $images[$index] = _rotate_image( $image->{data}, $direction ); my $new_set = (ref $self)->new({ data_items => \@images, |