aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/httpd.conf24
-rw-r--r--perllib/FixMyStreet/Alert.pm45
-rw-r--r--perllib/FixMyStreet/App/Controller/Location.pm4
-rw-r--r--perllib/FixMyStreet/App/Controller/Reports.pm133
-rwxr-xr-xperllib/FixMyStreet/App/Controller/Rss.pm211
-rwxr-xr-xweb/rss.cgi169
6 files changed, 315 insertions, 271 deletions
diff --git a/conf/httpd.conf b/conf/httpd.conf
index d9e6c470d..d2902e4cd 100644
--- a/conf/httpd.conf
+++ b/conf/httpd.conf
@@ -56,18 +56,18 @@ RewriteRule ^/[Ff]/([0-9A-Za-z]{16,18}).*$ /flickr.cgi?token=$1 [L
RewriteRule ^/[Tt]/([0-9A-Za-z]{16,18}).*$ /tms-signup.cgi?token=$1 [L]
# RSS feeds for updates on a problem
-RewriteRule ^/rss/([0-9]+)$ /rss.cgi?type=new_updates;id=$1 [QSA,L]
+#RewriteRule ^/rss/([0-9]+)$ /rss.cgi?type=new_updates;id=$1 [QSA,L]
# RSS feeds for new local problems
-RewriteRule ^/rss/([0-9]+)[,/]([0-9]+)$ /rss.cgi?type=local_problems;x=$1;y=$2 [QSA,L]
-RewriteRule ^/rss/n/([0-9]+)[,/]([0-9]+)$ /rss.cgi?type=local_problems;e=$1;n=$2 [QSA,L]
-RewriteRule ^/rss/l/([0-9.-]+)[,/]([0-9.-]+)$ /rss.cgi?type=local_problems;lat=$1;lon=$2 [QSA,L]
-RewriteRule ^/rss/([0-9]+)[,/]([0-9]+)/([0-9]+)$ /rss.cgi?type=local_problems;x=$1;y=$2;d=$3 [QSA,L]
-RewriteRule ^/rss/n/([0-9]+)[,/]([0-9]+)/([0-9]+)$ /rss.cgi?type=local_problems;e=$1;n=$2;d=$3 [QSA,L]
-RewriteRule ^/rss/l/([0-9.-]+)[,/]([0-9.-]+)/([0-9]+)$ /rss.cgi?type=local_problems;lat=$1;lon=$2;d=$3 [QSA,L]
-RewriteRule ^/rss/pc/(.*)/([0-9]+)$ /rss.cgi?type=local_problems;pc=$1;d=$2 [QSA,L]
-RewriteRule ^/rss/pc/(.*)$ /rss.cgi?type=local_problems;pc=$1 [QSA,L]
-RewriteRule ^/rss/problems$ /rss.cgi?type=new_problems [QSA,L]
+#RewriteRule ^/rss/([0-9]+)[,/]([0-9]+)$ /rss.cgi?type=local_problems;x=$1;y=$2 [QSA,L]
+#RewriteRule ^/rss/n/([0-9]+)[,/]([0-9]+)$ /rss.cgi?type=local_problems;e=$1;n=$2 [QSA,L]
+#RewriteRule ^/rss/l/([0-9.-]+)[,/]([0-9.-]+)$ /rss.cgi?type=local_problems;lat=$1;lon=$2 [QSA,L]
+#RewriteRule ^/rss/([0-9]+)[,/]([0-9]+)/([0-9]+)$ /rss.cgi?type=local_problems;x=$1;y=$2;d=$3 [QSA,L]
+#RewriteRule ^/rss/n/([0-9]+)[,/]([0-9]+)/([0-9]+)$ /rss.cgi?type=local_problems;e=$1;n=$2;d=$3 [QSA,L]
+#RewriteRule ^/rss/l/([0-9.-]+)[,/]([0-9.-]+)/([0-9]+)$ /rss.cgi?type=local_problems;lat=$1;lon=$2;d=$3 [QSA,L]
+#RewriteRule ^/rss/pc/(.*)/([0-9]+)$ /rss.cgi?type=local_problems;pc=$1;d=$2 [QSA,L]
+#RewriteRule ^/rss/pc/(.*)$ /rss.cgi?type=local_problems;pc=$1 [QSA,L]
+#RewriteRule ^/rss/problems$ /rss.cgi?type=new_problems [QSA,L]
# RSS feeds for voting areas
RewriteRule ^/rss/council/([0-9]+)$ /rss/reports/$1 [R=permanent,L]
@@ -76,7 +76,7 @@ RewriteRule ^/report$ /reports
#RewriteRule ^/reports/([^/]+)/([^/]+)$ /reports.cgi?council=$1;ward=$2 [QSA,L]
#RewriteRule ^/rss/(reports|area)/([^/]+)/([^/]+)$ /reports.cgi?rss=$1;council=$2;ward=$3 [QSA,L]
#RewriteRule ^/reports/([^/]+)$ /reports.cgi?council=$1 [QSA,L]
-RewriteRule ^/rss/area/([0-9]+)$ /rss.cgi?type=area_problems;id=$1 [QSA,L]
+#RewriteRule ^/rss/area/([0-9]+)$ /rss.cgi?type=area_problems;id=$1 [QSA,L]
#RewriteRule ^/rss/(reports|area)/([^/]+)$ /reports.cgi?rss=$1;council=$2 [QSA,L]
# Fix incorrect RSS urls caused by my stupidity
@@ -114,7 +114,7 @@ RewriteRule ^/json(.*) /json.cgi$1 [L]
RewriteRule ^/photo(.*) /photo.cgi$1 [L]
RewriteRule ^/questionnaire(.*) /questionnaire.cgi$1 [L]
# RewriteRule ^/reports(.*) /reports.cgi$1 [L]
-RewriteRule ^/rss(.*) /rss.cgi$1 [L]
+# RewriteRule ^/rss(.*) /rss.cgi$1 [L]
RewriteRule ^/test(.*) /test.cgi$1 [L]
RewriteRule ^/tms-signup(.*) /tms-signup.cgi$1 [L]
RewriteRule ^/upload(.*) /upload.cgi$1 [L]
diff --git a/perllib/FixMyStreet/Alert.pm b/perllib/FixMyStreet/Alert.pm
index 15981acc5..bf6a6c5d4 100644
--- a/perllib/FixMyStreet/Alert.pm
+++ b/perllib/FixMyStreet/Alert.pm
@@ -241,20 +241,21 @@ sub _send_aggregated_alert_email(%) {
}
}
-sub generate_rss ($$$;$$$$) {
- my ($type, $xsl, $qs, $db_params, $title_params, $cobrand, $http_q) = @_;
- $db_params ||= [];
- my $url = Cobrand::base_url($cobrand);
- my $cobrand_data = Cobrand::extra_data($cobrand, $http_q);
+sub generate_rss ($) {
+ my $c = shift;
+ my $type = $c->stash->{type};
+ $c->stash->{qs} ||= '';
+ $c->stash->{db_params} ||= [];
+ my $cobrand_data = $c->cobrand->extra_data;
my $q = dbh()->prepare('select * from alert_type where ref=?');
$q->execute($type);
my $alert_type = $q->fetchrow_hashref;
- my ($site_restriction, $site_id) = Cobrand::site_restriction($cobrand, $cobrand_data);
+ my ($site_restriction, $site_id) = $c->cobrand->site_restriction($cobrand_data);
throw FixMyStreet::Alert::Error('Unknown alert type') unless $alert_type;
# Do our own encoding
my $rss = new XML::RSS( version => '2.0', encoding => 'UTF-8',
- stylesheet=> $xsl, encode_output => undef );
+ stylesheet=> $c->cobrand->feed_xsl, encode_output => undef );
$rss->add_module(prefix=>'georss', uri=>'http://www.georss.org/georss');
# Only apply a site restriction if the alert uses the problem table
@@ -267,8 +268,8 @@ sub generate_rss ($$$;$$$$) {
$query .= " limit $rss_limit" unless $type =~ /^all/;
$q = dbh()->prepare($query);
if ($query =~ /\?/) {
- throw FixMyStreet::Alert::Error('Missing parameter') unless @$db_params;
- $q->execute(@$db_params);
+ throw FixMyStreet::Alert::Error('Missing parameter') unless @{ $c->stash->{db_params} };
+ $q->execute( @{ $c->stash->{db_params} } );
} else {
$q->execute();
}
@@ -291,22 +292,22 @@ sub generate_rss ($$$;$$$$) {
(my $title = _($alert_type->{item_title})) =~ s/{{(.*?)}}/$row->{$1}/g;
(my $link = $alert_type->{item_link}) =~ s/{{(.*?)}}/$row->{$1}/g;
(my $desc = _($alert_type->{item_description})) =~ s/{{(.*?)}}/$row->{$1}/g;
- my $cobrand_url = Cobrand::url($cobrand, $url . $link, $http_q);
+ my $url = $c->uri_for( $link );
my %item = (
title => ent($title),
- link => $cobrand_url,
- guid => $cobrand_url,
+ link => $url,
+ guid => $url,
description => ent(ent($desc)) # Yes, double-encoded, really.
);
$item{pubDate} = $pubDate if $pubDate;
$item{category} = $row->{category} if $row->{category};
- my $display_photos = Cobrand::allow_photo_display($cobrand);
+ my $display_photos = $c->cobrand->allow_photo_display;
if ($display_photos && $row->{photo}) {
- $item{description} .= ent("\n<br><img src=\"". Cobrand::url($cobrand, $url, $http_q) . "/photo?id=$row->{id}\">");
+ $item{description} .= ent("\n<br><img src=\"". $c->uri_for( $c->cobrand->base_url ) . "/photo?id=$row->{id}\">");
}
- my $recipient_name = Cobrand::contact_name($cobrand);
- $item{description} .= ent("\n<br><a href='$cobrand_url'>" .
+ my $recipient_name = $c->cobrand->contact_name;
+ $item{description} .= ent("\n<br><a href='$url'>" .
sprintf(_("Report on %s"), $recipient_name) . "</a>");
if ($row->{latitude} || $row->{longitude}) {
@@ -319,26 +320,26 @@ sub generate_rss ($$$;$$$$) {
if ($alert_type->{head_sql_query}) {
$q = dbh()->prepare($alert_type->{head_sql_query});
if ($alert_type->{head_sql_query} =~ /\?/) {
- $q->execute(@$db_params);
+ $q->execute(@{ $c->stash->{db_params} });
} else {
$q->execute();
}
$row = $q->fetchrow_hashref;
}
- foreach (keys %$title_params) {
- $row->{$_} = $title_params->{$_};
+ foreach ( keys %{ $c->stash->{title_params} } ) {
+ $row->{$_} = $c->stash->{title_params}->{$_};
}
(my $title = _($alert_type->{head_title})) =~ s/{{(.*?)}}/$row->{$1}/g;
(my $link = $alert_type->{head_link}) =~ s/{{(.*?)}}/$row->{$1}/g;
(my $desc = _($alert_type->{head_description})) =~ s/{{(.*?)}}/$row->{$1}/g;
$rss->channel(
- title => ent($title), link => "$url$link$qs", description => ent($desc),
+ title => ent($title), link => $link . $c->stash->{qs}, description => ent($desc),
language => 'en-gb'
);
my $out = $rss->as_string;
- my $uri = Cobrand::url($cobrand, $ENV{SCRIPT_URI}, $http_q);
- $out =~ s{<link>(.*?)</link>}{"<link>" . Cobrand::url($cobrand, $1, $http_q) . "</link><uri>$uri</uri>"}e;
+ my $uri = $c->uri_for( '/' . $c->req->path );
+ $out =~ s{<link>(.*?)</link>}{"<link>" . $c->uri_for( $1 ) . "</link><uri>$uri</uri>"}e;
return $out;
}
diff --git a/perllib/FixMyStreet/App/Controller/Location.pm b/perllib/FixMyStreet/App/Controller/Location.pm
index 7be8eaa0c..76f54e7b3 100644
--- a/perllib/FixMyStreet/App/Controller/Location.pm
+++ b/perllib/FixMyStreet/App/Controller/Location.pm
@@ -58,10 +58,10 @@ If no matches are found returns false.
=cut
sub determine_location_from_pc : Private {
- my ( $self, $c ) = @_;
+ my ( $self, $c, $pc ) = @_;
# check for something to search
- my $pc = $c->req->param('pc') || return;
+ $pc ||= $c->req->param('pc') || return;
$c->stash->{pc} = $pc; # for template
my ( $latitude, $longitude, $error ) =
diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm
index 228d4dd60..43106331b 100644
--- a/perllib/FixMyStreet/App/Controller/Reports.pm
+++ b/perllib/FixMyStreet/App/Controller/Reports.pm
@@ -64,15 +64,7 @@ Show the summary page for a particular council.
sub council : Path : Args(1) {
my ( $self, $c, $council ) = @_;
-
- $c->forward( 'council_check', [ $council ] );
- $c->forward( 'load_parent' );
- $c->forward( 'load_problems' );
- $c->forward( 'group_problems' );
- $c->forward( 'sort_problems' );
-
- $c->stash->{rss_url} = '/rss/reports/'
- . $c->cobrand->short_name( $c->stash->{council}, $c->stash->{areas_info} );
+ $c->detach( 'ward', [ $council ] );
}
=head2 index
@@ -85,29 +77,75 @@ sub ward : Path : Args(2) {
my ( $self, $c, $council, $ward ) = @_;
$c->forward( 'council_check', [ $council ] );
- $c->forward( 'ward_check', [ $ward ] );
+ $c->forward( 'ward_check', [ $ward ] )
+ if $ward;
$c->forward( 'load_parent' );
$c->forward( 'load_problems' );
$c->forward( 'group_problems' );
$c->forward( 'sort_problems' );
$c->stash->{rss_url} = '/rss/reports/'
- . $c->cobrand->short_name( $c->stash->{council}, $c->stash->{areas_info} )
- . '/' . $c->cobrand->short_name( $c->stash->{ward} );
+ . $c->cobrand->short_name( $c->stash->{council}, $c->stash->{areas_info} );
+ $c->stash->{rss_url} .= '/' . $c->cobrand->short_name( $c->stash->{ward} )
+ if $c->stash->{ward};
+}
+
+sub rss_council : Regex('^rss/(reports|area)$') : Args(1) {
+ my ( $self, $c, $council ) = @_;
+ $c->detach( 'rss_ward', [ $council ] );
}
-#sub rss_ward : RegEx('/rss/(reports|area)') : Args(2) {
-# my ( $self, $c, $council, $ward ) = @_;
-#
-# $c->stash->{q_council} = $council;
-# $c->stash->{q_ward} = $ward;
-#
-#}
-#
-#sub rss_council : RegEx('/rss/(reports|area)') : Args(1) {
-# my ( $self, $c, $council ) = @_;
-# $c->stash->{rss} = $c->req->{rss};
-#}
+sub rss_ward : Regex('^rss/(reports|area)$') : Args(2) {
+ my ( $self, $c, $council, $ward ) = @_;
+
+ my ( $rss ) = $c->req->captures->[0];
+
+ $c->stash->{rss} = 1;
+
+ $c->forward( 'council_check', [ $council ] );
+ $c->forward( 'ward_check', [ $ward ] ) if $ward;
+
+ if ($rss eq 'area' && $c->stash->{council}{type} ne 'DIS' && $c->stash->{council}{type} ne 'CTY') {
+ # Two possibilites are the same for one-tier councils, so redirect one to the other
+ $c->detach( 'redirect_area' );
+ }
+
+ my $url = $c->cobrand->short_name( $c->stash->{council} );
+ $url .= '/' . $c->cobrand->short_name( $c->stash->{ward} ) if $c->stash->{ward};
+ $c->stash->{qs} = "/$url";
+
+ my @params;
+ push @params, $c->stash->{council}->{id} if $rss eq 'reports';
+ push @params, $c->stash->{ward}
+ ? $c->stash->{ward}->{id}
+ : $c->stash->{council}->{id};
+ $c->stash->{db_params} = [ @params ];
+
+ if ( $rss eq 'area' && $c->stash->{ward} ) {
+ # All problems within a particular ward
+ $c->stash->{type} = 'area_problems';
+ $c->stash->{title_params} = { NAME => $c->stash->{ward}{name} };
+ $c->stash->{db_params} = [ $c->stash->{ward}->{id} ];
+ } elsif ( $rss eq 'area' ) {
+ # Problems within a particular council
+ $c->stash->{type} = 'area_problems';
+ $c->stash->{title_params} = { NAME => $c->stash->{council}{name} };
+ $c->stash->{db_params} = [ $c->stash->{council}->{id} ];
+ } elsif ($c->stash->{ward}) {
+ # Problems sent to a council, restricted to a ward
+ $c->stash->{type} = 'ward_problems';
+ $c->stash->{title_params} = { COUNCIL => $c->stash->{council}{name}, WARD => $c->stash->{ward}{name} };
+ $c->stash->{db_params} = [ $c->stash->{council}->{id}, $c->stash->{ward}->{id} ];
+ } else {
+ # Problems sent to a council
+ $c->stash->{type} = 'council_problems';
+ $c->stash->{title_params} = { COUNCIL => $c->stash->{council}{name} };
+ $c->stash->{db_params} = [ $c->stash->{council}->{id}, $c->stash->{council}->{id} ];
+ }
+
+ # Send on to the RSS generation
+ $c->forward( '/rss/output' );
+}
=head2 council_check
@@ -139,7 +177,7 @@ sub council_check : Private {
my $council = mySociety::MaPit::call('area', $q_council);
$c->detach( 'redirect_index') if $council->{error};
$c->stash->{council} = $council;
- $c->detach( 'redirect_council' );
+ $c->detach( 'redirect_area' );
}
# We must now have a string to check
@@ -190,7 +228,7 @@ sub ward_check : Private {
}
}
# Given a false ward name
- $c->detach( 'redirect_council' );
+ $c->detach( 'redirect_area' );
}
sub load_parent : Private {
@@ -283,22 +321,14 @@ sub redirect_index : Private {
$c->res->redirect( $c->uri_for($url) );
}
-sub redirect_council : Private {
+sub redirect_area : Private {
my ( $self, $c ) = @_;
my $url = '';
$url .= "/rss" if $c->stash->{rss};
$url .= '/reports';
$url .= '/' . $c->cobrand->short_name( $c->stash->{council} );
- $c->res->redirect( $c->uri_for($url) );
-}
-
-sub redirect_ward : Private {
- my ( $self, $c ) = @_;
- my $url = '';
- $url .= "/rss" if $c->stash->{rss};
- $url .= '/reports';
- $url .= '/' . $c->cobrand->short_name( $c->stash->{council} );
- $url .= '/' . $c->cobrand->short_name( $c->stash->{ward} );
+ $url .= '/' . $c->cobrand->short_name( $c->stash->{ward} )
+ if $c->stash->{ward};
$c->res->redirect( $c->uri_for($url) );
}
@@ -330,32 +360,3 @@ __PACKAGE__->meta->make_immutable;
1;
-# # RSS - reports for sent reports, area for all problems in area
-# if ($rss && $council) {
-# my $url = Page::short_name($council);
-# $url .= '/' . Page::short_name($ward) if $ward;
-# if ($rss eq 'area' && $area_type ne 'DIS' && $area_type ne 'CTY') {
-# # Two possibilites are the same for one-tier councils, so redirect one to the other
-# print $q->redirect($base_url . '/rss/reports/' . $url);
-# return;
-# }
-# my $type = 'council_problems'; # Problems sent to a council
-# my (@params, %title_params);
-# $title_params{COUNCIL} = $area_name;
-# push @params, $council->{id} if $rss eq 'reports';
-# push @params, $ward ? $ward->{id} : $council->{id};
-# if ($ward && $rss eq 'reports') {
-# $type = 'ward_problems'; # Problems sent to a council, restricted to a ward
-# $title_params{WARD} = $q_ward;
-# } elsif ($rss eq 'area') {
-# $title_params{NAME} = $ward ? $q_ward : $q_council;
-# $type = 'area_problems'; # Problems within an area
-# }
-# print $q->header( -type => 'application/xml; charset=utf-8' );
-# my $xsl = Cobrand::feed_xsl($cobrand);
-# my $out = FixMyStreet::Alert::generate_rss($type, $xsl, "/$url", \@params, \%title_params, $cobrand, $q);
-# $out =~ s/matthew.fixmystreet/emptyhomes.matthew.fixmystreet/g if $q->{site} eq 'emptyhomes';
-# print $out;
-# return;
-# }
-
diff --git a/perllib/FixMyStreet/App/Controller/Rss.pm b/perllib/FixMyStreet/App/Controller/Rss.pm
new file mode 100755
index 000000000..fa9e3a4de
--- /dev/null
+++ b/perllib/FixMyStreet/App/Controller/Rss.pm
@@ -0,0 +1,211 @@
+package FixMyStreet::App::Controller::Rss;
+
+use Moose;
+use namespace::autoclean;
+use URI::Escape;
+use FixMyStreet::Alert;
+use mySociety::Gaze;
+use mySociety::Locale;
+use mySociety::MaPit;
+
+BEGIN { extends 'Catalyst::Controller'; }
+
+=head1 NAME
+
+FixMyStreet::App::Controller::Rss - Catalyst Controller
+
+=head1 DESCRIPTION
+
+Catalyst Controller.
+
+=head1 METHODS
+
+=cut
+
+sub updates : LocalRegex('^(\d+)$') {
+ my ( $self, $c ) = @_;
+
+ my $id = $c->req->captures->[0];
+ my $problem = $c->model('DB::Problem')->find( { id => $id } );
+
+ # FIXME Put these 404/410 checks in central place - Report.pm does it too.
+ if ( !$problem || $problem->state eq 'unconfirmed' ) {
+ $c->detach( '/page_error_404_not_found', [ _('Unknown problem ID') ] );
+ } elsif ( $problem->state eq 'hidden' ) {
+ $c->detach(
+ '/page_error_410_gone',
+ [ _('That report has been removed from FixMyStreet.') ]
+ );
+ }
+
+ $c->stash->{type} = 'new_updates';
+ $c->stash->{qs} = 'report/' . $id;
+ $c->stash->{db_params} = [ $id ];
+ $c->forward('output');
+}
+
+sub new_problems : Path('problems') : Args(0) {
+ my ( $self, $c ) = @_;
+
+ $c->stash->{type} = 'new_problems';
+ $c->forward('output');
+}
+
+# FIXME I don't think this is used - check
+#sub reports_to_council : Private {
+# my ( $self, $c ) = @_;
+#
+# my $id = $c->stash->{id};
+# $c->stash->{type} = 'council_problems';
+# $c->stash->{qs} = '/' . $id;
+# $c->stash->{db_params} = [ $id ];
+# $c->forward('output');
+#}
+
+sub reports_in_area : LocalRegex('^area/(\d+)$') {
+ my ( $self, $c ) = @_;
+
+ my $id = $c->req->captures->[0];
+ my $area = mySociety::MaPit::call('area', $id);
+ $c->stash->{type} = 'area_problems';
+ $c->stash->{qs} = '/' . $id;
+ $c->stash->{db_params} = [ $id ];
+ $c->stash->{title_params} = { NAME => $area->{name} };
+ $c->forward('output');
+}
+
+sub all_problems : Private {
+ my ( $self, $c ) = @_;
+
+ $c->stash->{type} = 'all_problems';
+ $c->forward('output');
+}
+
+sub local_problems_pc : Path('pc') : Args(1) {
+ my ( $self, $c, $query ) = @_;
+ $c->forward( 'local_problems_pc_distance', [ $query ] );
+}
+
+sub local_problems_pc_distance : Path('pc') : Args(2) {
+ my ( $self, $c, $query, $d ) = @_;
+
+ $c->forward( 'get_query_parameters', [ $d ] );
+ unless ( $c->forward( '/location/determine_location_from_pc', [ $query ] ) ) {
+ $c->res->redirect( '/alert' );
+ $c->detach();
+ }
+
+ my $pretty_query = $query;
+ $pretty_query = mySociety::PostcodeUtil::canonicalise_postcode($query)
+ if mySociety::PostcodeUtil::is_valid_postcode($query);
+
+ my $pretty_query_escaped = URI::Escape::uri_escape_utf8($pretty_query);
+ $pretty_query_escaped =~ s/%20/+/g;
+
+ $c->stash->{qs} = "?pc=$pretty_query_escaped";
+ $c->stash->{title_params} = { POSTCODE => $pretty_query };
+ $c->stash->{type} = 'postcode_local_problems';
+
+ $c->forward( 'local_problems_ll',
+ [ $c->stash->{latitude}, $c->stash->{longitude} ]
+ );
+
+}
+
+sub local_problems : LocalRegex('^(n|l)/([\d.-]+)[,/]([\d.-]+)(?:/(\d+))?$') {
+ my ( $self, $c ) = @_;
+
+ my ( $type, $a, $b, $d) = @{ $c->req->captures };
+ $c->forward( 'get_query_parameters', [ $d ] );
+
+ $c->detach( 'redirect_lat_lon', [ $a, $b ] )
+ if $type eq 'n';
+
+ $c->stash->{qs} = "?lat=$a;lon=$b";
+ $c->stash->{type} = 'local_problems';
+
+ $c->forward( 'local_problems_ll', [ $a, $b ] );
+}
+
+sub local_problems_ll : Private {
+ my ( $self, $c, $lat, $lon ) = @_;
+
+ # truncate the lat,lon for nicer urls
+ ( $lat, $lon ) = map { Utils::truncate_coordinate($_) } ( $lat, $lon );
+
+ my $d = $c->stash->{distance};
+ if ( $d ) {
+ $c->stash->{qs} .= ";d=$d";
+ $d = 100 if $d > 100;
+ } else {
+ $d = mySociety::Gaze::get_radius_containing_population( $lat, $lon, 200000 );
+ $d = int( $d * 10 + 0.5 ) / 10;
+ mySociety::Locale::in_gb_locale {
+ $d = sprintf("%f", $d);
+ }
+ }
+
+ $c->stash->{db_params} = [ $lat, $lon, $d ];
+
+ if ($c->stash->{state} ne 'all') {
+ $c->stash->{type} .= '_state';
+ push @{ $c->stash->{db_params} }, $c->stash->{state};
+ }
+
+ $c->forward('output');
+}
+
+sub output : Private {
+ my ( $self, $c ) = @_;
+ $c->response->header('Content-Type' => 'application/xml; charset=utf-8');
+ $c->response->body( FixMyStreet::Alert::generate_rss( $c ) );
+}
+
+sub local_problems_legacy : LocalRegex('^(\d+)[,/](\d+)(?:/(\d+))?$') {
+ my ( $self, $c ) = @_;
+ my ($x, $y, $d) = @{ $c->req->captures };
+ $c->forward( 'get_query_parameters', [ $d ] );
+
+ # 5000/31 as initial scale factor for these RSS feeds, now variable so redirect.
+ my $e = int( ($x * 5000/31) + 0.5 );
+ my $n = int( ($y * 5000/31) + 0.5 );
+ $c->detach( 'redirect_lat_lon', [ $e, $n ] );
+}
+
+sub get_query_parameters : Private {
+ my ( $self, $c, $d ) = @_;
+
+ $d = '' unless $d =~ /^\d+$/;
+ $c->stash->{distance} = $d;
+
+ my $state = $c->req->param('state') || 'all';
+ $state = 'all' unless $state =~ /^(all|open|fixed)$/;
+ $c->stash->{state_qs} = "?state=$state" unless $state eq 'all';
+
+ $state = 'confirmed' if $state eq 'open';
+ $c->stash->{state} = $state;
+}
+
+sub redirect_lat_lon : Private {
+ my ( $self, $c, $e, $n ) = @_;
+ my ($lat, $lon) = Utils::convert_en_to_latlon_truncated($e, $n);
+
+ my $d_str = '';
+ $d_str = '/' . $c->stash->{distance} if $c->stash->{distance};
+ $c->res->redirect( "/rss/l/$lat,$lon" . $d_str . $c->stash->{state_qs} );
+}
+
+=head1 AUTHOR
+
+Matthew Somerville
+
+=head1 LICENSE
+
+Copyright (c) 2011 UK Citizens Online Democracy. All rights reserved.
+Licensed under the Affero GPL.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;
diff --git a/web/rss.cgi b/web/rss.cgi
deleted file mode 100755
index 1570ca97f..000000000
--- a/web/rss.cgi
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/perl -w -I../perllib
-
-# rss.cgi:
-# RSS for FixMyStreet
-#
-# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
-# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
-#
-# $Id: rss.cgi,v 1.38 2009-12-17 15:15:21 louise Exp $
-
-use strict;
-use Error qw(:try);
-use Standard;
-use Encode;
-use URI::Escape;
-use FixMyStreet::Alert;
-use FixMyStreet::Geocode;
-use mySociety::Locale;
-use mySociety::MaPit;
-use mySociety::Gaze;
-use Utils;
-
-sub main {
- my $q = shift;
- my $type = $q->param('type') || '';
- my $cobrand = Page::get_cobrand($q);
- my $xsl = Cobrand::feed_xsl($cobrand);
- my $out;
- if ($type eq 'local_problems') {
- $out = rss_local_problems($q);
- return unless $out;
- } elsif ($type eq 'new_updates') {
- my $id = $q->param('id');
- my $problem = Problems::fetch_problem($id);
- if (!$problem) {
- print $q->header(-status=>'404 Not Found',-type=>'text/html');
- return;
- }
- my $qs = 'report/' . $id;
- $out = FixMyStreet::Alert::generate_rss($type, $xsl, $qs, [$id], undef, $cobrand, $q);
- } elsif ($type eq 'new_problems' || $type eq 'new_fixed_problems') {
- $out = FixMyStreet::Alert::generate_rss($type, $xsl, '', undef, undef, $cobrand, $q);
- } elsif ($type eq 'council_problems') {
- my $id = $q->param('id');
- my $qs = '/'.$id;
- $out = FixMyStreet::Alert::generate_rss($type, $xsl, $qs, [$id], undef, $cobrand. $q);
- } elsif ($type eq 'area_problems') {
- my $id = $q->param('id');
- my $va_info = mySociety::MaPit::call('area', $id);
- my $qs = '/'.$id;
- $out = FixMyStreet::Alert::generate_rss($type, $xsl, $qs, [$id], { NAME => $va_info->{name} }, $cobrand, $q);
- } elsif ($type eq 'all_problems') {
- $out = FixMyStreet::Alert::generate_rss($type, $xsl, '', undef, undef, $cobrand, $q);
- } else {
- my $base = mySociety::Config::get('BASE_URL');
- print $q->redirect($base . '/alert');
- return '';
- }
- print $q->header( -type => 'application/xml; charset=utf-8' );
- print $out;
-}
-Page::do_fastcgi(\&main);
-
-sub rss_local_problems {
- my $q = shift;
- my $pc = $q->param('pc');
-
- my $x = $q->param('x');
- my $y = $q->param('y');
- my $lat = $q->param('lat');
- my $lon = $q->param('lon');
- my $e = $q->param('e');
- my $n = $q->param('n');
- my $d = $q->param('d') || '';
- $d = '' unless $d =~ /^\d+$/;
- my $d_str = '';
- $d_str = "/$d" if $d;
- my $state = $q->param('state') || 'all';
- $state = 'all' unless $state =~ /^(all|open|fixed)$/;
-
- # state is getting lost in the redirects. Add it on to the end as a query
- my $state_qs = '';
- $state_qs = "?state=$state" unless $state eq 'all';
-
- $state = 'confirmed' if $state eq 'open';
-
- my $qs;
- my %title_params;
- my $alert_type;
-
- my $cobrand = Page::get_cobrand($q);
- my $base = Cobrand::base_url($cobrand);
- if ($x && $y) {
- # 5000/31 as initial scale factor for these RSS feeds, now variable so redirect.
- $e = int( ($x * 5000/31) + 0.5 );
- $n = int( ($y * 5000/31) + 0.5 );
- ($lat, $lon) = Utils::convert_en_to_latlon_truncated($e, $n);
- print $q->redirect(-location => "$base/rss/l/$lat,$lon$d_str$state_qs");
- return '';
- } elsif ($e && $n) {
- ($lat, $lon) = Utils::convert_en_to_latlon_truncated($e, $n);
- print $q->redirect(-location => "$base/rss/l/$lat,$lon$d_str$state_qs");
- return '';
- } elsif ($pc) {
- my $error;
- try {
- ($lat, $lon, $error) = FixMyStreet::Geocode::lookup($pc, $q);
- } catch Error::Simple with {
- $error = shift;
- };
- if ($error) {
- print $q->redirect(-location => "$base/alert");
- return '';
- } else {
- ( $lat, $lon ) = map { Utils::truncate_coordinate($_) } ( $lat, $lon );
-
- my $pretty_pc = $pc;
- if (mySociety::PostcodeUtil::is_valid_postcode($pc)) {
- $pretty_pc = mySociety::PostcodeUtil::canonicalise_postcode($pc);
- }
- my $pretty_pc_escaped = URI::Escape::uri_escape_utf8($pretty_pc);
- $pretty_pc_escaped =~ s/%20/+/g;
- $qs = "?pc=$pretty_pc_escaped";
-
- $title_params{'POSTCODE'} = $pretty_pc;
- }
- # pass through rather than redirecting.
- } elsif ( $lat || $lon ) {
- # pass through
- } else {
- die "Missing E/N, x/y, lat/lon, or postcode parameter in RSS feed";
- }
-
- # truncate the lat,lon for nicer urls
- ( $lat, $lon ) = map { Utils::truncate_coordinate($_) } ( $lat, $lon );
-
- if (!$qs) {
- $qs = "?lat=$lat;lon=$lon";
- }
-
- if ($d) {
- $qs .= ";d=$d";
- $d = 100 if $d > 100;
- } else {
- $d = mySociety::Gaze::get_radius_containing_population($lat, $lon, 200000);
- $d = int($d*10+0.5)/10;
- mySociety::Locale::in_gb_locale {
- $d = sprintf("%f", $d);
- }
- }
-
- my $xsl = Cobrand::feed_xsl($cobrand);
-
- if ($pc) {
- $alert_type = 'postcode_local_problems';
- } else {
- $alert_type = 'local_problems';
- }
-
- my @db_params = ($lat, $lon, $d);
-
- if ($state ne 'all') {
- $alert_type .= '_state';
- push @db_params, $state;
- }
-
- return FixMyStreet::Alert::generate_rss($alert_type, $xsl, $qs, \@db_params, \%title_params, $cobrand, $q);
-}
-