Skip to content
This repository has been archived by the owner on Mar 8, 2018. It is now read-only.

Add Atom feeds for issues either by operator or map area #603

Merged
merged 11 commits into from Apr 16, 2012
Merged
24 changes: 19 additions & 5 deletions app/controllers/operators_controller.rb
Expand Up @@ -4,7 +4,7 @@ class OperatorsController < ApplicationController
before_filter :long_cache before_filter :long_cache
before_filter :find_operator, :except => [:index] before_filter :find_operator, :except => [:index]
before_filter :setup_shared_title, :except => [:index] before_filter :setup_shared_title, :except => [:index]

before_filter :setup_issues_feed, :only => [:show, :issues, :routes]


def index def index
@operator_list_threshold = 20 @operator_list_threshold = 20
Expand Down Expand Up @@ -45,7 +45,12 @@ def index
end end
end end
end end


def setup_issues_feed
@issues_feed_params = params.clone
@issues_feed_params[:format] = 'atom'
end

def show def show
@title = @operator.name @title = @operator.name
@current_tab = :issues @current_tab = :issues
Expand Down Expand Up @@ -74,9 +79,18 @@ def show
# reported to another organisation (e.g., a PTE) then that route won't show here. # reported to another organisation (e.g., a PTE) then that route won't show here.


def issues def issues
show respond_to do |format|
@title = t('route_operators.issues.title', :operator => @operator.name) format.html do
render :show show
@title = t('route_operators.issues.title', :operator => @operator.name)
render :show
end
format.atom do
@title = t('route_operators.issues.feed_title', :operator => @operator.name)
@issues = Problem.find_recent_issues false, :single_operator => @operator
render :template => 'shared/issues.atom.builder', :layout => false
end
end
end end


def routes def routes
Expand Down
192 changes: 108 additions & 84 deletions app/controllers/problems_controller.rb
Expand Up @@ -7,7 +7,8 @@ class ProblemsController < ApplicationController
:find_train_route, :find_train_route,
:find_ferry_route, :find_ferry_route,
:find_other_route, :find_other_route,
:browse] :browse,
:atom_link]
before_filter :find_visible_problem, :only => [:show, :update, :add_comment] before_filter :find_visible_problem, :only => [:show, :update, :add_comment]
before_filter :require_problem_reporter, :only => [:convert] before_filter :require_problem_reporter, :only => [:convert]
skip_before_filter :require_beta_password, :only => [:frontpage] skip_before_filter :require_beta_password, :only => [:frontpage]
Expand Down Expand Up @@ -376,6 +377,15 @@ def find_ferry_route
def choose_location def choose_location
end end


def atom_link
@issues_feed_title = atom_feed_title @lon, @lat
@issues_feed_params = params.clone
@issues_feed_params['action'] = 'browse'
@issues_feed_params['format'] = 'atom'
render :partial => 'shared/atom_link',
:locals => { :feed_link_text => t('problems.browse.feed_link_text') }
end

def browse def browse
if params[:geolocate] == '1' if params[:geolocate] == '1'
@geolocate_on_load = true @geolocate_on_load = true
Expand Down Expand Up @@ -430,9 +440,16 @@ def find_nearest_stop(lon, lat, transport_mode_name)
end end
end end


def atom_feed_title(lon, lat)
t('problems.browse.feed_title',
:longitude => lon,
:latitude => lat)
end

def find_area(options) def find_area(options)
@map_height = options[:map_height] @map_height = options[:map_height]
@map_width = options[:map_width] @map_width = options[:map_width]
to_render = nil
if is_valid_lon_lat?(params[:lon], params[:lat]) if is_valid_lon_lat?(params[:lon], params[:lat])
lat = params[:lat].to_f lat = params[:lat].to_f
lon = params[:lon].to_f lon = params[:lon].to_f
Expand All @@ -442,100 +459,107 @@ def find_area(options)
@geolocate_on_load = false @geolocate_on_load = false
# don't show geolocate button # don't show geolocate button
@geolocation_failed = true @geolocation_failed = true
render options[:find_template] to_render = options[:find_template]
return else
end nearest_stop = find_nearest_stop(params[:lon], params[:lat], nil)
nearest_stop = find_nearest_stop(params[:lon], params[:lat], nil) if nearest_stop
if nearest_stop map_params_from_location([nearest_stop],
map_params_from_location([nearest_stop],
find_other_locations=true,
@map_height,
@map_width,
options[:map_options])
@locations = [nearest_stop]
render options[:browse_template]
return
else # no nearest stop suggests empty database
location_search.fail
@error_message = t('problems.find_stop.please_enter_an_area')
end
elsif params[:name]
if params[:name].blank?
@error_message = t('problems.find_stop.please_enter_an_area')
render options[:find_template]
return
end
location_search = LocationSearch.new_search!(session_id, :name => params[:name],
:location_type => 'Stop/station')
stop_info = Gazetteer.place_from_name(params[:name], params[:stop_name], options[:map_options][:mode])
# got back localities
if stop_info[:localities]
if stop_info[:localities].size > 1
@localities = stop_info[:localities]
@matched_stops_or_stations = stop_info[:matched_stops_or_stations]
@name = params[:name]
render :choose_locality
return
else
return render_browse_template(stop_info[:localities], options[:map_options], options[:browse_template])
end
# got back district
elsif stop_info[:district]
return render_browse_template([stop_info[:district]], options[:map_options], options[:browse_template])
# got back admin area
elsif stop_info[:admin_area]
return render_browse_template([stop_info[:admin_area]], options[:map_options], options[:browse_template])
# got back stops/stations
elsif stop_info[:locations]
if options[:map_options][:mode] == :browse
return render_browse_template(stop_info[:locations], options[:map_options], options[:browse_template])
else
map_params_from_location(stop_info[:locations],
find_other_locations=true, find_other_locations=true,
@map_height, @map_height,
@map_width, @map_width,
options[:map_options]) options[:map_options])
@locations = stop_info[:locations] @locations = [nearest_stop]
render options[:browse_template] to_render = options[:browse_template]
return else # no nearest stop suggests empty database
end
# got back postcode info
elsif stop_info[:postcode_info]
postcode_info = stop_info[:postcode_info]
if postcode_info[:error]
location_search.fail location_search.fail
if postcode_info[:error] == :area_not_known @error_message = t('problems.find_stop.please_enter_an_area')
@error_message = t('problems.find_stop.postcode_area_not_known') end
elsif postcode_info[:error] == :service_unavailable end
@error_message = t('problems.find_stop.postcode_service_unavailable') elsif params[:name]
if params[:name].blank?
@error_message = t('problems.find_stop.please_enter_an_area')
to_render = options[:find_template]
else
location_search = LocationSearch.new_search!(session_id, :name => params[:name],
:location_type => 'Stop/station')
stop_info = Gazetteer.place_from_name(params[:name], params[:stop_name], options[:map_options][:mode])
# got back localities
if stop_info[:localities]
if stop_info[:localities].size > 1
@localities = stop_info[:localities]
@matched_stops_or_stations = stop_info[:matched_stops_or_stations]
@name = params[:name]
to_render = :choose_locality
else else
@error_message = t('problems.find_stop.postcode_not_found') return render_browse_template(stop_info[:localities], options[:map_options], options[:browse_template])
end
# got back district
elsif stop_info[:district]
return render_browse_template([stop_info[:district]], options[:map_options], options[:browse_template])
# got back admin area
elsif stop_info[:admin_area]
return render_browse_template([stop_info[:admin_area]], options[:map_options], options[:browse_template])
# got back stops/stations
elsif stop_info[:locations]
if options[:map_options][:mode] == :browse
return render_browse_template(stop_info[:locations], options[:map_options], options[:browse_template])
else
map_params_from_location(stop_info[:locations],
find_other_locations=true,
@map_height,
@map_width,
options[:map_options])
@locations = stop_info[:locations]
to_render = options[:browse_template]
end
# got back postcode info
elsif stop_info[:postcode_info]
postcode_info = stop_info[:postcode_info]
if postcode_info[:error]
location_search.fail
if postcode_info[:error] == :area_not_known
@error_message = t('problems.find_stop.postcode_area_not_known')
elsif postcode_info[:error] == :service_unavailable
@error_message = t('problems.find_stop.postcode_service_unavailable')
else
@error_message = t('problems.find_stop.postcode_not_found')
end
to_render = options[:find_template]
else
@lat = postcode_info[:lat] unless @lat
@lon = postcode_info[:lon] unless @lon
@zoom = postcode_info[:zoom] unless @zoom
map_data = Map.other_locations(@lat, @lon, @zoom, @map_height, @map_width, @highlight)
@other_locations = map_data[:locations]
@issues_on_map = map_data[:issues]
@nearest_issues = map_data[:nearest_issues]
@distance = map_data[:distance]
@locations = []
@find_other_locations = true
to_render = options[:browse_template]
end end
render options[:find_template]
return
else else
@lat = postcode_info[:lat] unless @lat # didn't find anything
@lon = postcode_info[:lon] unless @lon location_search.fail
@zoom = postcode_info[:zoom] unless @zoom @error_message = t('problems.find_stop.area_not_found')
map_data = Map.other_locations(@lat, @lon, @zoom, @map_height, @map_width, @highlight) to_render = options[:find_template]
@other_locations = map_data[:locations]
@issues_on_map = map_data[:issues]
@nearest_issues = map_data[:nearest_issues]
@distance = map_data[:distance]
@locations = []
@find_other_locations = true
render options[:browse_template]
return
end end
else
# didn't find anything
location_search.fail
@error_message = t('problems.find_stop.area_not_found')
render options[:find_template]
return
end end
end end

respond_to do |format|
format.html do
@issues_feed_params = params.clone
@issues_feed_params[:format] = 'atom'
render to_render if to_render
end
format.atom do
@title = atom_feed_title @lon, @lat
@issues = []
@issues.concat(@issues_on_map) if @issues_on_map
@issues.concat(@nearest_issues) if @nearest_issues
render :template => 'shared/issues.atom.builder', :layout => false
end
end
end end


def is_valid_lon_lat?(lon, lat) def is_valid_lon_lat?(lon, lat)
Expand Down
5 changes: 5 additions & 0 deletions app/models/campaign.rb
Expand Up @@ -263,4 +263,9 @@ def self.needing_questionnaire(weeks_ago, user=nil)
self.visible.find(:all, :conditions => query + params, self.visible.find(:all, :conditions => query + params,
:include => :problem) :include => :problem)
end end

def feed_title_suffix
:fixed == status ? " [FIXED]" : ""
end

end end
6 changes: 5 additions & 1 deletion app/models/problem.rb
Expand Up @@ -494,4 +494,8 @@ def self.needing_questionnaire(weeks_ago, user=nil)
self.visible.sent.find(:all, :conditions => query + params) self.visible.sent.find(:all, :conditions => query + params)
end end


end def feed_title_suffix
:fixed == status ? " [FIXED]" : ""
end

end
1 change: 1 addition & 0 deletions app/views/operators/show.erb
Expand Up @@ -57,6 +57,7 @@
<%= will_paginate @stations %> <%= will_paginate @stations %>
<%- elsif @current_tab == :issues %> <%- elsif @current_tab == :issues %>
<%- if @issue_count != 0 %> <%- if @issue_count != 0 %>
<%= render :partial => 'shared/atom_link', :locals => { :feed_link_text => t('route_operators.show.feed_link_text', :operator => @operator.name) } %>
<%= will_paginate @issues, :params => { :action => :issues } %> <%= will_paginate @issues, :params => { :action => :issues } %>
<ul class="issues-list widecol"> <ul class="issues-list widecol">
<%= render :partial => "shared/issue", :collection => @issues, :locals => {:context => :issue_list } %> <%= render :partial => "shared/issue", :collection => @issues, :locals => {:context => :issue_list } %>
Expand Down
1 change: 1 addition & 0 deletions app/views/problems/browse_area.erb
Expand Up @@ -7,6 +7,7 @@
<div id="main-content" class="browse-map-container container"> <div id="main-content" class="browse-map-container container">


<div class="leftcol mediumnarrowcol"> <div class="leftcol mediumnarrowcol">
<%= render :partial => 'shared/atom_link', :locals => { :feed_link_text => t('problems.browse.feed_link_text') } %>
<div id="issues-in-area"> <div id="issues-in-area">
<%= render :partial => 'shared/issues_in_area'%> <%= render :partial => 'shared/issues_in_area'%>
</div> </div>
Expand Down
5 changes: 5 additions & 0 deletions app/views/shared/_atom_link.erb
@@ -0,0 +1,5 @@
<%- if @issues_feed_params %>
<div class="atom-link" id="in-page-atom-link">
<%= link_to image_tag("feed.png", :class => 'inline-icon') + " " + feed_link_text, @issues_feed_params %>
</div>
<%- end %>
4 changes: 2 additions & 2 deletions app/views/shared/issues.atom.builder
Expand Up @@ -4,15 +4,15 @@ atom_feed do |feed|
@issues.each do |issue| @issues.each do |issue|
if issue.is_a?(Campaign) if issue.is_a?(Campaign)
feed.entry(issue) do |entry| feed.entry(issue) do |entry|
entry.title(h(issue.title)) entry.title issue.title + issue.feed_title_suffix
entry.content(strip_tags(issue.description)) entry.content(strip_tags(issue.description))
entry.author do |author| entry.author do |author|
author.name(issue.initiator.name) author.name(issue.initiator.name)
end end
end end
elsif issue.is_a?(Problem) elsif issue.is_a?(Problem)
feed.entry(issue) do |entry| feed.entry(issue) do |entry|
entry.title(h(issue.subject)) entry.title issue.subject + issue.feed_title_suffix
entry.content(strip_tags(issue.description)) entry.content(strip_tags(issue.description))
entry.author do |author| entry.author do |author|
author.name(issue.reporter.name) author.name(issue.reporter.name)
Expand Down
2 changes: 2 additions & 0 deletions config/locales/views/operators/en.yml
Expand Up @@ -16,6 +16,7 @@ en:
routes_header: "Routes" routes_header: "Routes"
stations_header: "Stations" stations_header: "Stations"
issues_header: "Issues" issues_header: "Issues"
feed_link_text: "Get updates on issues for %{operator}"
is_an_operator: "{%operator} is a transport operator." is_an_operator: "{%operator} is a transport operator."
is_an_operator_with_transport_mode: "%{operator} is a transport operator providing %{transport_mode} services." is_an_operator_with_transport_mode: "%{operator} is a transport operator providing %{transport_mode} services."
operates_routes: operates_routes:
Expand All @@ -32,6 +33,7 @@ en:
other: "%{count} issues have been reported to %{operator}." other: "%{count} issues have been reported to %{operator}."
issues: issues:
title: "%{operator} issues" title: "%{operator} issues"
feed_title: "Issues for %{operator} on FixMyTransport"
routes: routes:
title: "%{operator} routes" title: "%{operator} routes"
stations: stations:
Expand Down
2 changes: 2 additions & 0 deletions config/locales/views/problems/en.yml
Expand Up @@ -8,6 +8,8 @@ en:
title: "Issues in '%{area}'" title: "Issues in '%{area}'"
no_other_issues: No issues have been reported yet. no_other_issues: No issues have been reported yet.
title_no_name: "Browsing issues" title_no_name: "Browsing issues"
feed_title: "Issues around longitude %{longitude} and latitude %{latitude} on FixMyTransport"
feed_link_text: "Get updates on issues on and around this map"
choose_area: choose_area:
choose_area: "Choose area" choose_area: "Choose area"
multiple_localities: "We found more than one place matching \"%{name}\". Please select one, or try a different search if yours is not here:" multiple_localities: "We found more than one place matching \"%{name}\". Please select one, or try a different search if yours is not here:"
Expand Down
7 changes: 7 additions & 0 deletions config/routes.rb
Expand Up @@ -72,6 +72,13 @@
map.issues '/issues', :action => 'issues_index', :controller => 'problems' map.issues '/issues', :action => 'issues_index', :controller => 'problems'
map.browse_issues '/issues/browse', :action => 'browse', :controller => 'problems' map.browse_issues '/issues/browse', :action => 'browse', :controller => 'problems'


map.browse_issues_atom_link '/issues/browse/atom_link/:zoom/:lat/:lon', :action => 'atom_link',
:controller => 'problems',
:conditions => { :method => :get },
:requirements => { :zoom => /\d\d?/,
:lon => /[-+]?[0-9]*\.?[0-9]+/,
:lat => /[-+]?[0-9]*\.?[0-9]+/ }

# stops # stops
map.add_comment_stop "/stops/:scope/:id/add_comment", :controller => "locations", map.add_comment_stop "/stops/:scope/:id/add_comment", :controller => "locations",
:action => 'add_comment_to_stop', :action => 'add_comment_to_stop',
Expand Down