1 class TraceController < ApplicationController
2 before_filter :authorize_web
3 before_filter :authorize, :only => [:api_details, :api_data, :api_create]
6 # Counts and selects pages of GPX traces for various criteria (by user, tags, public etc.).
7 # target_user - if set, specifies the user to fetch traces for. if not set will fetch all traces
8 def list (target_user = nil)
9 # from display name, pick up user id if one user's traces only
10 display_name = params[:display_name]
11 if target_user.nil? and !display_name.blank?
12 @display_name = display_name
13 @title += " from #{@display_name}"
14 target_user = User.find(:first, :conditions => [ "display_name = ?", display_name])
19 @title = "public GPS traces"
20 elsif target_user.id == @user.id
21 @title = "your GPS traces"
23 @title = "public GPS traces from #{target_user.display_name}"
26 @title += " tagged with #{params[:tag]}" if params[:tag]
29 opt[:include] = [:user, :tags] # load users and tags from db at same time as traces
32 # 1 - all traces, logged in = all public traces + all user's (i.e + all mine)
33 # 2 - all traces, not logged in = all public traces
34 # 3 - user's traces, logged in as same user = all user's traces
35 # 4 - user's traces, not logged in as that user = all user's public traces
36 if target_user.nil? # all traces
38 conditions = ["(public = 1 OR user_id = ?)", @user.id] #1
40 conditions = ["public = 1"] #2
43 if @user and @user.id == target_user.id
44 conditions = ["user_id = ?", @user.id] #3 (check vs user id, so no join + can't pick up non-public traces by changing name)
46 conditions = ["public = 1 AND user_id = ?", target_user.id] #4
49 conditions[0] += " AND users.display_name != ''" # users need to set display name before traces will be exposed
51 opt[:order] = 'timestamp DESC'
54 conditions[0] += " AND gpx_file_tags.tag = ?"
58 opt[:conditions] = conditions
61 @trace_pages, @traces = paginate(:traces, opt)
63 # put together SET of tags across traces, for related links
66 @traces.each do |trace|
67 trace.tags.reload if params[:tag] # if searched by tag, ActiveRecord won't bring back other tags, so do explicitly here
68 trace.tags.each do |tag|
69 tagset[tag.tag] = tag.tag
74 # final helper vars for view
75 @display_name = display_name
76 @all_tags = tagset.values
81 list(@user) unless @user.nil?
83 redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri
88 @trace = Trace.find(params[:id])
91 render :nothing, :status => :forbidden if @trace.user.id != @user.id
94 rescue ActiveRecord::RecordNotFound
95 render :nothing => true, :status => :not_found
99 name = params[:trace][:gpx_file].original_filename.gsub(/[^a-zA-Z0-9.]/, '_') # This makes sure filenames are sane
101 do_create(name, params[:trace][:tagstring], params[:trace][:description], params[:trace][:public]) do |f|
102 f.write(params[:trace][:gpx_file].read)
106 logger.info("id is #{@trace.id}")
107 flash[:notice] = "Your GPX file has been uploaded and is awaiting insertion in to the database. This will usually happen within half an hour, and an email will be sent to you on completion."
109 redirect_to :action => 'mine'
114 trace = Trace.find(params[:id])
115 if trace and (trace.public? or (@user and @user == trace.user))
116 send_file(trace.trace_name, :filename => "#{trace.id}#{trace.extension_name}", :type => trace.mime_type, :disposition => 'attachment')
118 render :nothing, :status => :not_found
123 trace = Trace.find(params[:id])
124 if @user and trace.user == @user and !trace.public
127 flash[:notice] = 'Track made public'
128 redirect_to :controller => 'trace', :action => 'view', :id => params[:id]
133 traces = Trace.find(:all, :conditions => ['public = true'], :order => 'timestamp DESC', :limit => 20)
135 rss = OSM::GeoRSS.new
137 #def add(latitude=0, longitude=0, title_text='dummy title', url='http://www.example.com/', description_text='dummy description', timestamp=Time.now)
138 traces.each do |trace|
139 rss.add(trace.latitude, trace.longitude, trace.name, url_for({:controller => 'trace', :action => 'view', :id => trace.id, :display_name => trace.user.display_name}), "<img src='#{url_for({:controller => 'trace', :action => 'icon', :id => trace.id, :user_login => trace.user.display_name})}'> GPX file with #{trace.size} points from #{trace.user.display_name}", trace.timestamp)
142 render :text => rss.to_s, :content_type => "application/rss+xml"
147 trace = Trace.find(params[:id])
149 if trace.public? or (@user and @user == trace.user)
150 send_file(trace.large_picture_name, :filename => "#{trace.id}.gif", :type => 'image/gif', :disposition => 'inline')
152 render :nothing, :status => :forbidden
154 rescue ActiveRecord::RecordNotFound
155 render :nothing => true, :status => :not_found
157 render :nothing => true, :status => :internal_server_error
163 trace = Trace.find(params[:id])
165 if trace.public? or (@user and @user == trace.user)
166 send_file(trace.icon_picture_name, :filename => "#{trace.id}_icon.gif", :type => 'image/gif', :disposition => 'inline')
168 render :nothing, :status => :forbidden
170 rescue ActiveRecord::RecordNotFound
171 render :nothing => true, :status => :not_found
173 render :nothing => true, :status => :internal_server_error
179 trace = Trace.find(params[:id])
181 if trace.public? or trace.user == @user
182 render :text => trace.to_xml.to_s, :content_type => "text/xml"
184 render :nothing => true, :status => :forbidden
186 rescue ActiveRecord::RecordNotFound
187 render :nothing => true, :status => :not_found
189 render :nothing => true, :status => :internal_server_error
194 render :action => 'data'
198 do_create(params[:filename], params[:tags], params[:description], true) do |f|
199 f.write(request.raw_post)
203 render :nothing => true
205 render :nothing => true, :status => :internal_server_error
211 def do_create(name, tags, description, public)
212 filename = "/tmp/#{rand}"
214 File.open(filename, "w") { |f| yield f }
216 @trace = Trace.new({:name => name, :tagstring => tags,
217 :description => description, :public => public})
218 @trace.inserted = false
220 @trace.timestamp = Time.now
223 File.rename(filename, @trace.trace_name)
225 FileUtils.rm_f(filename)