aboutsummaryrefslogtreecommitdiffstats
path: root/bin/send-comments
blob: 1a12fa684439a2fb6cf844f448d98de0a2cbe6e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env perl

# send-reports:
# Send new problem reports to bodies
#
# Copyright (c) 2011 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org

use strict;
use warnings;
require 5.8.0;

use Digest::MD5;
use Encode;
use Error qw(:try);
use CronFns;

use FixMyStreet::App;

use Utils;
use mySociety::Config;
use mySociety::EmailUtil;

use Open311;

# maximum number of webservice attempts to send before not trying any more (XXX may be better in config?)
use constant SEND_FAIL_RETRIES_CUTOFF => 3;

# send_method config values found in by-area config data, for selecting to appropriate method
use constant SEND_METHOD_EMAIL      => 'email';
use constant SEND_METHOD_OPEN311    => 'Open311';

# Set up site, language etc.
my ($verbose, $nomail) = CronFns::options();
my $base_url = mySociety::Config::get('BASE_URL');
my $site = CronFns::site($base_url);

my $bodies = FixMyStreet::App->model('DB::Body')->search( {
    send_method => SEND_METHOD_OPEN311,
    send_comments => 1,
} );

while ( my $body = $bodies->next ) {
    my $use_extended = 0;
    my $comments = FixMyStreet::App->model('DB::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',
        }
    );

    if ( $body->areas->{2482} ) {
        $use_extended = 1;
    }

    my $o = Open311->new(
            endpoint => $body->endpoint,
            jurisdiction => $body->jurisdiction,
            api_key => $body->api_key,
            use_extended_updates => $use_extended,
    );

    if ( $body->areas->{2482} ) {
        my $endpoints = $o->endpoints;
        $endpoints->{update} = 'update.xml';
        $endpoints->{service_request_updates} = 'update.xml';
        $o->endpoints( $endpoints );
    }

    while ( my $comment = $comments->next ) {
        my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($comment->cobrand)->new();

        if ( $comment->send_fail_count ) {
            next if bromley_retry_timeout( $comment );
        }

        if ( $body->areas->{2482} ) {
            my $extra = $comment->extra;
            if ( !$extra ) {
                $extra = {};
            }

            unless ( $extra->{title} ) {
                $extra->{title} = $comment->user->title;
                $comment->extra( $extra );
            }
        }

        my $id = $o->post_service_request_update( $comment );

        if ( $id ) {
            $comment->update( {
                external_id => $id,
                whensent    => \'ms_current_timestamp()',
            } );
        } else {
            $comment->update( {
                send_fail_count => $comment->send_fail_count + 1,
                send_fail_timestamp => \'ms_current_timestamp()',
                send_fail_reason => 'Failed to post over Open311',
            } );
        }
    }
}

sub bromley_retry_timeout {
    my $row = shift;

    my $tz = DateTime::TimeZone->new( name => 'local' );
    my $now = DateTime->now( time_zone => $tz );
    my $diff = $now - $row->send_fail_timestamp;
    if ( $diff->in_units( 'minutes' ) < 30 ) {
        return 1;
    }

    return 0;
}