aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/Script
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/Script')
-rw-r--r--perllib/FixMyStreet/Script/Alerts.pm41
-rw-r--r--perllib/FixMyStreet/Script/Questionnaires.pm6
-rw-r--r--perllib/FixMyStreet/Script/Reports.pm8
-rwxr-xr-xperllib/FixMyStreet/Script/UpdateAllReports.pm136
4 files changed, 120 insertions, 71 deletions
diff --git a/perllib/FixMyStreet/Script/Alerts.pm b/perllib/FixMyStreet/Script/Alerts.pm
index c001cc311..4b5641f9e 100644
--- a/perllib/FixMyStreet/Script/Alerts.pm
+++ b/perllib/FixMyStreet/Script/Alerts.pm
@@ -39,6 +39,7 @@ sub send() {
$item_table.name as item_name, $item_table.anonymous as item_anonymous,
$item_table.confirmed as item_confirmed,
$item_table.photo as item_photo,
+ $item_table.problem_state as item_problem_state,
$head_table.*
from alert, $item_table, $head_table
where alert.parameter::integer = $head_table.id
@@ -65,6 +66,7 @@ sub send() {
$query = FixMyStreet::DB->schema->storage->dbh->prepare($query);
$query->execute();
my $last_alert_id;
+ my $last_problem_state = '';
my %data = ( template => $alert_type->template, data => [], schema => $schema );
while (my $row = $query->fetchrow_hashref) {
@@ -86,7 +88,26 @@ sub send() {
alert_id => $row->{alert_id},
parameter => $row->{item_id},
} );
+
+ # this is currently only for new_updates
+ if (defined($row->{item_text})) {
+ # this might throw up the odd false positive but only in cases where the
+ # state has changed and there was already update text
+ if ($row->{item_problem_state} &&
+ !( $last_problem_state eq '' && $row->{item_problem_state} eq 'confirmed' ) &&
+ $last_problem_state ne $row->{item_problem_state}
+ ) {
+ my $state = FixMyStreet::DB->resultset("State")->display($row->{item_problem_state}, 1, $cobrand);
+
+ my $update = _('State changed to:') . ' ' . $state;
+ $row->{item_text} = $row->{item_text} ? $row->{item_text} . "\n\n" . $update :
+ $update;
+ }
+ next unless $row->{item_text};
+ }
+
if ($last_alert_id && $last_alert_id != $row->{alert_id}) {
+ $last_problem_state = '';
_send_aggregated_alert_email(%data);
%data = ( template => $alert_type->template, data => [], schema => $schema );
}
@@ -109,7 +130,7 @@ sub send() {
my $user = $schema->resultset('User')->find( {
id => $row->{alert_user_id}
} );
- $data{alert_email} = $user->email;
+ $data{alert_user} = $user;
my $token_obj = $schema->resultset('Token')->create( {
scope => 'alert_to_reporter',
data => {
@@ -209,7 +230,7 @@ sub send() {
template => $template,
data => [],
alert_id => $alert->id,
- alert_email => $alert->user->email,
+ alert_user => $alert->user,
lang => $alert->lang,
cobrand => $cobrand,
cobrand_data => $alert->cobrand_data,
@@ -258,16 +279,20 @@ sub _send_aggregated_alert_email(%) {
$cobrand->set_lang_and_domain( $data{lang}, 1, FixMyStreet->path_to('locale')->stringify );
FixMyStreet::Map::set_map_class($cobrand->map_type);
- if (!$data{alert_email}) {
+ if (!$data{alert_user}) {
my $user = $data{schema}->resultset('User')->find( {
id => $data{alert_user_id}
} );
- $data{alert_email} = $user->email;
+ $data{alert_user} = $user;
}
- my ($domain) = $data{alert_email} =~ m{ @ (.*) \z }x;
+ # Ignore phone-only users
+ return unless $data{alert_user}->email_verified;
+
+ my $email = $data{alert_user}->email;
+ my ($domain) = $email =~ m{ @ (.*) \z }x;
return if $data{schema}->resultset('Abuse')->search( {
- email => [ $data{alert_email}, $domain ]
+ email => [ $email, $domain ]
} )->first;
my $token = $data{schema}->resultset("Token")->new_result( {
@@ -275,7 +300,7 @@ sub _send_aggregated_alert_email(%) {
data => {
id => $data{alert_id},
type => 'unsubscribe',
- email => $data{alert_email},
+ email => $email,
}
} );
$data{unsubscribe_url} = $cobrand->base_url( $data{cobrand_data} ) . '/A/' . $token->token;
@@ -286,7 +311,7 @@ sub _send_aggregated_alert_email(%) {
"$data{template}.txt",
\%data,
{
- To => $data{alert_email},
+ To => $email,
},
$sender,
0,
diff --git a/perllib/FixMyStreet/Script/Questionnaires.pm b/perllib/FixMyStreet/Script/Questionnaires.pm
index ec6139d2d..5fc01512d 100644
--- a/perllib/FixMyStreet/Script/Questionnaires.pm
+++ b/perllib/FixMyStreet/Script/Questionnaires.pm
@@ -49,7 +49,11 @@ sub send_questionnaires_period {
# Not all cobrands send questionnaires
next unless $cobrand->send_questionnaires;
- next if $row->is_from_abuser;
+
+ if ($row->is_from_abuser || !$row->user->email_verified) {
+ $row->update( { send_questionnaire => 0 } );
+ next;
+ }
# Cobranded and non-cobranded messages can share a database. In this case, the conf file
# should specify a vhost to send the reports for each cobrand, so that they don't get sent
diff --git a/perllib/FixMyStreet/Script/Reports.pm b/perllib/FixMyStreet/Script/Reports.pm
index 1e5fd55bb..04ad1c893 100644
--- a/perllib/FixMyStreet/Script/Reports.pm
+++ b/perllib/FixMyStreet/Script/Reports.pm
@@ -84,7 +84,6 @@ sub send(;$) {
$h{query} = $row->postcode;
$h{url} = $email_base_url . $row->url;
$h{admin_url} = $row->admin_url($cobrand);
- $h{phone_line} = $h{phone} ? _('Phone:') . " $h{phone}\n\n" : '';
if ($row->photo) {
$h{has_photo} = _("This web page also contains a photo of the problem, provided by the user.") . "\n\n";
$h{image_url} = $email_base_url . $row->photos->[0]->{url_full};
@@ -223,7 +222,9 @@ sub send(;$) {
for my $sender ( keys %reporters ) {
debug_print("sending using " . $sender, $row->id) if $debug_mode;
$sender = $reporters{$sender};
- $result *= $sender->send( $row, \%h );
+ my $res = $sender->send( $row, \%h );
+ $result *= $res;
+ $row->add_send_method($sender) if !$res;
if ( $sender->unconfirmed_counts) {
foreach my $e (keys %{ $sender->unconfirmed_counts } ) {
foreach my $c (keys %{ $sender->unconfirmed_counts->{$e} }) {
@@ -299,6 +300,9 @@ sub _send_report_sent_email {
my $nomail = shift;
my $cobrand = shift;
+ # Don't send 'report sent' text
+ return unless $row->user->email_verified;
+
FixMyStreet::Email::send_cron(
$row->result_source->schema,
'confirm_report_sent.txt',
diff --git a/perllib/FixMyStreet/Script/UpdateAllReports.pm b/perllib/FixMyStreet/Script/UpdateAllReports.pm
index 1bd069ee8..d6f3eb64b 100755
--- a/perllib/FixMyStreet/Script/UpdateAllReports.pm
+++ b/perllib/FixMyStreet/Script/UpdateAllReports.pm
@@ -4,11 +4,9 @@ use strict;
use warnings;
use FixMyStreet;
+use FixMyStreet::Cobrand;
use FixMyStreet::DB;
-use File::Path ();
-use File::Slurp;
-use JSON::MaybeXS;
use List::MoreUtils qw(zip);
use List::Util qw(sum);
@@ -21,6 +19,11 @@ if ( FixMyStreet->config('BASE_URL') =~ /zurich|zueri/ ) {
$age_column = 'created';
}
+my $dtf = FixMyStreet::DB->schema->storage->datetime_parser;
+
+my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('default')->new;
+FixMyStreet::DB->schema->cobrand($cobrand);
+
sub generate {
my $include_areas = shift;
@@ -81,13 +84,10 @@ sub generate {
}
}
- my $body = encode_json( {
+ return {
fixed => \%fixed,
open => \%open,
- } );
-
- File::Path::mkpath( FixMyStreet->path_to( '../data/' )->stringify );
- File::Slurp::write_file( FixMyStreet->path_to( '../data/all-reports.json' )->stringify, \$body );
+ };
}
sub end_period {
@@ -107,10 +107,18 @@ sub loop_period {
}
sub generate_dashboard {
+ my $body = shift;
+
my %data;
+ my $rs = FixMyStreet::DB->resultset('Problem');
+ $rs = $rs->to_body($body) if $body;
+
+ my $rs_c = FixMyStreet::DB->resultset('Comment');
+ $rs_c = $rs_c->to_body($body) if $body;
+
my $end_today = end_period('day');
- my $min_confirmed = FixMyStreet::DB->resultset('Problem')->search({
+ my $min_confirmed = $rs->search({
state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
}, {
select => [ { min => 'confirmed' } ],
@@ -134,11 +142,11 @@ sub generate_dashboard {
my @problem_periods = loop_period($min_confirmed, $group_by, $extra);
my %problems_reported_by_period = stuff_by_day_or_year(
- $group_by, 'Problem',
+ $group_by, $rs,
state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
);
my %problems_fixed_by_period = stuff_by_day_or_year(
- $group_by, 'Problem',
+ $group_by, $rs,
state => [ FixMyStreet::DB::Result::Problem->fixed_states() ],
);
@@ -158,24 +166,23 @@ sub generate_dashboard {
);
$data{last_seven_days} = \%last_seven_days;
- my $dtf = FixMyStreet::DB->schema->storage->datetime_parser;
my $eight_ago = $dtf->format_datetime(DateTime->now->subtract(days => 8));
%problems_reported_by_period = stuff_by_day_or_year('day',
- 'Problem',
+ $rs,
state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
- confirmed => { '>=', $eight_ago },
+ 'me.confirmed' => { '>=', $eight_ago },
);
%problems_fixed_by_period = stuff_by_day_or_year('day',
- 'Comment',
- confirmed => { '>=', $eight_ago },
+ $rs_c,
+ 'me.confirmed' => { '>=', $eight_ago },
-or => [
problem_state => [ FixMyStreet::DB::Result::Problem->fixed_states() ],
mark_fixed => 1,
],
);
my %problems_updated_by_period = stuff_by_day_or_year('day',
- 'Comment',
- confirmed => { '>=', $eight_ago },
+ $rs_c,
+ 'me.confirmed' => { '>=', $eight_ago },
);
my $date = DateTime->today->subtract(days => 7);
@@ -189,47 +196,17 @@ sub generate_dashboard {
$last_seven_days{fixed_total} = sum @{$last_seven_days{fixed}};
$last_seven_days{updated_total} = sum @{$last_seven_days{updated}};
- my(@top_five_bodies);
- $data{top_five_bodies} = \@top_five_bodies;
-
- my $bodies = FixMyStreet::DB->resultset('Body')->search;
- my $substmt = "select min(id) from comment where me.problem_id=comment.problem_id and (problem_state in ('fixed', 'fixed - council', 'fixed - user') or mark_fixed)";
- while (my $body = $bodies->next) {
- my $subquery = FixMyStreet::DB->resultset('Comment')->to_body($body)->search({
- -or => [
- problem_state => [ FixMyStreet::DB::Result::Problem->fixed_states() ],
- mark_fixed => 1,
- ],
- 'me.id' => \"= ($substmt)",
- 'me.state' => 'confirmed',
- }, {
- select => [
- { extract => "epoch from me.confirmed-problem.confirmed", -as => 'time' },
- ],
- as => [ qw/time/ ],
- rows => 100,
- order_by => { -desc => 'me.confirmed' },
- join => 'problem'
- })->as_subselect_rs;
- my $avg = $subquery->search({
- }, {
- select => [ { avg => "time" } ],
- as => [ qw/avg/ ],
- })->first->get_column('avg');
- push @top_five_bodies, { name => $body->name, days => int($avg / 60 / 60 / 24 + 0.5) }
- if defined $avg;
+ if ($body) {
+ calculate_top_five_wards(\%data, $rs, $body);
+ } else {
+ calculate_top_five_bodies(\%data);
}
- @top_five_bodies = sort { $a->{days} <=> $b->{days} } @top_five_bodies;
- $data{average} = @top_five_bodies
- ? int((sum map { $_->{days} } @top_five_bodies) / @top_five_bodies + 0.5) : undef;
-
- @top_five_bodies = @top_five_bodies[0..4] if @top_five_bodies > 5;
my $week_ago = $dtf->format_datetime(DateTime->now->subtract(days => 7));
- my $last_seven_days = FixMyStreet::DB->resultset("Problem")->search({
+ my $last_seven_days = $rs->search({
confirmed => { '>=', $week_ago },
})->count;
- my @top_five_categories = FixMyStreet::DB->resultset("Problem")->search({
+ my @top_five_categories = $rs->search({
confirmed => { '>=', $week_ago },
category => { '!=', 'Other' },
}, {
@@ -247,19 +224,17 @@ sub generate_dashboard {
}
$data{other_categories} = $last_seven_days;
- my $body = encode_json( \%data );
- File::Path::mkpath( FixMyStreet->path_to( '../data/' )->stringify );
- File::Slurp::write_file( FixMyStreet->path_to( '../data/all-reports-dashboard.json' )->stringify, \$body );
+ return \%data;
}
sub stuff_by_day_or_year {
my $period = shift;
- my $table = shift;
+ my $rs = shift;
my %params = @_;
- my $results = FixMyStreet::DB->resultset($table)->search({
+ my $results = $rs->search({
%params
}, {
- select => [ { extract => \"$period from confirmed", -as => $period }, { count => 'id' } ],
+ select => [ { extract => \"$period from me.confirmed", -as => $period }, { count => 'me.id' } ],
as => [ $period, 'count' ],
group_by => [ $period ],
});
@@ -271,4 +246,45 @@ sub stuff_by_day_or_year {
return %out;
}
+sub calculate_top_five_bodies {
+ my ($data) = @_;
+
+ my(@top_five_bodies);
+
+ my $bodies = FixMyStreet::DB->resultset('Body')->search;
+ while (my $body = $bodies->next) {
+ my $avg = $body->calculate_average;
+ push @top_five_bodies, { name => $body->name, days => int($avg / 60 / 60 / 24 + 0.5) }
+ if defined $avg;
+ }
+ @top_five_bodies = sort { $a->{days} <=> $b->{days} } @top_five_bodies;
+ $data->{average} = @top_five_bodies
+ ? int((sum map { $_->{days} } @top_five_bodies) / @top_five_bodies + 0.5) : undef;
+
+ @top_five_bodies = @top_five_bodies[0..4] if @top_five_bodies > 5;
+ $data->{top_five_bodies} = \@top_five_bodies;
+}
+
+sub calculate_top_five_wards {
+ my ($data, $rs, $body) = @_;
+
+ my $children = $body->first_area_children;
+ die $children->{error} if $children->{error};
+
+ my $week_ago = $dtf->format_datetime(DateTime->now->subtract(days => 7));
+ my $last_seven_days = $rs->search({ confirmed => { '>=', $week_ago } });
+ my $last_seven_days_count = $last_seven_days->count;
+ $last_seven_days = $last_seven_days->search(undef, { select => 'areas' });
+
+ while (my $row = $last_seven_days->next) {
+ $children->{$_}{reports}++ foreach grep { $children->{$_} } split /,/, $row->areas;
+ }
+ my @wards = sort { $b->{reports} <=> $a->{reports} } grep { $_->{reports} } values %$children;
+ @wards = @wards[0..4] if @wards > 5;
+
+ my $sum_five = (sum map { $_->{reports} } @wards) || 0;
+ $data->{other_wards} = $last_seven_days_count - $sum_five;
+ $data->{wards} = \@wards;
+}
+
1;