diff options
Diffstat (limited to 'perllib')
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Bromley.pm | 19 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Buckinghamshire.pm | 5 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Lewisham.pm | 15 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Oxfordshire.pm | 13 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Comment.pm | 20 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Problem.pm | 10 | ||||
-rw-r--r-- | perllib/FixMyStreet/Script/Questionnaires.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/Script/Reports.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/SendReport/Email.pm | 2 | ||||
-rw-r--r-- | perllib/Open311.pm | 2 | ||||
-rw-r--r-- | perllib/Open311/GetServiceRequestUpdates.pm | 24 | ||||
-rwxr-xr-x | perllib/Open311/PostServiceRequestUpdates.pm | 128 |
12 files changed, 220 insertions, 22 deletions
diff --git a/perllib/FixMyStreet/Cobrand/Bromley.pm b/perllib/FixMyStreet/Cobrand/Bromley.pm index a6d58504c..e1021eda9 100644 --- a/perllib/FixMyStreet/Cobrand/Bromley.pm +++ b/perllib/FixMyStreet/Cobrand/Bromley.pm @@ -165,5 +165,24 @@ sub open311_config { $params->{extended_description} = 0; } +sub open311_config_updates { + my ($self, $params) = @_; + $params->{use_extended_updates} = 1; + $params->{endpoints} = { + service_request_updates => 'update.xml', + update => 'update.xml' + }; +} + +sub open311_pre_send { + my ($self, $row, $open311) = @_; + + my $extra = $row->extra || {}; + unless ( $extra->{title} ) { + $extra->{title} = $row->user->title; + $row->extra( $extra ); + } +} + 1; diff --git a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm index 783a565f1..fb074da85 100644 --- a/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm +++ b/perllib/FixMyStreet/Cobrand/Buckinghamshire.pm @@ -100,6 +100,11 @@ sub open311_post_send { $sender->send($row, $h); } +sub open311_config_updates { + my ($self, $params) = @_; + $params->{mark_reopen} = 1; +} + sub map_type { 'Buckinghamshire' } sub default_map_zoom { 3 } diff --git a/perllib/FixMyStreet/Cobrand/Lewisham.pm b/perllib/FixMyStreet/Cobrand/Lewisham.pm new file mode 100644 index 000000000..325f6e833 --- /dev/null +++ b/perllib/FixMyStreet/Cobrand/Lewisham.pm @@ -0,0 +1,15 @@ +package FixMyStreet::Cobrand::Lewisham; +use base 'FixMyStreet::Cobrand::UK'; + +use strict; +use warnings; + +sub council_area_id { 2492 } + +sub open311_post_update_skip { + my ($self) = @_; + return 1; +} + +1; + diff --git a/perllib/FixMyStreet/Cobrand/Oxfordshire.pm b/perllib/FixMyStreet/Cobrand/Oxfordshire.pm index f03f1b605..4d627c756 100644 --- a/perllib/FixMyStreet/Cobrand/Oxfordshire.pm +++ b/perllib/FixMyStreet/Cobrand/Oxfordshire.pm @@ -171,6 +171,19 @@ sub open311_config { $params->{extended_description} = 'oxfordshire'; } +sub open311_config_updates { + my ($self, $params) = @_; + $params->{use_customer_reference} = 1; +} + +sub should_skip_sending_update { + my ($self, $update ) = @_; + + # Oxfordshire stores the external id of the problem as a customer reference + # in metadata + return 1 if !$update->problem->get_extra_metadata('customer_reference'); +} + sub on_map_default_status { return 'open'; } sub contact_email { diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm index b4e42b456..d27c5ea8c 100644 --- a/perllib/FixMyStreet/DB/Result/Comment.pm +++ b/perllib/FixMyStreet/DB/Result/Comment.pm @@ -115,6 +115,26 @@ my $stz = sub { around created => $stz; around confirmed => $stz; +=head2 get_cobrand_logged + +Get a cobrand object for the cobrand the update was made on. + +e.g. if an update was logged at www.fixmystreet.com, this will be a +FixMyStreet::Cobrand::FixMyStreet object. + +=cut + +has get_cobrand_logged => ( + is => 'ro', + lazy => 1, + default => sub { + my $self = shift; + my $cobrand_class = FixMyStreet::Cobrand->get_class_for_moniker( $self->cobrand ); + return $cobrand_class->new; + }, +); + + # You can replace this text with custom code or comments, and it will be preserved on regeneration sub check_for_errors { diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm index 76a6f72fb..2192158d3 100644 --- a/perllib/FixMyStreet/DB/Result/Problem.pm +++ b/perllib/FixMyStreet/DB/Result/Problem.pm @@ -780,7 +780,7 @@ sub duration_string { sub local_coords { my $self = shift; - my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($self->cobrand)->new; + my $cobrand = $self->get_cobrand_logged; if ($cobrand->moniker eq 'zurich') { my ($x, $y) = Geo::Coordinates::CH1903Plus::from_latlon($self->latitude, $self->longitude); return ( int($x+0.5), int($y+0.5) ); @@ -896,8 +896,9 @@ sub updates_sent_to_body { return unless $self->send_method_used && $self->send_method_used eq 'Open311'; # Some bodies only send updates *to* FMS, they don't receive updates. - # NB See also the list in bin/send-comments - my $excluded = qr{Lewisham|Oxfordshire}; + my $cobrand = $self->get_cobrand_logged; + my $handler = $cobrand->call_hook(get_body_handler_for_problem => $self); + return 0 if $handler && $handler->call_hook('open311_post_update_skip'); my @bodies = values %{ $self->bodies }; my @updates_sent = grep { @@ -905,8 +906,7 @@ sub updates_sent_to_body { ( $_->send_method eq 'Open311' || $_->send_method eq 'Noop' # Sending might be temporarily disabled - ) && - !($_->name =~ /$excluded/) + ) } @bodies; return scalar @updates_sent; } diff --git a/perllib/FixMyStreet/Script/Questionnaires.pm b/perllib/FixMyStreet/Script/Questionnaires.pm index d89f1bcf8..bcdaa06d6 100644 --- a/perllib/FixMyStreet/Script/Questionnaires.pm +++ b/perllib/FixMyStreet/Script/Questionnaires.pm @@ -43,7 +43,7 @@ sub send_questionnaires_period { while (my $row = $unsent->next) { - my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new(); + my $cobrand = $row->get_cobrand_logged; $cobrand->set_lang_and_domain($row->lang, 1); FixMyStreet::Map::set_map_class($cobrand->map_type); diff --git a/perllib/FixMyStreet/Script/Reports.pm b/perllib/FixMyStreet/Script/Reports.pm index 87f9fd124..dd8f4e370 100644 --- a/perllib/FixMyStreet/Script/Reports.pm +++ b/perllib/FixMyStreet/Script/Reports.pm @@ -44,7 +44,7 @@ sub send(;$) { debug_print("starting to loop through unsent problem reports...") if $debug_mode; while (my $row = $unsent->next) { - my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new(); + my $cobrand = $row->get_cobrand_logged; FixMyStreet::DB->schema->cobrand($cobrand); if ($debug_mode) { diff --git a/perllib/FixMyStreet/SendReport/Email.pm b/perllib/FixMyStreet/SendReport/Email.pm index 4307694a1..1b484aefe 100644 --- a/perllib/FixMyStreet/SendReport/Email.pm +++ b/perllib/FixMyStreet/SendReport/Email.pm @@ -71,7 +71,7 @@ sub send { } my ($verbose, $nomail) = CronFns::options(); - my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new(); + my $cobrand = $row->get_cobrand_logged; $cobrand = $cobrand->call_hook(get_body_handler_for_problem => $row) || $cobrand; my $params = { diff --git a/perllib/Open311.pm b/perllib/Open311.pm index 6c6ec59cc..56fe567c5 100644 --- a/perllib/Open311.pm +++ b/perllib/Open311.pm @@ -397,7 +397,7 @@ sub _populate_service_request_update_params { } if ( $comment->photo ) { - my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($comment->cobrand)->new(); + my $cobrand = $comment->get_cobrand_logged; my $email_base_url = $cobrand->base_url($comment->cobrand_data); my $url = $email_base_url . $comment->photos->[0]->{url_full}; $params->{media_url} = $url; diff --git a/perllib/Open311/GetServiceRequestUpdates.pm b/perllib/Open311/GetServiceRequestUpdates.pm index bef1aca67..c6da37790 100644 --- a/perllib/Open311/GetServiceRequestUpdates.pm +++ b/perllib/Open311/GetServiceRequestUpdates.pm @@ -18,7 +18,7 @@ Readonly::Scalar my $AREA_ID_BROMLEY => 2482; Readonly::Scalar my $AREA_ID_OXFORDSHIRE => 2237; sub fetch { - my $self = shift; + my ($self, $open311) = @_; my $bodies = $self->schema->resultset('Body')->search( { @@ -31,25 +31,23 @@ sub fetch { while ( my $body = $bodies->next ) { - my $o = Open311->new( - endpoint => $body->endpoint, - api_key => $body->api_key, - jurisdiction => $body->jurisdiction, + my %open311_conf = ( + endpoint => $body->endpoint, + api_key => $body->api_key, + jurisdiction => $body->jurisdiction, extended_statuses => $body->send_extended_statuses, ); - # custom endpoint URLs because these councils have non-standard paths - if ( $body->areas->{$AREA_ID_BROMLEY} ) { - my $endpoints = $o->endpoints; - $endpoints->{update} = 'update.xml'; - $endpoints->{service_request_updates} = 'update.xml'; - $o->endpoints( $endpoints ); - } + my $cobrand = $body->get_cobrand_handler; + $cobrand->call_hook(open311_config_updates => \%open311_conf) + if $cobrand; + + $open311 //= Open311->new(%open311_conf); $self->suppress_alerts( $body->suppress_alerts ); $self->blank_updates_permitted( $body->blank_updates_permitted ); $self->system_user( $body->comment_user ); - $self->update_comments( $o, $body ); + $self->update_comments( $open311, $body ); } } diff --git a/perllib/Open311/PostServiceRequestUpdates.pm b/perllib/Open311/PostServiceRequestUpdates.pm new file mode 100755 index 000000000..63e149ece --- /dev/null +++ b/perllib/Open311/PostServiceRequestUpdates.pm @@ -0,0 +1,128 @@ +package Open311::PostServiceRequestUpdates; + +use strict; +use warnings; +use v5.14; + +use DateTime; +use Moo; +use FixMyStreet; +use FixMyStreet::Cobrand; +use FixMyStreet::DB; +use Open311; + +use constant SEND_METHOD_OPEN311 => 'Open311'; + +has verbose => ( is => 'ro', default => 0 ); + +sub send { + my $self = shift; + + my $bodies = FixMyStreet::DB->resultset('Body')->search( { + send_method => SEND_METHOD_OPEN311, + send_comments => 1, + } ); + + while ( my $body = $bodies->next ) { + my $cobrand = $body->get_cobrand_handler; + next if $cobrand && $cobrand->call_hook('open311_post_update_skip'); + $self->process_body($body); + } +} + +sub open311_params { + my ($self, $body) = @_; + + my %open311_conf = ( + endpoint => $body->endpoint, + jurisdiction => $body->jurisdiction, + api_key => $body->api_key, + extended_statuses => $body->send_extended_statuses, + ); + + my $cobrand = $body->get_cobrand_handler; + $cobrand->call_hook(open311_config_updates => \%open311_conf) + if $cobrand; + + return %open311_conf; +} + +sub process_body { + my ($self, $body) = @_; + + my $o = Open311->new( $self->open311_params($body) ); + + my $comments = FixMyStreet::DB->resultset('Comment')->search( { + 'me.whensent' => undef, + 'me.external_id' => undef, + 'me.state' => 'confirmed', + 'me.confirmed' => { '!=' => undef }, + 'problem.whensent' => { '!=' => undef }, + 'problem.external_id' => { '!=' => undef }, + 'problem.bodies_str' => { -like => '%' . $body->id . '%' }, + 'problem.send_method_used' => 'Open311', + }, + { + join => 'problem', + order_by => [ 'confirmed', 'id' ], + } + ); + + while ( my $comment = $comments->next ) { + my $cobrand = $body->get_cobrand_handler || $comment->get_cobrand_logged; + + # Some cobrands (e.g. Buckinghamshire) don't want to receive updates + # from anyone except the original problem reporter. + if ($cobrand->call_hook(should_skip_sending_update => $comment)) { + unless (defined $comment->get_extra_metadata('cobrand_skipped_sending')) { + $comment->set_extra_metadata(cobrand_skipped_sending => 1); + $comment->update; + } + next; + } + + next if !$self->verbose && $comment->send_fail_count && retry_timeout($comment); + + $self->process_update($body, $o, $comment, $cobrand); + } +} + +sub process_update { + my ($self, $body, $o, $comment, $cobrand) = @_; + + $cobrand->call_hook(open311_pre_send => $comment, $o); + + my $id = $o->post_service_request_update( $comment ); + + if ( $id ) { + $comment->update( { + external_id => $id, + whensent => \'current_timestamp', + } ); + } else { + $comment->update( { + send_fail_count => $comment->send_fail_count + 1, + send_fail_timestamp => \'current_timestamp', + send_fail_reason => "Failed to post over Open311\n\n" . $o->error, + } ); + + if ( $self->verbose && $o->error ) { + warn $o->error; + } + } +} + +sub retry_timeout { + my $row = shift; + + my $tz = FixMyStreet->local_time_zone; + my $now = DateTime->now( time_zone => $tz ); + my $diff = $now - $row->send_fail_timestamp; + if ( $diff->in_units( 'minutes' ) < 30 ) { + return 1; + } + + return 0; +} + +1; |