1 | #!/usr/bin/perl |
---|
2 | # |
---|
3 | # Copyright (c) 2006 Dominic Hargreaves |
---|
4 | # See accompanying file "LICENCE" for licence details |
---|
5 | |
---|
6 | use strict; |
---|
7 | use warnings; |
---|
8 | |
---|
9 | use CGI::Fast qw/:standard -debug/; |
---|
10 | use Geo::Postcode; |
---|
11 | |
---|
12 | # Find our private perl libraries |
---|
13 | use FindBin; |
---|
14 | use lib "$FindBin::Bin/../perllib"; |
---|
15 | use NPEMap; |
---|
16 | use NPEMap::Postcodes; |
---|
17 | |
---|
18 | # Set up database handler to try and make sure it's ready for the first |
---|
19 | # request |
---|
20 | # No point in handling errors here since they'll get handled by the request |
---|
21 | # handler |
---|
22 | my $dbh = setup_dbh(); |
---|
23 | |
---|
24 | my @fields = qw(easting northing postcode1 postcode2); |
---|
25 | my $returnBaseURL = ''; |
---|
26 | |
---|
27 | my $googleAnalytics = <<"HERE"; |
---|
28 | <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> |
---|
29 | </script> |
---|
30 | <script type="text/javascript"> |
---|
31 | _uacct = "UA-732621-2"; |
---|
32 | if (typeof urchinTracker == 'function') urchinTracker(); |
---|
33 | </script> |
---|
34 | HERE |
---|
35 | my $cgi; |
---|
36 | # Process incoming requests |
---|
37 | REQUEST: while ($cgi = new CGI::Fast) { |
---|
38 | |
---|
39 | my $returnlink = ''; |
---|
40 | |
---|
41 | |
---|
42 | |
---|
43 | # In case the database went away, make sure we have a connection |
---|
44 | unless ($dbh = setup_dbh()) { |
---|
45 | print_html_err('Error setting up database connection', $returnlink); |
---|
46 | next REQUEST; |
---|
47 | } |
---|
48 | |
---|
49 | my ($easting, $northing); |
---|
50 | |
---|
51 | # Input validation |
---|
52 | foreach my $field (@fields) { |
---|
53 | unless (defined $cgi->param($field)) { |
---|
54 | print_html_err ("Parameter '$field' missing", $returnlink); |
---|
55 | next REQUEST; |
---|
56 | } |
---|
57 | } |
---|
58 | |
---|
59 | # Is the Easting in a valid range? |
---|
60 | if (($cgi->param('easting') > 700000) or |
---|
61 | ($cgi->param('easting') < 0)) { |
---|
62 | print_html_err ("Parameter 'easting' must be an integer between 0 and 700,000", $returnlink); |
---|
63 | next REQUEST; |
---|
64 | } else { |
---|
65 | $easting = $cgi->param('easting'); |
---|
66 | } |
---|
67 | |
---|
68 | # Is the Northing in a valid range? |
---|
69 | if (($cgi->param('northing') > 1300000) or |
---|
70 | ($cgi->param('northing') < 0)) { |
---|
71 | print_html_err("Parameter 'northing' must be an integer between 0 and 1,300,000", $returnlink); |
---|
72 | next REQUEST; |
---|
73 | } else { |
---|
74 | $northing = $cgi->param('northing'); |
---|
75 | } |
---|
76 | |
---|
77 | my $sth; |
---|
78 | |
---|
79 | # Now validate the postcode input format |
---|
80 | my ($trimmed_1, $trimmed_2) = ($cgi->param('postcode1'), $cgi->param('postcode2')); |
---|
81 | $trimmed_1 =~ s/^\s+//; |
---|
82 | $trimmed_2 =~ s/^\s+//; |
---|
83 | $trimmed_1 =~ s/\s+$//; |
---|
84 | $trimmed_2 =~ s/\s+$//; |
---|
85 | my $raw_postcode = $trimmed_1; |
---|
86 | $raw_postcode .= ' ' . $trimmed_2 if defined $trimmed_2; |
---|
87 | |
---|
88 | unless ((length($trimmed_2)) == 1 or (length($trimmed_2) == 0) or (length($trimmed_2) == 3) or (!defined $trimmed_2)) { |
---|
89 | print_html_err("The postcode format is not valid", $returnlink); |
---|
90 | next REQUEST; |
---|
91 | } |
---|
92 | |
---|
93 | my $postcode = Geo::Postcode->new($raw_postcode); |
---|
94 | my ($first, $second, $third, $fourth) = @{$postcode->fragments}; |
---|
95 | my ($outward, $inward); |
---|
96 | |
---|
97 | if ($postcode->valid) { |
---|
98 | # We have a complete postcode; input it straight into the database |
---|
99 | $outward = $first . $second; |
---|
100 | $inward = $third . $fourth; |
---|
101 | } elsif($postcode->valid_fragment) { |
---|
102 | # We have a valid fragment; let's build up what we can |
---|
103 | # We are guaranteed to have the first two |
---|
104 | $outward = $first . $second; |
---|
105 | $inward = ''; |
---|
106 | $inward .= $third if defined $third; |
---|
107 | $inward .= $fourth if defined $fourth; |
---|
108 | } else { |
---|
109 | print_html_err("The postcode format is not valid", $returnlink); |
---|
110 | next REQUEST; |
---|
111 | } |
---|
112 | |
---|
113 | # Check for a duplicate. |
---|
114 | # We want to collect duplicates from different IP addresses as a kind of |
---|
115 | # corroboration factor; this just catches accidental double-submission |
---|
116 | # really. |
---|
117 | $sth = $dbh->prepare('SELECT raw_postcode_outward FROM postcodes WHERE raw_postcode_outward = ? AND raw_postcode_inward = ? AND easting = ? AND northing = ? AND ip = ? AND NOT deleted'); |
---|
118 | unless ($sth->execute($cgi->param('postcode1'), $cgi->param('postcode2'), $easting, $northing, $ENV{'REMOTE_ADDR'})) { |
---|
119 | print_html_err('Database error when checking for duplicate data :(', $returnlink); |
---|
120 | next REQUEST; |
---|
121 | } |
---|
122 | |
---|
123 | if ($sth->rows) { |
---|
124 | print_html_err('You, or someone with the same IP address, have already submitted this postcode with these co-ordinates.', $returnlink); |
---|
125 | next REQUEST; |
---|
126 | } |
---|
127 | |
---|
128 | $sth = $dbh->prepare('INSERT INTO postcodes (outward, inward, raw_postcode_outward, raw_postcode_inward, easting, northing, ip, source, user_agent) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?)'); |
---|
129 | if ($sth->execute($outward, $inward, $cgi->param('postcode1'), $cgi->param('postcode2'), $easting, $northing, $ENV{'REMOTE_ADDR'}, $ENV{'HTTP_USER_AGENT'})) { |
---|
130 | print "Content-type: text/html\n\n"; |
---|
131 | print "<p>Thank you for telling us where your post code is!</p>\n"; |
---|
132 | # Any extra actions |
---|
133 | build_home_stats($dbh); |
---|
134 | next REQUEST; |
---|
135 | } else { |
---|
136 | print STDERR "DB error: " . $dbh->errstr . "\n"; |
---|
137 | print_html_err("Database error when adding your data :(", $returnlink); |
---|
138 | next REQUEST; |
---|
139 | } |
---|
140 | |
---|
141 | # WE NEVER GET HERE |
---|
142 | |
---|
143 | } |
---|
144 | |
---|
145 | # No more requests to serve, so tidy up |
---|
146 | $dbh->disconnect; |
---|