1 class NotesController < ApplicationController
3 layout 'site', :only => [:mine]
5 before_filter :check_api_readable
6 before_filter :authorize_web, :only => [:mine]
7 before_filter :setup_user_auth, :only => [:create, :comment]
8 before_filter :authorize, :only => [:close, :reopen, :destroy]
9 before_filter :require_moderator, :only => [:destroy]
10 before_filter :check_api_writable, :only => [:create, :comment, :close, :reopen, :destroy]
11 before_filter :require_allow_write_notes, :only => [:create, :comment, :close, :reopen, :destroy]
12 before_filter :set_locale
13 after_filter :compress_output
14 around_filter :api_call_handle_error, :api_call_timeout
17 # Return a list of notes in a given area
19 # Figure out the bbox - we prefer a bbox argument but also
20 # support the old, deprecated, method with four arguments
22 bbox = BoundingBox.from_bbox_params(params)
24 raise OSM::APIBadUserInput.new("No l was given") unless params[:l]
25 raise OSM::APIBadUserInput.new("No r was given") unless params[:r]
26 raise OSM::APIBadUserInput.new("No b was given") unless params[:b]
27 raise OSM::APIBadUserInput.new("No t was given") unless params[:t]
29 bbox = BoundingBox.from_lrbt_params(params)
32 # Get any conditions that need to be applied
33 notes = closed_condition(Note.scoped)
35 # Check that the boundaries are valid
38 # Check the the bounding box is not too big
39 bbox.check_size(MAX_NOTE_REQUEST_AREA)
41 # Find the notes we want to return
42 @notes = notes.bbox(bbox).order("updated_at DESC").limit(result_limit).preload(:comments)
45 respond_to do |format|
56 # Check the arguments are sane
57 raise OSM::APIBadUserInput.new("No lat was given") unless params[:lat]
58 raise OSM::APIBadUserInput.new("No lon was given") unless params[:lon]
59 raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
61 # Extract the arguments
63 lon = Float(params[:lon])
65 raise OSM::APIBadUserInput.new("lon was not a number")
68 lat = Float(params[:lat])
70 raise OSM::APIBadUserInput.new("lat was not a number")
72 comment = params[:text]
74 # Include in a transaction to ensure that there is always a note_comment for every note
77 @note = Note.create(:lat => lat, :lon => lon)
78 raise OSM::APIBadUserInput.new("The note is outside this world") unless @note.in_world?
83 # Add a comment to the note
84 add_comment(@note, comment, "opened")
87 # Return a copy of the new note
88 respond_to do |format|
89 format.xml { render :action => :show }
90 format.json { render :action => :show }
95 # Add a comment to an existing note
97 # Check the arguments are sane
98 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
99 raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
101 # Extract the arguments
102 id = params[:id].to_i
103 comment = params[:text]
105 # Find the note and check it is valid
106 @note = Note.find(id)
107 raise OSM::APINotFoundError unless @note
108 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
109 raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
111 # Add a comment to the note
113 add_comment(@note, comment, "commented")
116 # Return a copy of the updated note
117 respond_to do |format|
118 format.xml { render :action => :show }
119 format.json { render :action => :show }
126 # Check the arguments are sane
127 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
129 # Extract the arguments
130 id = params[:id].to_i
131 comment = params[:text]
133 # Find the note and check it is valid
134 @note = Note.find_by_id(id)
135 raise OSM::APINotFoundError unless @note
136 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
137 raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
139 # Close the note and add a comment
143 add_comment(@note, comment, "closed")
146 # Return a copy of the updated note
147 respond_to do |format|
148 format.xml { render :action => :show }
149 format.json { render :action => :show }
156 # Check the arguments are sane
157 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
159 # Extract the arguments
160 id = params[:id].to_i
161 comment = params[:text]
163 # Find the note and check it is valid
164 @note = Note.find_by_id(id)
165 raise OSM::APINotFoundError unless @note
166 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
167 raise OSM::APINoteAlreadyOpenError.new(@note) unless @note.closed?
169 # Reopen the note and add a comment
173 add_comment(@note, comment, "reopened")
176 # Return a copy of the updated note
177 respond_to do |format|
178 format.xml { render :action => :show }
179 format.json { render :action => :show }
184 # Get a feed of recent notes and comments
186 # Get any conditions that need to be applied
187 notes = closed_condition(Note.scoped)
191 bbox = BoundingBox.from_bbox_params(params)
193 bbox.check_boundaries
194 bbox.check_size(MAX_NOTE_REQUEST_AREA)
196 notes = notes.bbox(bbox)
199 # Find the comments we want to return
200 @comments = NoteComment.where(:note_id => notes).order("created_at DESC").limit(result_limit).preload(:note)
203 respond_to do |format|
211 # Check the arguments are sane
212 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
214 # Find the note and check it is valid
215 @note = Note.find(params[:id])
216 raise OSM::APINotFoundError unless @note
217 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
220 respond_to do |format|
229 # Delete (hide) a note
231 # Check the arguments are sane
232 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
234 # Extract the arguments
235 id = params[:id].to_i
236 comment = params[:text]
238 # Find the note and check it is valid
239 @note = Note.find(id)
240 raise OSM::APINotFoundError unless @note
241 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
243 # Mark the note as hidden
245 @note.status = "hidden"
248 add_comment(@note, comment, "hidden", false)
251 # Return a copy of the updated note
252 respond_to do |format|
253 format.xml { render :action => :show }
254 format.json { render :action => :show }
259 # Return a list of notes matching a given string
261 # Check the arguments are sane
262 raise OSM::APIBadUserInput.new("No query string was given") unless params[:q]
264 # Get any conditions that need to be applied
265 @notes = closed_condition(Note.scoped)
266 @notes = @notes.joins(:comments).where("note_comments.body ~ ?", params[:q])
268 # Find the notes we want to return
269 @notes = @notes.order("updated_at DESC").limit(result_limit).preload(:comments)
272 respond_to do |format|
273 format.rss { render :action => :index }
274 format.xml { render :action => :index }
275 format.json { render :action => :index }
276 format.gpx { render :action => :index }
281 # Display a list of notes by a specified user
283 if params[:display_name]
284 if @this_user = User.active.find_by_display_name(params[:display_name])
285 @title = t 'note.mine.title', :user => @this_user.display_name
286 @heading = t 'note.mine.heading', :user => @this_user.display_name
287 @description = t 'note.mine.subheading', :user => render_to_string(:partial => "user", :object => @this_user)
288 @page = (params[:page] || 1).to_i
290 @notes = @this_user.notes.order("updated_at DESC, id").uniq.offset((@page - 1) * @page_size).limit(@page_size).preload(:comments => :author).all
292 @title = t 'user.no_such_user.title'
293 @not_found_user = params[:display_name]
295 render :template => 'user/no_such_user', :status => :not_found
301 #------------------------------------------------------------
302 # utility functions below.
303 #------------------------------------------------------------
306 # Render an OK response
308 if params[:format] == "js"
309 render :text => "osbResponse();", :content_type => "text/javascript"
311 render :text => "ok " + @note.id.to_s + "\n", :content_type => "text/plain" if @note
312 render :text => "ok\n", :content_type => "text/plain" unless @note
317 # Get the maximum number of results to return
319 if params[:limit] and params[:limit].to_i > 0 and params[:limit].to_i < 10000
327 # Generate a condition to choose which bugs we want based
328 # on their status and the user's request parameters
329 def closed_condition(notes)
331 closed_since = params[:closed].to_i
337 notes = notes.where("status != 'hidden'")
338 elsif closed_since > 0
339 notes = notes.where("(status = 'open' OR (status = 'closed' AND closed_at > '#{Time.now - closed_since.days}'))")
341 notes = notes.where("status = 'open'")
348 # Add a comment to a note
349 def add_comment(note, text, event, notify = true)
350 attributes = { :visible => true, :event => event, :body => text }
353 attributes[:author_id] = @user.id
355 attributes[:author_ip] = request.remote_ip
358 comment = note.comments.create(attributes, :without_protection => true)
360 note.comments.map { |c| c.author }.uniq.each do |user|
361 if notify and user and user != @user
362 Notifier.note_comment_notification(comment, user).deliver