source: trunk/npemap.org.uk/cgi/submit.cgi @ 27

Last change on this file since 27 was 27, checked in by Dominic Hargreaves, 15 years ago

Add check for duplicate submissions.

  • Property svn:executable set to *
File size: 3.3 KB
Line 
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use DBI;
7use CGI qw/:standard -debug/;
8use Geo::Postcode;
9use Date::Format;
10
11sub print_err;
12sub print_ok;
13
14my $dbh = DBI->connect("dbi:Pg:dbname=npemaps","npemaps","") or
15    print_err("Could not connect to database");
16
17my $cgi = new CGI;
18
19my ($easting, $northing);
20my @fields = qw(easting northing postcode);
21
22# Input validation
23foreach my $field (@fields) {
24    unless (defined $cgi->param($field)) {
25        print_err ("Parameter '$field' missing");
26    }
27}
28
29# Is the Easting in a valid range?
30if (($cgi->param('easting') > 700000) or
31    ($cgi->param('easting') < 0)) {
32    print_err ("Parameter 'easting' must be an integer between 0 and 700,000");
33} else {
34    $easting = $cgi->param('easting');
35}
36
37# Is the Northing in a valid range?
38if (($cgi->param('northing') > 1300000) or
39    ($cgi->param('northing') < 0)) {
40    print_err("Parameter 'northing' must be an integer between 0 and 1,300,000");
41} else {
42    $northing = $cgi->param('northing');
43}
44
45my $sth;
46
47# Now validate the postcode input format
48my $raw_postcode = $cgi->param('postcode');
49my $postcode = Geo::Postcode->new($raw_postcode);
50my ($first, $second, $third, $fourth) = @{$postcode->fragments};
51my ($outward, $inward);
52
53if ($postcode->valid) {
54    # We have a complete postcode; input it straight into the database
55    $outward = $first . $second;
56    $inward = $third . $fourth;
57} elsif($postcode->valid_fragment) {
58    # We have a valid fragment; let's build up what we can
59    # We are guaranteed to have the first two
60    $outward = $first . $second;
61    $inward = $third if $third;
62    $inward .= $fourth if $fourth;
63} else {
64    print_err("The postcode format is not valid");
65}
66
67# Check for a duplicate.
68# We want to collect duplicates from different IP addresses as a kind of
69# corroboration factor; this just catches accidental double-submission
70# really.
71$sth = $dbh->prepare('SELECT * FROM postcodes WHERE raw_postcode = ? AND easting = ? AND northing = ? AND ip = ?');
72unless ($sth->execute($raw_postcode, $easting, $northing, $ENV{'REMOTE_ADDR'})) {
73    print_err('Database error when checking for duplicate data :(');
74}
75
76if ($sth->rows) {
77    print_err('You, or someone with the same IP address, have already submitted this postcode with these co-ordinates.');
78}
79
80$sth = $dbh->prepare('INSERT INTO postcodes (outward, inward, raw_postcode, easting, northing, ip, created_at, source) VALUES (?, ?, ?, ?, ?, ?, ?, 0)');
81if ($sth->execute($outward, $inward, $raw_postcode, $easting, $northing, $ENV{'REMOTE_ADDR'}, time2str('%Y-%m-%d %H:%M:%S', time))) {
82    print "Content-type: text/html\n\n";
83    print "<html><head><title>Thank you</title></head>\n";
84    print "<body>Thank you for telling us where your post code is!\n";
85    print "</body></html>";
86    exit 0;
87} else {
88    print STDERR "DB error: " . $dbh->errstr . "\n";
89    print_err("Database error when adding your data :(");
90}
91
92sub print_err ($) {
93    my $err = shift;
94    print "Content-type: text/html\n\n";
95    print "<html><head><title>Error submitting</title></head>\n";
96    print "<body><p>The following error occurred whilst submitting data:\n";
97    print CGI::escapeHTML($err);
98    print "</p><p>Your input was:</p>\n<ul>";
99    foreach my $field (@fields) {
100        my $param = $cgi->param($field) || '';
101        print "<li>$field: " . $param . "</li>\n";
102    }
103    print "</ul></body></html>\n";
104    exit 0;
105}
Note: See TracBrowser for help on using the repository browser.