]> git.openstreetmap.org Git - rails.git/blobdiff - app/controllers/api/notes_controller.rb
Improves dropping of first note's comment
[rails.git] / app / controllers / api / notes_controller.rb
index 7e2e7fb793babed86952313cc1d0703043d2f760..af0c5e0398a4265ff6e122f927668e69b6910e9b 100644 (file)
@@ -1,5 +1,7 @@
 module Api
   class NotesController < ApiController
 module Api
   class NotesController < ApiController
+    include QueryMethods
+
     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]
     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]
@@ -36,7 +38,9 @@ module Api
       @max_lat = bbox.max_lat
 
       # Find the notes we want to return
       @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)
+      notes = notes.bbox(bbox).order("updated_at DESC")
+      notes = query_limit(notes)
+      @notes = notes.preload(:comments)
 
       # Render the result
       respond_to do |format|
 
       # Render the result
       respond_to do |format|
@@ -81,19 +85,22 @@ module Api
       # Extract the arguments
       lon = OSM.parse_float(params[:lon], OSM::APIBadUserInput, "lon was not a number")
       lat = OSM.parse_float(params[:lat], OSM::APIBadUserInput, "lat was not a number")
       # Extract the arguments
       lon = OSM.parse_float(params[:lon], OSM::APIBadUserInput, "lon was not a number")
       lat = OSM.parse_float(params[:lat], OSM::APIBadUserInput, "lat was not a number")
-      comment = params[:text]
+      description = params[:text]
+
+      # Get note's author info (for logged in users - user_id, for logged out users - IP address)
+      note_author_info = author_info
 
       # Include in a transaction to ensure that there is always a note_comment for every note
       Note.transaction do
         # Create the note
 
       # Include in a transaction to ensure that there is always a note_comment for every note
       Note.transaction do
         # Create the note
-        @note = Note.create(:lat => lat, :lon => lon)
+        @note = Note.create(:lat => lat, :lon => lon, :description => description, :user_id => note_author_info[:user_id], :user_ip => note_author_info[:user_ip])
         raise OSM::APIBadUserInput, "The note is outside this world" unless @note.in_world?
 
         # Save the note
         @note.save!
 
         raise OSM::APIBadUserInput, "The note is outside this world" unless @note.in_world?
 
         # Save the note
         @note.save!
 
-        # Add a comment to the note
-        add_comment(@note, comment, "opened")
+        # Add opening comment (description) to the note
+        add_comment(@note, description, "opened")
       end
 
       # Return a copy of the new note
       end
 
       # Return a copy of the new note
@@ -231,8 +238,9 @@ module Api
 
       # Find the comments we want to return
       @comments = NoteComment.where(:note => notes)
 
       # Find the comments we want to return
       @comments = NoteComment.where(:note => notes)
-                             .order(:created_at => :desc).limit(result_limit)
-                             .preload(:author, :note => { :comments => :author })
+                             .order(:created_at => :desc)
+      @comments = query_limit(@comments)
+      @comments = @comments.preload(:author, :note => { :comments => :author })
 
       # Render the result
       respond_to do |format|
 
       # Render the result
       respond_to do |format|
@@ -248,47 +256,21 @@ module Api
       @notes = bbox_condition(@notes)
 
       # Add any user filter
       @notes = bbox_condition(@notes)
 
       # Add any user filter
-      if params[:display_name] || params[:user]
-        if params[:display_name]
-          @user = User.find_by(:display_name => params[:display_name])
-
-          raise OSM::APIBadUserInput, "User #{params[:display_name]} not known" unless @user
-        else
-          @user = User.find_by(:id => params[:user])
-
-          raise OSM::APIBadUserInput, "User #{params[:user]} not known" unless @user
-        end
-
-        @notes = @notes.joins(:comments).where(:note_comments => { :author_id => @user })
-      end
+      user = query_conditions_user_value
+      @notes = @notes.joins(:comments).where(:note_comments => { :author_id => user }) if user
 
       # Add any text filter
 
       # Add any text filter
-      @notes = @notes.joins(:comments).where("to_tsvector('english', note_comments.body) @@ plainto_tsquery('english', ?)", params[:q]) if params[:q]
+      if params[:q]
+        @notes = @notes.joins(:comments).where("to_tsvector('english', note_comments.body) @@ plainto_tsquery('english', ?) OR to_tsvector('english', notes.description) @@ plainto_tsquery('english', ?)", params[:q], params[:q])
+      end
 
       # Add any date filter
 
       # Add any date filter
-      if params[:from]
-        begin
-          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]).utc
-               else
-                 Time.now.utc
-               end
-        rescue ArgumentError
-          raise OSM::APIBadUserInput, "Date #{params[:to]} is in a wrong format"
-        end
-
-        @notes = if params[:sort] == "updated_at"
-                   @notes.where(:updated_at => from..to)
-                 else
-                   @notes.where(:created_at => from..to)
-                 end
-      end
+      time_filter_property = if params[:sort] == "updated_at"
+                               :updated_at
+                             else
+                               :created_at
+                             end
+      @notes = query_conditions_time(@notes, time_filter_property)
 
       # Choose the sort order
       @notes = if params[:sort] == "created_at"
 
       # Choose the sort order
       @notes = if params[:sort] == "created_at"
@@ -306,7 +288,8 @@ module Api
                end
 
       # Find the notes we want to return
                end
 
       # Find the notes we want to return
-      @notes = @notes.distinct.limit(result_limit).preload(:comments)
+      @notes = query_limit(@notes.distinct)
+      @notes = @notes.preload(:comments)
 
       # Render the result
       respond_to do |format|
 
       # Render the result
       respond_to do |format|
@@ -323,20 +306,6 @@ module Api
     # utility functions below.
     #------------------------------------------------------------
 
     # utility functions below.
     #------------------------------------------------------------
 
-    ##
-    # Get the maximum number of results to return
-    def result_limit
-      if params[:limit]
-        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 #{Settings.max_note_query_limit}"
-        end
-      else
-        Settings.default_note_query_limit
-      end
-    end
-
     ##
     # Generate a condition to choose which notes we want based
     # on their status and the user's request parameters
     ##
     # Generate a condition to choose which notes we want based
     # on their status and the user's request parameters
@@ -379,21 +348,28 @@ module Api
       end
     end
 
       end
     end
 
+    ##
+    # Get author's information (for logged in users - user_id, for logged out users - IP address)
+    def author_info
+      if current_user
+        { :user_id => current_user.id }
+      else
+        { :user_ip => request.remote_ip }
+      end
+    end
+
     ##
     # Add a comment to a note
     def add_comment(note, text, event, notify: true)
       attributes = { :visible => true, :event => event, :body => text }
 
     ##
     # Add a comment to a note
     def add_comment(note, text, event, notify: true)
       attributes = { :visible => true, :event => event, :body => text }
 
-      if doorkeeper_token
-        author = current_user if scope_enabled?(:write_notes)
-      else
-        author = current_user
-      end
+      # Get note comment's author info (for logged in users - user_id, for logged out users - IP address)
+      note_comment_author_info = author_info
 
 
-      if author
-        attributes[:author_id] = author.id
+      if note_comment_author_info[:user_ip].nil?
+        attributes[:author_id] = note_comment_author_info[:user_id]
       else
       else
-        attributes[:author_ip] = request.remote_ip
+        attributes[:author_ip] = note_comment_author_info[:user_ip]
       end
 
       comment = note.comments.create!(attributes)
       end
 
       comment = note.comments.create!(attributes)