openstreetmap-website/app/controllers/map_bugs_controller.rb
Kai Krueger 59a6ed0e20 Don't limit get map_bugs to a small Area, by disabling the quadtile index for those searches
The volumn of bugs seem small enough to get away with normal or GiST indexes (not included yet)

Also includes some other fixes
2010-03-20 11:59:23 +00:00

285 lines
8.6 KiB
Ruby

class MapBugsController < ApplicationController
layout 'site', :only => [:my_bugs]
before_filter :check_api_readable
before_filter :authorize_web, :only => [:add_bug, :close_bug, :edit_bug, :delete, :my_bugs]
before_filter :check_api_writable, :only => [:add_bug, :close_bug, :edit_bug, :delete]
before_filter :require_moderator, :only => [:delete]
before_filter :set_locale, :only => [:my_bugs]
after_filter :compress_output
around_filter :api_call_handle_error, :api_call_timeout
# Help methods for checking boundary sanity and area size
include MapBoundary
def get_bugs
# Figure out the bbox
bbox = params['bbox']
if bbox and bbox.count(',') == 3
bbox = bbox.split(',')
min_lon, min_lat, max_lon, max_lat = sanitise_boundaries(bbox)
else
#Fallback to old style, this is deprecated and should not be used
raise OSM::APIBadUserInput.new("No l was given") unless params['l']
raise OSM::APIBadUserInput.new("No r was given") unless params['r']
raise OSM::APIBadUserInput.new("No b was given") unless params['b']
raise OSM::APIBadUserInput.new("No t was given") unless params['t']
min_lon = params['l'].to_f
max_lon = params['r'].to_f
min_lat = params['b'].to_f
max_lat = params['t'].to_f
end
limit = getLimit
conditions = closedCondition
check_boundaries(min_lon, min_lat, max_lon, max_lat, :false)
@bugs = MapBug.find_by_area_no_quadtile(min_lat, min_lon, max_lat, max_lon, :include => :map_bug_comment, :order => "last_changed DESC", :limit => limit, :conditions => conditions)
respond_to do |format|
format.html {render :template => 'map_bugs/get_bugs.js', :content_type => "text/javascript"}
format.rss {render :template => 'map_bugs/get_bugs.rss'}
format.js
format.xml {render :template => 'map_bugs/get_bugs.xml'}
format.json { render :json => @bugs.to_json(:methods => [:lat, :lon], :only => [:id, :status, :date_created], :include => { :map_bug_comment => { :only => [:commenter_name, :date_created, :comment]}}) }
# format.gpx {render :template => 'map_bugs/get_bugs.gpx'}
end
end
def add_bug
raise OSM::APIBadUserInput.new("No lat was given") unless params['lat']
raise OSM::APIBadUserInput.new("No lon was given") unless params['lon']
raise OSM::APIBadUserInput.new("No text was given") unless params['text']
lon = params['lon'].to_f
lat = params['lat'].to_f
comment = params['text']
name = "NoName";
name = params['name'] if params['name'];
#Include in a transaction to ensure that there is always a map_bug_comment for every map_bug
MapBug.transaction do
@bug = MapBug.create_bug(lat, lon)
#TODO: move this into a helper function
begin
url = "http://nominatim.openstreetmap.org/reverse?lat=" + lat.to_s + "&lon=" + lon.to_s + "&zoom=16"
response = REXML::Document.new(Net::HTTP.get(URI.parse(url)))
if result = response.get_text("reversegeocode/result")
@bug.nearby_place = result.to_s
else
@bug.nearby_place = "unknown"
end
rescue Exception => err
@bug.nearby_place = "unknown"
end
@bug.save;
add_comment(@bug, comment, name);
end
render_ok
end
def edit_bug
raise OSM::APIBadUserInput.new("No id was given") unless params['id']
raise OSM::APIBadUserInput.new("No text was given") unless params['text']
name = "NoName";
name = params['name'] if params['name'];
id = params['id'].to_i
bug = MapBug.find_by_id(id);
raise OSM::APINotFoundError unless bug
raise OSM::APIAlreadyDeletedError unless bug.visible
bug_comment = add_comment(bug, params['text'], name);
render_ok
end
def close_bug
raise OSM::APIBadUserInput.new("No id was given") unless params['id']
id = params['id'].to_i
bug = MapBug.find_by_id(id);
raise OSM::APINotFoundError unless bug
raise OSM::APIAlreadyDeletedError unless bug.visible
bug.close_bug;
render_ok
end
def rss
request.format = :rss
get_bugs
end
def gpx_bugs
request.format = :xml
get_bugs
end
def read
@bug = MapBug.find(params['id'])
raise OSM::APINotFoundError unless @bug
raise OSM::APIAlreadyDeletedError unless @bug.visible
respond_to do |format|
format.rss
format.xml
format.json { render :json => @bug.to_json(:methods => [:lat, :lon], :only => [:id, :status, :date_created], :include => { :map_bug_comment => { :only => [:commenter_name, :date_created, :comment]}}) }
end
end
def delete
bug = MapBug.find(params['id'])
raise OSM::APINotFoundError unless @bug
raise OSM::APIAlreadyDeletedError unless @bug.visible
bug.status = "hidden"
bug.save
render :text => "ok\n", :content_type => "text/html"
end
def search
raise OSM::APIBadUserInput.new("No query string was given") unless params['q']
limit = getLimit
conditions = closedCondition
conditions = cond_merge conditions, ['map_bug_comment.comment ~ ?', params['q']]
#TODO: There should be a better way to do this. CloseConditions are ignored at the moment
bugs2 = MapBug.find(:all, :limit => limit, :order => "last_changed DESC", :joins => :map_bug_comment, :include => :map_bug_comment,
:conditions => conditions)
@bugs = bugs2.uniq
respond_to do |format|
format.html {render :template => 'map_bugs/get_bugs.js', :content_type => "text/javascript"}
format.rss {render :template => 'map_bugs/get_bugs.rss'}
format.js
format.xml {render :template => 'map_bugs/get_bugs.xml'}
format.json { render :json => @bugs.to_json(:methods => [:lat, :lon], :only => [:id, :status, :date_created], :include => { :map_bug_comment => { :only => [:commenter_name, :date_created, :comment]}}) }
# format.gpx {render :template => 'map_bugs/get_bugs.gpx'}
end
end
def my_bugs
if params[:display_name]
@user2 = User.find_by_display_name(params[:display_name], :conditions => { :visible => true })
if @user2
if @user2.data_public? or @user2 == @user
conditions = ['map_bug_comment.commenter_id = ?', @user2.id]
else
conditions = ['false']
end
elsif request.format == :html
@title = t 'user.no_such_user.title'
@not_found_user = params[:display_name]
render :template => 'user/no_such_user', :status => :not_found
end
end
if @user2
user_link = render_to_string :partial => "user", :object => @user2
end
@title = t 'bugs.user.title_user', :user => @user2.display_name
@heading = t 'bugs.user.heading_user', :user => @user2.display_name
@description = t 'bugs.user.description_user', :user => user_link
@page = (params[:page] || 1).to_i
@page_size = 10
@bugs = MapBug.find(:all,
:include => [:map_bug_comment, {:map_bug_comment => :user}],
:joins => :map_bug_comment,
:order => "last_changed DESC",
:conditions => conditions,
:offset => (@page - 1) * @page_size,
:limit => @page_size).uniq
end
private
#------------------------------------------------------------
# utility functions below.
#------------------------------------------------------------
##
# merge two conditions
# TODO: this is a copy from changeset_controler.rb and should be factored out to share
def cond_merge(a, b)
if a and b
a_str = a.shift
b_str = b.shift
return [ a_str + " AND " + b_str ] + a + b
elsif a
return a
else b
return b
end
end
def render_ok
output_js = :false
output_js = :true if params['format'] == "js"
if output_js == :true
render :text => "osbResponse();", :content_type => "text/javascript"
else
render :text => "ok " + @bug.id.to_s + "\n", :content_type => "text/html" if @bug
render :text => "ok\n", :content_type => "text/html" unless @bug
end
end
def getLimit
limit = 100;
limit = params['limit'] if ((params['limit']) && (params['limit'].to_i < 10000) && (params['limit'].to_i > 0))
return limit
end
def closedCondition
closed_since = 7 unless params['closed']
closed_since = params['closed'].to_i if params['closed']
if closed_since < 0
conditions = ["status != 'hidden'"]
elsif closed_since > 0
conditions = ["((status = 'open') OR ((status = 'closed' ) AND (date_closed > '" + (Time.now - closed_since.days).to_s + "')))"]
else
conditions = ["status = 'open'"]
end
return conditions
end
def add_comment(bug, comment, name)
t = Time.now.getutc
bug_comment = bug.map_bug_comment.create(:date_created => t, :visible => true, :comment => comment);
if @user
bug_comment.commenter_id = @user.id
bug_comment.commenter_name = @user.display_name
else
bug_comment.commenter_ip = request.remote_ip
bug_comment.commenter_name = name + " (a)"
end
bug_comment.save;
bug.last_changed = t
bug.save
end
end