diff options
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Rss.pm')
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Rss.pm | 211 |
1 files changed, 211 insertions, 0 deletions
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; |