#!/usr/bin/perl -w
# index.cgi:
# Main code for FixMyStreet
#
# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
# $Id: index.cgi,v 1.140 2007-06-16 19:42:25 matthew Exp $
use strict;
require 5.8.0;
# Horrible boilerplate to set up appropriate library paths.
use FindBin;
use lib "$FindBin::Bin/../perllib";
use lib "$FindBin::Bin/../../perllib";
use Error qw(:try);
use File::Slurp;
use Image::Magick;
use LWP::Simple;
use RABX;
use CGI::Carp;
use Digest::MD5 qw(md5_hex);
use URI::Escape;
use Page;
use mySociety::AuthToken;
use mySociety::Config;
use mySociety::DBHandle qw(dbh select_all);
use mySociety::Gaze;
use mySociety::GeoUtil;
use mySociety::Util;
use mySociety::MaPit;
use mySociety::VotingArea;
use mySociety::Web qw(ent NewURL);
BEGIN {
mySociety::Config::set_file("$FindBin::Bin/../conf/general");
mySociety::DBHandle::configure(
Name => mySociety::Config::get('BCI_DB_NAME'),
User => mySociety::Config::get('BCI_DB_USER'),
Password => mySociety::Config::get('BCI_DB_PASS'),
Host => mySociety::Config::get('BCI_DB_HOST', undef),
Port => mySociety::Config::get('BCI_DB_PORT', undef)
);
if (!dbh()->selectrow_array('select secret from secret for update of secret')) {
local dbh()->{HandleError};
dbh()->do('insert into secret (secret) values (?)', {}, unpack('h*', mySociety::Util::random_bytes(32)));
}
dbh()->commit();
}
# Main code for index.cgi
sub main {
my $q = shift;
my $out = '';
my %params;
if ($q->param('submit_problem')) {
$params{title} = 'Submitting your problem';
$out = submit_problem($q);
} elsif ($q->param('submit_update')) {
$params{title} = 'Submitting your update';
($out) = submit_update($q);
} elsif ($q->param('submit_map')) {
$params{title} = 'Reporting a problem';
$out = display_form($q);
} elsif ($q->param('id')) {
($out, %params) = display_problem($q);
$params{title} .= ' - Viewing a problem';
} elsif ($q->param('pc') || ($q->param('x') && $q->param('y'))) {
($out, %params) = display_location($q);
$params{title} = 'Viewing a location';
} else {
$out = front_page($q);
}
print Page::header($q, %params);
print $out;
print Page::footer();
dbh()->rollback();
}
Page::do_fastcgi(\&main);
# Display front page
sub front_page {
my ($q, $error) = @_;
my $pc_h = ent($q->param('pc') || '');
my $out = <
(like graffiti, fly tipping, broken paving slabs, or street lighting)
' . $error . '
' if ($error); my $fixed = dbh()->selectrow_array("select count(*) from problem where state='fixed' and lastupdate>ms_current_timestamp()-'1 month'::interval"); my $updates = dbh()->selectrow_array("select count(*) from comment where state='confirmed'"); my $new = dbh()->selectrow_array("select count(*) from problem where state in ('confirmed','fixed') and confirmed>ms_current_timestamp()-'1 week'::interval"); $out .= <Please note:
If you cannot see a map – if you have images turned off, or are using a text only browser, for example – and you wish to report a problem, please skip this step and we will ask you to describe the location of your problem instead.
EOF $out .= <No problems have been reported yet.
'; } $out .= <No problems have been reported yet.
'; } $out .= <No problems have been fixed yet
'; } $out .= ''; $out .= Page::display_map_end(1); my %params = ( rss => [ 'Recent local problems, FixMyStreet', "/rss/$x,$y" ] ); return ($out, %params); } sub display_problem { my ($q, @errors) = @_; my @vars = qw(id name email update fixed x y); my %input = map { $_ => $q->param($_) || '' } @vars; my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; $input{x} ||= 0; $input{x} += 0; $input{y} ||= 0; $input{y} += 0; # Get all information from database my $problem = dbh()->selectrow_hashref( "select id, easting, northing, council, category, title, detail, photo, used_map, name, anonymous, extract(epoch from confirmed) as time, state, extract(epoch from whensent-confirmed) as whensent, extract(epoch from ms_current_timestamp()-lastupdate) as duration from problem where id=? and state in ('confirmed','fixed', 'hidden')", {}, $input{id}); return display_location($q, 'Unknown problem ID') unless $problem; return front_page($q, 'That problem has been hidden from public view as it contained inappropriate public details') if $problem->{state} eq 'hidden'; my $x = Page::os_to_tile($problem->{easting}); my $y = Page::os_to_tile($problem->{northing}); my $x_tile = $input{x} || int($x); my $y_tile = $input{y} || int($y); my $px = Page::os_to_px($problem->{easting}, $x_tile); my $py = Page::os_to_px($problem->{northing}, $y_tile); my $out = ''; my $pins = Page::display_pin($q, $px, $py, 'blue'); $out .= Page::display_map($q, x => $x_tile, y => $y_tile, type => 0, pins => $pins, px => $px, py => $py ); $out .= $q->p({id => 'unknown'}, _('This problem is old and of unknown status.')) if $problem->{state} eq 'confirmed' && $problem->{duration} > 8*7*24*60*60; $out .= $q->p({id => 'fixed'}, _('This problem has been fixed.')) if $problem->{state} eq 'fixed'; $out .= Page::display_problem_text($q, $problem); $out .= $q->p({align=>'right'}, $q->small($q->a({href => '/contact?id=' . $input{id}}, 'Offensive? Unsuitable? Tell us')) ); # Try and have pin near centre of map $x_tile -= 1 if $x - $x_tile < 0.5; $y_tile -= 1 if $y - $y_tile < 0.5; my $back = NewURL($q, id=>undef, x=>$x_tile, y=>$y_tile); $out .= ''; $out .= 'Receive email when updates are left on this problem
EOF $out .= Page::display_problem_updates($input{id}); $out .= 'We found more than one match for that location: