diff options
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 41 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Reports.pm | 11 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Rss.pm | 10 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Default.pm | 67 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Reading.pm | 29 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Southampton.pm | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Problem.pm | 27 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/ResultSet/AlertType.pm | 43 | ||||
-rw-r--r-- | perllib/FixMyStreet/Map/FMS.pm | 10 |
10 files changed, 215 insertions, 31 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index a34737844..c988b23c1 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -572,6 +572,9 @@ sub report_edit : Path('report_edit') : Args(1) { elsif ( $c->req->param('banuser') ) { $c->forward('ban_user'); } + elsif ( $c->req->param('rotate_photo') ) { + $c->forward('rotate_photo'); + } elsif ( $c->req->param('submit') ) { $c->forward('check_token'); @@ -1161,6 +1164,31 @@ sub check_email_for_abuse : Private { return 1; } +=head2 rotate_photo + +Rotate a photo 90 degrees left or right + +=cut + +sub rotate_photo : Private { + my ( $self, $c ) =@_; + + my $direction = $c->req->param('rotate_photo'); + + return unless $direction =~ /Left/ or $direction =~ /Right/; + + my $photo = _rotate_image( $c->stash->{problem}->photo, $direction =~ /Left/ ? -90 : 90 ); + + if ( $photo ) { + $c->stash->{rotated} = 1; + $c->stash->{problem}->photo( $photo ); + $c->stash->{problem}->update(); + } + + return 1; +} + + =head2 check_page_allowed Checks if the current catalyst action is in the list of allowed pages and @@ -1207,6 +1235,19 @@ sub trim { return $e; } +sub _rotate_image { + my ($photo, $direction) = @_; + use Image::Magick; + my $image = Image::Magick->new; + $image->BlobToImage($photo); + my $err = $image->Rotate($direction); + return 0 if $err; + my @blobs = $image->ImageToBlob(); + undef $image; + return $blobs[0]; +} + + =head1 AUTHOR Struan Donald diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index c6ede88f7..e982d6a4c 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -911,6 +911,13 @@ sub check_for_errors : Private { %{ $c->stash->{report}->check_for_errors }, ); + # if they're got the login details wrong when signing in then + # we don't care about the name field even though it's validated + # by the user object + if ( $c->req->param('submit_sign_in') and $field_errors{password} ) { + delete $field_errors{name}; + } + # add the photo error if there is one. if ( my $photo_error = delete $c->stash->{photo_error} ) { $field_errors{photo} = $photo_error; diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index 0a4ae4609..0587a627a 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -110,6 +110,8 @@ sub ward : Path : Args(2) { $c->stash->{council_url} = '/reports/' . $council_short; + $c->stash->{stats} = $c->cobrand->get_report_stats(); + my $pins = $c->stash->{pins}; $c->stash->{page} = 'reports'; # So the map knows to make clickable pins @@ -349,17 +351,12 @@ sub load_and_group_problems : Private { $c->stash->{pager} = $problems->pager; $problems = $problems->cursor; # Raw DB cursor for speed - my ( %fixed, %open, @pins, $total, $cobrand_total ); + my ( %fixed, %open, @pins ); my $re_councils = join('|', keys %{$c->stash->{areas_info}}); my @cols = ( 'id', 'council', 'state', 'areas', 'latitude', 'longitude', 'title', 'cobrand', 'duration', 'age' ); while ( my @problem = $problems->next ) { my %problem = zip @cols, @problem; $c->log->debug( $problem{'cobrand'} . ', cobrand is ' . $c->cobrand->moniker ); - if ( $problem{'cobrand'} && $problem{'cobrand'} eq $c->cobrand->moniker ) { - $cobrand_total++; - } else { - $total++; - } if ( !$problem{council} ) { # Problem was not sent to any council, add to possible councils $problem{councils} = 0; @@ -382,8 +379,6 @@ sub load_and_group_problems : Private { fixed => \%fixed, open => \%open, pins => \@pins, - cobrand_count => $cobrand_total || 0, - total_count => $total || 0, ); return 1; diff --git a/perllib/FixMyStreet/App/Controller/Rss.pm b/perllib/FixMyStreet/App/Controller/Rss.pm index 7fddbed97..822780b81 100755 --- a/perllib/FixMyStreet/App/Controller/Rss.pm +++ b/perllib/FixMyStreet/App/Controller/Rss.pm @@ -251,6 +251,12 @@ sub add_row : Private { (my $link = $alert_type->item_link) =~ s/{{(.*?)}}/$row->{$1}/g; (my $desc = _($alert_type->item_description)) =~ s/{{(.*?)}}/$row->{$1}/g; my $url = $c->uri_for( $link ); + + if ( $row->{postcode} ) { + my $pc = $c->cobrand->format_postcode( $row->{postcode} ); + $title .= ", $pc"; + } + my %item = ( title => ent($title), link => $url, @@ -266,8 +272,8 @@ sub add_row : Private { } if ( $row->{used_map} ) { - #my $address = $c->cobrand->find_closest_address_for_rss( $row->{latitude}, $row->{longitude} ); - #$item{description} .= ent("\n<br>$address"); + my $address = $c->cobrand->find_closest_address_for_rss( $row->{latitude}, $row->{longitude}, $row ); + $item{description} .= ent("\n<br>$address") if $address; } my $recipient_name = $c->cobrand->contact_name; diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 1e87468ac..b5a1cd8d3 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -545,10 +545,15 @@ Used by send-reports to attach nearest things to the bottom of the report =cut sub find_closest { - my ( $self, $latitude, $longitude ) = @_; + my ( $self, $latitude, $longitude, $problem ) = @_; my $str = ''; if ( my $j = FixMyStreet::Geocode::Bing::reverse( $latitude, $longitude ) ) { + # cache the bing results for use in alerts + if ( $problem ) { + $problem->geocode( $j ); + $problem->update; + } if ($j->{resourceSets}[0]{resources}[0]{name}) { $str .= sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s"), $j->{resourceSets}[0]{resources}[0]{name}) . "\n\n"; @@ -576,23 +581,55 @@ Used by rss feeds to provide a bit more context =cut sub find_closest_address_for_rss { - my ( $self, $latitude, $longitude ) = @_; + my ( $self, $latitude, $longitude, $problem ) = @_; my $str = ''; - if ( my $j = FixMyStreet::Geocode::Bing::reverse( $latitude, $longitude, 1 ) ) { - if ($j->{resourceSets}[0]{resources}[0]{name}) { - my $address = $j->{resourceSets}[0]{resources}[0]{address}; - my @address; - push @address, $address->{addressLine} if $address->{addressLine} ne 'Street'; - push @address, $address->{locality}; - $str .= sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s"), - join( ', ', @address ) ); - } + my $j; + if ( $problem && ref($problem) =~ /FixMyStreet/ && $problem->can( 'geocode' ) ) { + $j = $problem->geocode; + } else { + $problem = FixMyStreet::App->model('DB::Problem')->find( { id => $problem->{id} } ); + $j = $problem->geocode; + } + + # if we've not cached it then we don't want to look it up in order to avoid + # hammering the bing api + # if ( !$j ) { + # $j = FixMyStreet::Geocode::Bing::reverse( $latitude, $longitude, 1 ); + + # $problem->geocode( $j ); + # $problem->update; + # } + + if ($j && $j->{resourceSets}[0]{resources}[0]{name}) { + my $address = $j->{resourceSets}[0]{resources}[0]{address}; + my @address; + push @address, $address->{addressLine} if $address->{addressLine} and $address->{addressLine} !~ /^Street$/i; + push @address, $address->{locality} if $address->{locality}; + $str .= sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s"), + join( ', ', @address ) ) if @address; } return $str; } +=head2 format_postcode + +Takes a postcode string and if it looks like a valid postcode then transforms it +into the canonical postcode. + +=cut + +sub format_postcode { + my ( $self, $postcode ) = @_; + + if ( $postcode ) { + $postcode = mySociety::PostcodeUtil::canonicalise_postcode($postcode) + if $postcode && mySociety::PostcodeUtil::is_valid_postcode($postcode); + } + + return $postcode; +} =head2 council_check Paramters are COUNCILS, QUERY, CONTEXT. Return a boolean indicating whether @@ -960,5 +997,13 @@ to be resized then return 0; sub default_photo_resize { return 0; } +=head2 get_report_stats + +Get stats to display on the council reports page + +=cut + +sub get_report_stats { return 0; } + 1; diff --git a/perllib/FixMyStreet/Cobrand/Reading.pm b/perllib/FixMyStreet/Cobrand/Reading.pm index f4fd0dc7a..8e98931fd 100644 --- a/perllib/FixMyStreet/Cobrand/Reading.pm +++ b/perllib/FixMyStreet/Cobrand/Reading.pm @@ -77,5 +77,32 @@ sub recent_photos { return $self->problems->recent_photos( $num, $lat, $lon, $dist ); } -1; +sub get_report_stats { + my $self = shift; + + my ( $cobrand, $main_site ) = ( 0, 0 ); + + $self->{c}->log->debug( 'X' x 60 ); + my $stats = $self->{c}->model('DB::Problem')->search( + { confirmed => { '>=', '2011-11-01' } }, + { + select => [ { count => 'id', -as => 'cobrand_count' }, 'cobrand' ], + group_by => [qw/cobrand/] + } + ); + + while ( my $stat = $stats->next ) { + if ( $stat->cobrand eq $self->moniker ) { + $cobrand += $stat->get_column( 'cobrand_count' ); + } else { + $main_site += $stat->get_column( 'cobrand_count' ); + } + } + return { + cobrand => $cobrand, + main_site => $main_site, + }; +} + +1; diff --git a/perllib/FixMyStreet/Cobrand/Southampton.pm b/perllib/FixMyStreet/Cobrand/Southampton.pm index bd461f5e2..213dd533b 100644 --- a/perllib/FixMyStreet/Cobrand/Southampton.pm +++ b/perllib/FixMyStreet/Cobrand/Southampton.pm @@ -64,6 +64,7 @@ sub all_councils_report { sub disambiguate_location { return { + town => 'Southampton', centre => '50.913822,-1.400493', span => '0.084628,0.15701', bounds => [ '50.871508,-1.478998', '50.956136,-1.321988' ], diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index 9ff19efb6..7ceabf1da 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -82,6 +82,8 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "flagged", { data_type => "boolean", default_value => \"false", is_nullable => 0 }, + "geocode", + { data_type => "bytea", is_nullable => 1 }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->has_many( @@ -104,8 +106,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-07-29 16:26:23 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ifvx9FOlbui66hPyzNIAPA +# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-09-19 14:38:43 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nq8Ufn/SEoDGSrrGlHIxag # Add fake relationship to stored procedure table __PACKAGE__->has_one( @@ -134,6 +136,27 @@ __PACKAGE__->filter_column( }, } ); + +__PACKAGE__->filter_column( + geocode => { + filter_from_storage => sub { + my $self = shift; + my $ser = shift; + return undef unless defined $ser; + my $h = new IO::String($ser); + return RABX::wire_rd($h); + }, + filter_to_storage => sub { + my $self = shift; + my $data = shift; + my $ser = ''; + my $h = new IO::String($ser); + RABX::wire_wr( $data, $h ); + return $ser; + }, + } +); + use DateTime::TimeZone; use Image::Size; use Moose; diff --git a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm index c1a5d65c9..32654e534 100644 --- a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm +++ b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm @@ -9,6 +9,8 @@ use mySociety::EmailUtil; use mySociety::Gaze; use mySociety::Locale; use mySociety::MaPit; +use IO::String; +use RABX; # Child must have confirmed, id, email, state(!) columns # If parent/child, child table must also have name and text @@ -82,12 +84,21 @@ sub email_alerts ($) { } my $url = $cobrand->base_url_for_emails( $row->{alert_cobrand_data} ); + # this is currently only for new_updates if ($row->{item_text}) { $data{problem_url} = $url . "/report/" . $row->{id}; $data{data} .= $row->{item_name} . ' : ' if $row->{item_name} && !$row->{item_anonymous}; $data{data} .= $row->{item_text} . "\n\n------\n\n"; + # this is ward and council problems } else { - $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}\n\n"; + my $postcode = $cobrand->format_postcode( $row->{postcode} ); + $postcode = ", $postcode" if $postcode; + $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}$postcode\n\n"; + if ( exists $row->{geocode} && $row->{geocode} && $ref =~ /ward|council/ ) { + my $nearest_st = _get_address_from_gecode( $row->{geocode} ); + $data{data} .= $nearest_st if $nearest_st; + } + $data{data} .= "\n\n------\n\n"; } if (!$data{alert_user_id}) { %data = (%data, %$row); @@ -134,7 +145,7 @@ sub email_alerts ($) { }; my $states = "'" . join( "', '", FixMyStreet::DB::Result::Problem::visible_states() ) . "'"; my %data = ( template => $template, data => '', alert_id => $alert->id, alert_email => $alert->user->email, lang => $alert->lang, cobrand => $alert->cobrand, cobrand_data => $alert->cobrand_data ); - my $q = "select problem.id, problem.title from problem_find_nearby(?, ?, ?) as nearby, problem, users + my $q = "select problem.id, problem.postcode, problem.geocode, problem.title from problem_find_nearby(?, ?, ?) as nearby, problem, users where nearby.problem_id = problem.id and problem.user_id = users.id and problem.state in ($states) @@ -150,7 +161,14 @@ sub email_alerts ($) { alert_id => $alert->id, parameter => $row->{id}, } ); - $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}\n\n"; + my $postcode = $cobrand->format_postcode( $row->{postcode} ); + $postcode = ", $postcode" if $postcode; + $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}$postcode\n\n"; + if ( exists $row->{geocode} && $row->{geocode} ) { + my $nearest_st = _get_address_from_gecode( $row->{geocode} ); + $data{data} .= $nearest_st if $nearest_st; + } + $data{data} .= "\n\n------\n\n"; } _send_aggregated_alert_email(%data) if $data{data}; } @@ -210,4 +228,23 @@ sub _send_aggregated_alert_email(%) { } } +sub _get_address_from_gecode { + my $geocode = shift; + + return '' unless defined $geocode; + my $h = new IO::String($geocode); + my $data = RABX::wire_rd($h); + + my $str = ''; + + my $address = $data->{resourceSets}[0]{resources}[0]{address}; + my @address; + push @address, $address->{addressLine} if $address->{addressLine} && $address->{addressLine} ne 'Street'; + push @address, $address->{locality} if $address->{locality}; + $str .= sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s\n\n"), + join( ', ', @address ) ) if @address; + + return $str; +} + 1; diff --git a/perllib/FixMyStreet/Map/FMS.pm b/perllib/FixMyStreet/Map/FMS.pm index d5edac763..24842c861 100644 --- a/perllib/FixMyStreet/Map/FMS.pm +++ b/perllib/FixMyStreet/Map/FMS.pm @@ -47,11 +47,13 @@ sub map_tiles { "http://tilma.mysociety.org/sv/$z/$x/$y.png", ]; } else { + my $url = "g=701"; + $url .= "&productSet=mmOS" if $z > 10; return [ - "http://ecn.t0.tiles.virtualearth.net/tiles/r" . get_quadkey($x-1, $y-1, $z) . ".png?g=701&productSet=mmOS", - "http://ecn.t1.tiles.virtualearth.net/tiles/r" . get_quadkey($x, $y-1, $z) . ".png?g=701&productSet=mmOS", - "http://ecn.t2.tiles.virtualearth.net/tiles/r" . get_quadkey($x-1, $y, $z) . ".png?g=701&productSet=mmOS", - "http://ecn.t3.tiles.virtualearth.net/tiles/r" . get_quadkey($x, $y, $z) . ".png?g=701&productSet=mmOS", + "http://ecn.t0.tiles.virtualearth.net/tiles/r" . get_quadkey($x-1, $y-1, $z) . ".png?$url", + "http://ecn.t1.tiles.virtualearth.net/tiles/r" . get_quadkey($x, $y-1, $z) . ".png?$url", + "http://ecn.t2.tiles.virtualearth.net/tiles/r" . get_quadkey($x-1, $y, $z) . ".png?$url", + "http://ecn.t3.tiles.virtualearth.net/tiles/r" . get_quadkey($x, $y, $z) . ".png?$url", ]; } } |