diff options
author | Matthew Somerville <matthew@mysociety.org> | 2011-05-19 21:07:13 +0100 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2011-05-19 21:07:13 +0100 |
commit | 69018ac3b22e469cf66f526ac76b1b8469085cb5 (patch) | |
tree | bff34e3af37160175af6074f303a9170d601933c /perllib/FixMyStreet/App/Controller | |
parent | b49dac25fb9ec11c09972e3a0b49690ccac3bc68 (diff) |
Migrate RSS feeds handling.
Diffstat (limited to 'perllib/FixMyStreet/App/Controller')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Location.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Reports.pm | 133 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Rss.pm | 211 |
3 files changed, 280 insertions, 68 deletions
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; |