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, :destroy]
9 before_filter :check_api_writable, :only => [:create, :comment, :close, :destroy]
10 before_filter :require_allow_write_notes, :only => [:create, :comment, :close, :destroy]
11 before_filter :set_locale, :only => [:mine]
12 after_filter :compress_output
13 around_filter :api_call_handle_error, :api_call_timeout
16 # Return a list of notes in a given area
18 # Figure out the bbox - we prefer a bbox argument but also
19 # support the old, deprecated, method with four arguments
21 bbox = BoundingBox.from_bbox_params(params)
23 raise OSM::APIBadUserInput.new("No l was given") unless params[:l]
24 raise OSM::APIBadUserInput.new("No r was given") unless params[:r]
25 raise OSM::APIBadUserInput.new("No b was given") unless params[:b]
26 raise OSM::APIBadUserInput.new("No t was given") unless params[:t]
28 bbox = BoundingBox.from_lrbt_params(params)
31 # Get any conditions that need to be applied
32 notes = closed_condition(Note.scoped)
34 # Check that the boundaries are valid
37 # Check the the bounding box is not too big
38 bbox.check_size(MAX_NOTE_REQUEST_AREA)
40 # Find the notes we want to return
41 @notes = notes.bbox(bbox).order("updated_at DESC").limit(result_limit).preload(:comments)
44 respond_to do |format|
55 # Check the arguments are sane
56 raise OSM::APIBadUserInput.new("No lat was given") unless params[:lat]
57 raise OSM::APIBadUserInput.new("No lon was given") unless params[:lon]
58 raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
60 # Extract the arguments
61 lon = params[:lon].to_f
62 lat = params[:lat].to_f
63 comment = params[:text]
65 # Include in a transaction to ensure that there is always a note_comment for every note
68 @note = Note.create(:lat => lat, :lon => lon)
69 raise OSM::APIBadUserInput.new("The note is outside this world") unless @note.in_world?
74 # Add a comment to the note
75 add_comment(@note, comment, "opened")
78 # Return a copy of the new note
79 respond_to do |format|
80 format.xml { render :action => :show }
81 format.json { render :action => :show }
86 # Add a comment to an existing note
88 # Check the arguments are sane
89 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
90 raise OSM::APIBadUserInput.new("No text was given") if params[:text].blank?
92 # Extract the arguments
94 comment = params[:text]
96 # Find the note and check it is valid
98 raise OSM::APINotFoundError unless @note
99 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
100 raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
102 # Add a comment to the note
104 add_comment(@note, comment, "commented")
107 # Return a copy of the updated note
108 respond_to do |format|
109 format.xml { render :action => :show }
110 format.json { render :action => :show }
117 # Check the arguments are sane
118 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
120 # Extract the arguments
121 id = params[:id].to_i
122 comment = params[:text]
124 # Find the note and check it is valid
125 @note = Note.find_by_id(id)
126 raise OSM::APINotFoundError unless @note
127 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
128 raise OSM::APINoteAlreadyClosedError.new(@note) if @note.closed?
130 # Close the note and add a comment
134 add_comment(@note, comment, "closed")
137 # Return a copy of the updated note
138 respond_to do |format|
139 format.xml { render :action => :show }
140 format.json { render :action => :show }
145 # Get a feed of recent notes and comments
147 # Get any conditions that need to be applied
148 notes = closed_condition(Note.scoped)
152 bbox = BoundingBox.from_bbox_params(params)
154 bbox.check_boundaries
155 bbox.check_size(MAX_NOTE_REQUEST_AREA)
157 notes = notes.bbox(bbox)
160 # Find the comments we want to return
161 @comments = NoteComment.where(:note_id => notes).order("created_at DESC").limit(result_limit).preload(:note)
164 respond_to do |format|
172 # Check the arguments are sane
173 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
175 # Find the note and check it is valid
176 @note = Note.find(params[:id])
177 raise OSM::APINotFoundError unless @note
178 raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible?
181 respond_to do |format|
190 # Delete (hide) a note
192 # Check the arguments are sane
193 raise OSM::APIBadUserInput.new("No id was given") unless params[:id]
195 # Extract the arguments
196 id = params[:id].to_i
198 # Find the note and check it is valid
200 raise OSM::APINotFoundError unless note
201 raise OSM::APIAlreadyDeletedError.new("note", note.id) unless note.visible?
203 # Mark the note as hidden
205 note.status = "hidden"
208 add_comment(note, nil, "hidden")
212 render :text => "ok\n", :content_type => "text/html"
216 # Return a list of notes matching a given string
218 # Check the arguments are sane
219 raise OSM::APIBadUserInput.new("No query string was given") unless params[:q]
221 # Get any conditions that need to be applied
222 @notes = closed_condition(Note.scoped)
223 @notes = @notes.joins(:comments).where("note_comments.body ~ ?", params[:q])
225 # Find the notes we want to return
226 @notes = @notes.order("updated_at DESC").limit(result_limit).preload(:comments)
229 respond_to do |format|
230 format.rss { render :action => :index }
231 format.xml { render :action => :index }
232 format.json { render :action => :index }
233 format.gpx { render :action => :index }
238 # Display a list of notes by a specified user
240 if params[:display_name]
241 if @this_user = User.active.find_by_display_name(params[:display_name])
242 @title = t 'note.mine.title', :user => @this_user.display_name
243 @heading = t 'note.mine.heading', :user => @this_user.display_name
244 @description = t 'note.mine.subheading', :user => render_to_string(:partial => "user", :object => @this_user)
245 @page = (params[:page] || 1).to_i
247 @notes = @this_user.notes.order("updated_at DESC, id").uniq.offset((@page - 1) * @page_size).limit(@page_size).preload(:comments => :author)
249 @title = t 'user.no_such_user.title'
250 @not_found_user = params[:display_name]
252 render :template => 'user/no_such_user', :status => :not_found
258 #------------------------------------------------------------
259 # utility functions below.
260 #------------------------------------------------------------
263 # Render an OK response
265 if params[:format] == "js"
266 render :text => "osbResponse();", :content_type => "text/javascript"
268 render :text => "ok " + @note.id.to_s + "\n", :content_type => "text/plain" if @note
269 render :text => "ok\n", :content_type => "text/plain" unless @note
274 # Get the maximum number of results to return
276 if params[:limit] and params[:limit].to_i > 0 and params[:limit].to_i < 10000
284 # Generate a condition to choose which bugs we want based
285 # on their status and the user's request parameters
286 def closed_condition(notes)
288 closed_since = params[:closed].to_i
294 notes = notes.where("status != 'hidden'")
295 elsif closed_since > 0
296 notes = notes.where("(status = 'open' OR (status = 'closed' AND closed_at > '#{Time.now - closed_since.days}'))")
298 notes = notes.where("status = 'open'")
305 # Add a comment to a note
306 def add_comment(note, text, event)
307 attributes = { :visible => true, :event => event, :body => text }
310 attributes[:author_id] = @user.id
312 attributes[:author_ip] = request.remote_ip
315 comment = note.comments.create(attributes, :without_protection => true)
317 note.comments.map { |c| c.author }.uniq.each do |user|
318 if user and user != @user
319 Notifier.note_comment_notification(comment, user).deliver