aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm41
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm7
-rw-r--r--perllib/FixMyStreet/App/Controller/Reports.pm11
-rwxr-xr-xperllib/FixMyStreet/App/Controller/Rss.pm10
-rw-r--r--perllib/FixMyStreet/Cobrand/Default.pm67
-rw-r--r--perllib/FixMyStreet/Cobrand/Reading.pm29
-rw-r--r--perllib/FixMyStreet/Cobrand/Southampton.pm1
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm27
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/AlertType.pm43
-rw-r--r--perllib/FixMyStreet/Map/FMS.pm10
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",
];
}
}