source: trunk/npemap.org.uk/cgi/submit.fcgi @ 38

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

Unused sub declaration

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