]> git.openstreetmap.org Git - rails.git/blobdiff - app/controllers/api/traces_controller.rb
Merge pull request #5390 from AntonKhorev/trace-resourceful-routes
[rails.git] / app / controllers / api / traces_controller.rb
index 88b6edc67903782a0e7b90d4a5d0aa269b8a30b2..e91261058efe05db7500626deacec804f562d581 100644 (file)
@@ -1,74 +1,21 @@
 module Api
   class TracesController < ApiController
-    layout "site", :except => :georss
-
-    before_action :authorize_web
+    before_action :check_api_writable, :only => [:create, :update, :destroy]
     before_action :set_locale
     before_action :authorize
-    before_action :api_deny_access_handler
 
     authorize_resource
 
-    before_action :check_database_readable, :except => [:api_read, :api_data]
-    before_action :check_database_writable, :only => [:api_create, :api_update, :api_delete]
-    before_action :check_api_readable, :only => [:api_read, :api_data]
-    before_action :check_api_writable, :only => [:api_create, :api_update, :api_delete]
-    before_action :offline_redirect, :only => [:api_create, :api_delete, :api_data]
-    around_action :api_call_handle_error
-
-    def api_read
-      trace = Trace.visible.find(params[:id])
+    before_action :offline_error, :only => [:create, :destroy]
+    skip_around_action :api_call_timeout, :only => :create
 
-      if trace.public? || trace.user == current_user
-        render :xml => trace.to_xml.to_s
-      else
-        head :forbidden
-      end
-    end
-
-    def api_update
-      trace = Trace.visible.find(params[:id])
-
-      if trace.user == current_user
-        trace.update_from_xml(request.raw_post)
-        trace.save!
-
-        head :ok
-      else
-        head :forbidden
-      end
-    end
-
-    def api_delete
-      trace = Trace.visible.find(params[:id])
-
-      if trace.user == current_user
-        trace.visible = false
-        trace.save!
-
-        head :ok
-      else
-        head :forbidden
-      end
-    end
-
-    def api_data
-      trace = Trace.visible.find(params[:id])
+    def show
+      @trace = Trace.visible.find(params[:id])
 
-      if trace.public? || trace.user == current_user
-        if request.format == Mime[:xml]
-          send_data(trace.xml_file.read, :filename => "#{trace.id}.xml", :type => request.format.to_s, :disposition => "attachment")
-        elsif request.format == Mime[:gpx]
-          send_data(trace.xml_file.read, :filename => "#{trace.id}.gpx", :type => request.format.to_s, :disposition => "attachment")
-        else
-          send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => "attachment")
-        end
-      else
-        head :forbidden
-      end
+      head :forbidden unless @trace.public? || @trace.user == current_user
     end
 
-    def api_create
+    def create
       tags = params[:tags] || ""
       description = params[:description] || ""
       visibility = params[:visibility]
@@ -85,6 +32,7 @@ module Api
         trace = do_create(params[:file], tags, description, visibility)
 
         if trace.id
+          trace.schedule_import
           render :plain => trace.id.to_s
         elsif trace.valid?
           head :internal_server_error
@@ -96,18 +44,39 @@ module Api
       end
     end
 
+    def update
+      trace = Trace.visible.find(params[:id])
+
+      if trace.user == current_user
+        trace.update_from_xml(request.raw_post)
+        trace.save!
+
+        head :ok
+      else
+        head :forbidden
+      end
+    end
+
+    def destroy
+      trace = Trace.visible.find(params[:id])
+
+      if trace.user == current_user
+        trace.visible = false
+        trace.save!
+        trace.schedule_destruction
+
+        head :ok
+      else
+        head :forbidden
+      end
+    end
+
     private
 
     def do_create(file, tags, description, visibility)
       # Sanitise the user's filename
       name = file.original_filename.gsub(/[^a-zA-Z0-9.]/, "_")
 
-      # Get a temporary filename...
-      filename = "/tmp/#{rand}"
-
-      # ...and save the uploaded file to that location
-      File.open(filename, "wb") { |f| f.write(file.read) }
-
       # Create the trace object, falsely marked as already
       # inserted to stop the import daemon trying to load it
       trace = Trace.new(
@@ -115,43 +84,17 @@ module Api
         :tagstring => tags,
         :description => description,
         :visibility => visibility,
-        :inserted => true,
+        :inserted => false,
         :user => current_user,
-        :timestamp => Time.now.getutc
+        :timestamp => Time.now.utc,
+        :file => file
       )
 
-      if trace.valid?
-        Trace.transaction do
-          begin
-            # Save the trace object
-            trace.save!
-
-            # Rename the temporary file to the final name
-            FileUtils.mv(filename, trace.trace_name)
-          rescue StandardError
-            # Remove the file as we have failed to update the database
-            FileUtils.rm_f(filename)
-
-            # Pass the exception on
-            raise
-          end
-
-          begin
-            # Clear the inserted flag to make the import daemon load the trace
-            trace.inserted = false
-            trace.save!
-          rescue StandardError
-            # Remove the file as we have failed to update the database
-            FileUtils.rm_f(trace.trace_name)
-
-            # Pass the exception on
-            raise
-          end
-        end
-      end
+      # Save the trace object
+      trace.save!
 
       # Finally save the user's preferred privacy level
-      if pref = current_user.preferences.where(:k => "gps.trace.visibility").first
+      if pref = current_user.preferences.find_by(:k => "gps.trace.visibility")
         pref.v = visibility
         pref.save
       else
@@ -161,8 +104,8 @@ module Api
       trace
     end
 
-    def offline_redirect
-      redirect_to :action => :offline if Settings.status == "gpx_offline"
+    def offline_error
+      report_error "GPX files offline for maintenance", :service_unavailable if Settings.status == "gpx_offline"
     end
   end
 end