X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/be0e33862fedbf02e52a9e126cac31dfb5775b43..f5db9cbb207e17fc8a2f15f681819e9e55aa1906:/app/controllers/api/notes_controller.rb diff --git a/app/controllers/api/notes_controller.rb b/app/controllers/api/notes_controller.rb index d4ebef5d4..e6f391ede 100644 --- a/app/controllers/api/notes_controller.rb +++ b/app/controllers/api/notes_controller.rb @@ -1,18 +1,15 @@ module Api - class NotesController < ApplicationController - layout "site", :only => [:mine] - - skip_before_action :verify_authenticity_token + class NotesController < ApiController before_action :check_api_readable - before_action :setup_user_auth, :only => [:create, :comment, :show] - before_action :authorize, :only => [:close, :reopen, :destroy] - before_action :api_deny_access_handler + before_action :check_api_writable, :only => [:create, :comment, :close, :reopen, :destroy] + before_action :setup_user_auth, :only => [:create, :show] + before_action :authorize, :only => [:close, :reopen, :destroy, :comment] authorize_resource - before_action :check_api_writable, :only => [:create, :comment, :close, :reopen, :destroy] before_action :set_locale around_action :api_call_handle_error, :api_call_timeout + before_action :set_request_formats, :except => [:feed] ## # Return a list of notes in a given area @@ -37,7 +34,11 @@ module Api bbox.check_boundaries # Check the the bounding box is not too big - bbox.check_size(MAX_NOTE_REQUEST_AREA) + bbox.check_size(Settings.max_note_request_area) + @min_lon = bbox.min_lon + @min_lat = bbox.min_lat + @max_lon = bbox.max_lon + @max_lat = bbox.max_lat # Find the notes we want to return @notes = notes.bbox(bbox).order("updated_at DESC").limit(result_limit).preload(:comments) @@ -51,6 +52,26 @@ module Api end end + ## + # Read a note + def show + # Check the arguments are sane + raise OSM::APIBadUserInput, "No id was given" unless params[:id] + + # Find the note and check it is valid + @note = Note.find(params[:id]) + raise OSM::APINotFoundError unless @note + raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? || current_user&.moderator? + + # Render the result + respond_to do |format| + format.xml + format.rss + format.json + format.gpx + end + end + ## # Create a new note def create @@ -87,6 +108,36 @@ module Api end end + ## + # Delete (hide) a note + def destroy + # Check the arguments are sane + raise OSM::APIBadUserInput, "No id was given" unless params[:id] + + # Extract the arguments + id = params[:id].to_i + comment = params[:text] + + # Find the note and check it is valid + @note = Note.find(id) + raise OSM::APINotFoundError unless @note + raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? + + # Mark the note as hidden + Note.transaction do + @note.status = "hidden" + @note.save + + add_comment(@note, comment, "hidden", :notify => false) + end + + # Return a copy of the updated note + respond_to do |format| + format.xml { render :action => :show } + format.json { render :action => :show } + end + end + ## # Add a comment to an existing note def comment @@ -190,13 +241,17 @@ module Api bbox = BoundingBox.from_bbox_params(params) bbox.check_boundaries - bbox.check_size(MAX_NOTE_REQUEST_AREA) + bbox.check_size(Settings.max_note_request_area) notes = notes.bbox(bbox) + @min_lon = bbox.min_lon + @min_lat = bbox.min_lat + @max_lon = bbox.max_lon + @max_lat = bbox.max_lat end # Find the comments we want to return - @comments = NoteComment.where(:note_id => notes).order("created_at DESC").limit(result_limit).preload(:note) + @comments = NoteComment.where(:note => notes).order("created_at DESC").limit(result_limit).preload(:note) # Render the result respond_to do |format| @@ -204,56 +259,6 @@ module Api end end - ## - # Read a note - def show - # Check the arguments are sane - raise OSM::APIBadUserInput, "No id was given" unless params[:id] - - # Find the note and check it is valid - @note = Note.find(params[:id]) - raise OSM::APINotFoundError unless @note - raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? || current_user&.moderator? - - # Render the result - respond_to do |format| - format.xml - format.rss - format.json - format.gpx - end - end - - ## - # Delete (hide) a note - def destroy - # Check the arguments are sane - raise OSM::APIBadUserInput, "No id was given" unless params[:id] - - # Extract the arguments - id = params[:id].to_i - comment = params[:text] - - # Find the note and check it is valid - @note = Note.find(id) - raise OSM::APINotFoundError unless @note - raise OSM::APIAlreadyDeletedError.new("note", @note.id) unless @note.visible? - - # Mark the note as hidden - Note.transaction do - @note.status = "hidden" - @note.save - - add_comment(@note, comment, "hidden", false) - end - - # Return a copy of the updated note - respond_to do |format| - format.xml { render :action => :show } - format.json { render :action => :show } - end - end - ## # Return a list of notes matching a given string def search @@ -281,26 +286,45 @@ module Api # Add any date filter if params[:from] begin - from = Time.parse(params[:from]) + from = Time.parse(params[:from]).utc rescue ArgumentError raise OSM::APIBadUserInput, "Date #{params[:from]} is in a wrong format" end begin to = if params[:to] - Time.parse(params[:to]) + Time.parse(params[:to]).utc else - Time.now + Time.now.utc end rescue ArgumentError raise OSM::APIBadUserInput, "Date #{params[:to]} is in a wrong format" end - @notes = @notes.where(:created_at => from..to) + @notes = if params[:sort] == "updated_at" + @notes.where(:updated_at => from..to) + else + @notes.where(:created_at => from..to) + end end + # Choose the sort order + @notes = if params[:sort] == "created_at" + if params[:order] == "oldest" + @notes.order("created_at ASC") + else + @notes.order("created_at DESC") + end + else + if params[:order] == "oldest" + @notes.order("updated_at ASC") + else + @notes.order("updated_at DESC") + end + end + # Find the notes we want to return - @notes = @notes.order("updated_at DESC").limit(result_limit).preload(:comments) + @notes = @notes.distinct.limit(result_limit).preload(:comments) # Render the result respond_to do |format| @@ -321,13 +345,13 @@ module Api # Get the maximum number of results to return def result_limit if params[:limit] - if params[:limit].to_i.positive? && params[:limit].to_i <= 10000 + if params[:limit].to_i.positive? && params[:limit].to_i <= Settings.max_note_query_limit params[:limit].to_i else - raise OSM::APIBadUserInput, "Note limit must be between 1 and 10000" + raise OSM::APIBadUserInput, "Note limit must be between 1 and #{Settings.max_note_query_limit}" end else - 100 + Settings.default_note_query_limit end end @@ -336,9 +360,9 @@ module Api # on their status and the user's request parameters def closed_condition(notes) closed_since = if params[:closed] - params[:closed].to_i + params[:closed].to_i.days else - 7 + Note::DEFAULT_FRESHLY_CLOSED_LIMIT end if closed_since.negative? @@ -346,7 +370,7 @@ module Api elsif closed_since.positive? notes.where(:status => "open") .or(notes.where(:status => "closed") - .where(notes.arel_table[:closed_at].gt(Time.now - closed_since.days))) + .where(notes.arel_table[:closed_at].gt(Time.now.utc - closed_since))) else notes.where(:status => "open") end @@ -354,7 +378,7 @@ module Api ## # Add a comment to a note - def add_comment(note, text, event, notify = true) + def add_comment(note, text, event, notify: true) attributes = { :visible => true, :event => event, :body => text } if current_user @@ -366,7 +390,7 @@ module Api comment = note.comments.create!(attributes) note.comments.map(&:author).uniq.each do |user| - Notifier.note_comment_notification(comment, user).deliver_later if notify && user && user != current_user && user.visible? + UserMailer.note_comment_notification(comment, user).deliver_later if notify && user && user != current_user && user.visible? end end end