X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/aacc7ae3e0d8b9d0a1a46b4fc14355868d640306..a7f00eefc4842a87c9076cac8b70fab5149a732b:/app/controllers/trace_controller.rb
diff --git a/app/controllers/trace_controller.rb b/app/controllers/trace_controller.rb
index 2d4a26c29..3b3097755 100644
--- a/app/controllers/trace_controller.rb
+++ b/app/controllers/trace_controller.rb
@@ -5,24 +5,23 @@ class TraceController < ApplicationController
# Counts and selects pages of GPX traces for various criteria (by user, tags, public etc.).
# target_user - if set, specifies the user to fetch traces for. if not set will fetch all traces
- # paging_action - the action that will be linked back to from view
- def list (target_user = nil, paging_action = 'list')
- @title = 'public GPS traces'
- @title += " tagged with #{params[:tag]}" if params[:tag]
- @traces_per_page = 20
- page_index = params[:page] ? params[:page].to_i - 1 : 0 # nice 1-based page -> 0-based page index
-
+ def list(target_user = nil, action = "list")
# from display name, pick up user id if one user's traces only
display_name = params[:display_name]
- if target_user.nil? and display_name and display_name != ''
- @paging_action = 'view'
- @display_name = display_name
- @title += " from #{@display_name}"
+ if target_user.nil? and !display_name.blank?
target_user = User.find(:first, :conditions => [ "display_name = ?", display_name])
end
- opt = Hash.new
- opt[:include] = [:user, :tags] # load users and tags from db at same time as traces
+ # set title
+ if target_user.nil?
+ @title = "Public GPS traces"
+ elsif @user and @user.id == target_user.id
+ @title = "Your GPS traces"
+ else
+ @title = "Public GPS traces from #{target_user.display_name}"
+ end
+
+ @title += " tagged with #{params[:tag]}" if params[:tag]
# four main cases:
# 1 - all traces, logged in = all public traces + all user's (i.e + all mine)
@@ -31,40 +30,32 @@ class TraceController < ApplicationController
# 4 - user's traces, not logged in as that user = all user's public traces
if target_user.nil? # all traces
if @user
- conditions = ["(public = 1 OR user_id = ?)", @user.id] #1
+ conditions = ["(gpx_files.public = 1 OR gpx_files.user_id = ?)", @user.id] #1
else
- conditions = ["public = 1"] #2
+ conditions = ["gpx_files.public = 1"] #2
end
else
if @user and @user.id == target_user.id
- conditions = ["user_id = ?", @user.id] #3 (check vs user id, so no join + can't pick up non-public traces by changing name)
+ conditions = ["gpx_files.user_id = ?", @user.id] #3 (check vs user id, so no join + can't pick up non-public traces by changing name)
else
- conditions = ["public = 1 AND user_id = ?", target_user.id] #4
+ conditions = ["gpx_files.public = 1 AND gpx_files.user_id = ?", target_user.id] #4
end
end
- conditions[0] += " AND users.display_name != ''" # users need to set display name before traces will be exposed
- opt[:order] = 'timestamp DESC'
if params[:tag]
@tag = params[:tag]
- conditions[0] += " AND gpx_file_tags.tag = ?"
- conditions << @tag;
+ conditions[0] += " AND EXISTS (SELECT * FROM gpx_file_tags AS gft WHERE gft.gpx_id = gpx_files.id AND gft.tag = ?)"
+ conditions << @tag
end
- opt[:conditions] = conditions
+ conditions[0] += " AND gpx_files.visible = 1"
- # count traces using all options except limit
- @max_trace = Trace.count(opt)
- @max_page = Integer((@max_trace + 1) / @traces_per_page)
-
- # last step before fetch - add paging options
- opt[:limit] = @traces_per_page
- if page_index > 0
- opt[:offset] = @traces_per_page * page_index
- end
+ @trace_pages, @traces = paginate(:traces,
+ :include => [:user, :tags],
+ :conditions => conditions,
+ :order => "gpx_files.timestamp DESC",
+ :per_page => 20)
- @traces = Trace.find(:all , opt)
-
# put together SET of tags across traces, for related links
tagset = Hash.new
if @traces
@@ -77,15 +68,14 @@ class TraceController < ApplicationController
end
# final helper vars for view
- @display_name = display_name
+ @action = action
+ @display_name = target_user.display_name if target_user
@all_tags = tagset.values
- @paging_action = paging_action # the action that paging requests should route back to, e.g. 'list' or 'mine'
- @page = page_index + 1 # nice 1-based external page numbers
end
def mine
if @user
- list(@user, 'mine') unless @user.nil?
+ list(@user, "mine") unless @user.nil?
else
redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri
end
@@ -93,17 +83,20 @@ class TraceController < ApplicationController
def view
@trace = Trace.find(params[:id])
- unless @trace.public
- if @user
- render :nothing, :status => :forbidden if @trace.user.id != @user.id
- end
+ @title = "Viewing trace #{@trace.name}"
+ if !@trace.visible?
+ render :nothing => true, :status => :not_found
+ elsif !@trace.public? and @trace.user.id != @user.id
+ render :nothing => true, :status => :forbidden
end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
end
def create
name = params[:trace][:gpx_file].original_filename.gsub(/[^a-zA-Z0-9.]/, '_') # This makes sure filenames are sane
- do_create(name, params[:trace][:tagstring], params[:trace][:description]) do |f|
+ do_create(name, params[:trace][:tagstring], params[:trace][:description], params[:trace][:public]) do |f|
f.write(params[:trace][:gpx_file].read)
end
@@ -117,108 +110,164 @@ class TraceController < ApplicationController
def data
trace = Trace.find(params[:id])
- if trace and (trace.public? or (@user and @user == trace.user))
- send_file(trace.trace_name, :filename => "#{trace.id}.gpx", :type => trace.mime_type, :disposition => 'attachment')
+
+ if trace.visible? and (trace.public? or (@user and @user == trace.user))
+ send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => 'attachment')
else
render :nothing, :status => :not_found
end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
+ end
+
+ def delete
+ trace = Trace.find(params[:id])
+
+ if @user and trace.user == @user
+ if request.post? and trace.visible?
+ trace.visible = false
+ trace.save
+ flash[:notice] = 'Track scheduled for deletion'
+ redirect_to :controller => 'traces', :action => 'mine'
+ else
+ render :nothing, :status => :bad_request
+ end
+ else
+ render :nothing, :status => :forbidden
+ end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
end
def make_public
trace = Trace.find(params[:id])
- if @user and trace.user == @user and !trace.public
- trace.public = true
- trace.save
- flash[:notice] = 'Track made public'
- redirect_to :controller => 'trace', :action => 'view', :id => params[:id]
+
+ if @user and trace.user == @user
+ if request.post? and !trace.public?
+ trace.public = true
+ trace.save
+ flash[:notice] = 'Track made public'
+ redirect_to :controller => 'trace', :action => 'view', :id => params[:id]
+ else
+ render :nothing, :status => :bad_request
+ end
+ else
+ render :nothing, :status => :forbidden
end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
end
def georss
- traces = Trace.find(:all, :conditions => ['public = true'], :order => 'timestamp DESC', :limit => 20)
+ conditions = ["gpx_files.public = 1"]
+
+ if params[:display_name]
+ conditions[0] += " AND users.display_name = ?"
+ conditions << params[:display_name]
+ end
+
+ if params[:tag]
+ conditions[0] += " AND EXISTS (SELECT * FROM gpx_file_tags AS gft WHERE gft.gpx_id = gpx_files.id AND gft.tag = ?)"
+ conditions << params[:tag]
+ end
+
+ traces = Trace.find(:all, :include => :user, :conditions => conditions,
+ :order => "timestamp DESC", :limit => 20)
rss = OSM::GeoRSS.new
- #def add(latitude=0, longitude=0, title_text='dummy title', url='http://www.example.com/', description_text='dummy description', timestamp=Time.now)
traces.each do |trace|
- rss.add(trace.latitude, trace.longitude, trace.name, url_for({:controller => 'trace', :action => 'view', :id => trace.id, :display_name => trace.user.display_name}), " 'icon', :id => trace.id, :user_login => trace.user.display_name})}'> GPX file with #{trace.size} points from #{trace.user.display_name}", trace.timestamp)
+ rss.add(trace.latitude, trace.longitude, trace.name, trace.user.display_name, url_for({:controller => 'trace', :action => 'view', :id => trace.id, :display_name => trace.user.display_name}), " 'icon', :id => trace.id, :user_login => trace.user.display_name})}'> GPX file with #{trace.size} points from #{trace.user.display_name}", trace.timestamp)
end
render :text => rss.to_s, :content_type => "application/rss+xml"
end
def picture
- begin
- trace = Trace.find(params[:id])
+ trace = Trace.find(params[:id])
+ if trace.inserted?
if trace.public? or (@user and @user == trace.user)
send_file(trace.large_picture_name, :filename => "#{trace.id}.gif", :type => 'image/gif', :disposition => 'inline')
else
render :nothing, :status => :forbidden
end
- rescue ActiveRecord::RecordNotFound
+ else
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
end
def icon
- begin
- trace = Trace.find(params[:id])
+ trace = Trace.find(params[:id])
+ if trace.inserted?
if trace.public? or (@user and @user == trace.user)
send_file(trace.icon_picture_name, :filename => "#{trace.id}_icon.gif", :type => 'image/gif', :disposition => 'inline')
else
render :nothing, :status => :forbidden
end
- rescue ActiveRecord::RecordNotFound
+ else
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
end
def api_details
- begin
- trace = Trace.find(params[:id])
+ trace = Trace.find(params[:id])
- if trace.public? or trace.user == @user
- render :text => trace.to_xml.to_s, :content_type => "text/xml"
- else
- render :nothing => true, :status => :forbidden
- end
- rescue ActiveRecord::RecordNotFound
- render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
+ if trace.public? or trace.user == @user
+ render :text => trace.to_xml.to_s, :content_type => "text/xml"
+ else
+ render :nothing => true, :status => :forbidden
end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
end
def api_data
- render :action => 'data'
+ trace = Trace.find(params[:id])
+
+ if trace.public? or trace.user == @user
+ send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => 'attachment')
+ else
+ render :nothing => true, :status => :forbidden
+ end
+ rescue ActiveRecord::RecordNotFound
+ render :nothing => true, :status => :not_found
end
def api_create
- do_create(params[:filename], params[:tags], params[:description]) do |f|
- f.write(request.raw_post)
- end
+ if request.post?
+ name = params[:file].original_filename.gsub(/[^a-zA-Z0-9.]/, '_') # This makes sure filenames are sane
- if @trace.id
- render :nothing => true
+ do_create(name, params[:tags], params[:description], params[:public]) do |f|
+ f.write(params[:file].read)
+ end
+
+ if @trace.id
+ render :text => @trace.id.to_s, :content_type => "text/plain"
+ elsif @trace.valid?
+ render :nothing => true, :status => :internal_server_error
+ else
+ render :nothing => true, :status => :bad_request
+ end
else
- render :nothing => true, :status => :internal_server_error
+ render :nothing => true, :status => :method_not_allowed
end
end
private
- def do_create(name, tags, description)
+ def do_create(name, tags, description, public)
filename = "/tmp/#{rand}"
File.open(filename, "w") { |f| yield f }
- @trace = Trace.new({:name => name, :tagstring => tags, :description => description})
+ @trace = Trace.new({:name => name, :tagstring => tags,
+ :description => description, :public => public})
@trace.inserted = false
@trace.user = @user
@trace.timestamp = Time.now