X-Git-Url: https://git.openstreetmap.org/rails.git/blobdiff_plain/40647c53dff5f04f0ecfd4db891c4d3bf76b4a8d..c54471ee33f79b7119eb284b03a845813a058876:/app/controllers/amf_controller.rb diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index ea58c2866..4103ceda0 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -130,7 +130,7 @@ class AmfController < ApplicationController # Start new changeset def startchangeset(usertoken, cstags, closeid, closecomment) - user = getuserid(usertoken) + user = getuser(usertoken) if !user then return -1,"You are not logged in, so Potlatch can't write any changes to the database." end # close previous changeset and add comment @@ -153,7 +153,7 @@ class AmfController < ApplicationController cs.user_id = user.id # smsm1 doesn't like the next two lines and thinks they need to be abstracted to the model more/better cs.created_at = Time.now - cs.closed_at = Time.new + Changeset::IDLE_TIMEOUT + cs.closed_at = cs.created_at + Changeset::IDLE_TIMEOUT cs.save_with_tags! return [0,cs.id] end @@ -284,7 +284,13 @@ class AmfController < ApplicationController # 3. hash of tags, # 4. version, # 5. is this the current, visible version? (boolean) - + # + # *** FIXME: + # Should work by timestamp, not version (so that we can recover versions when + # a node has been changed, but not the enclosing way) + # Use strptime (http://www.ruby-doc.org/core/classes/DateTime.html) to + # to turn string back into timestamp. + def getway_old(id, version) #:doc: if version < 0 old_way = OldWay.find(:first, :conditions => ['visible = ? AND id = ?', true, id], :order => 'version DESC') @@ -305,20 +311,49 @@ class AmfController < ApplicationController # Find history of a way. Returns 'way', id, and # an array of previous versions. + # + # *** FIXME: + # Should look for changes in constituent nodes as well, + # and return timestamps. + # Heuristic: Find all nodes that have ever been part of the way; + # get a list of their revision dates; add revision dates of the way; + # sort and collapse list (to within 2 seconds); trim all dates before the + # start dateÊof the way. def getway_history(wayid) #:doc: - begin - history = Way.find(wayid).old_ways.reverse.collect do |old_way| - user_object = old_way.changeset.user - user = user_object.data_public? ? user_object.display_name : 'anonymous' - uid = user_object.data_public? ? user_object.id : 0 - [old_way.version, old_way.timestamp.strftime("%d %b %Y, %H:%M"), old_way.visible ? 1 : 0, user, uid] + + # Find list of revision dates for way and all constituent nodes + revdates=[] + Way.find(wayid).old_ways.collect do |a| + revdates.push(a.timestamp) + a.nds.each do |n| + Node.find(n).old_nodes.collect do |o| + revdates.push(o.timestamp) + end end + end + waycreated=revdates[0] + revdates.uniq! + revdates.sort! - return ['way',wayid,history] - rescue ActiveRecord::RecordNotFound - return ['way', wayid, []] + # Remove any dates (from nodes) before first revision date of way + revdates.delete_if { |d| d0 then - gpx = Trace.find(searchterm.to_i, :conditions => ["visible=? AND (public=? OR user_id=?)",true,true,uid] ) + gpx = Trace.find(searchterm.to_i, :conditions => ["visible=? AND (public=? OR user_id=?)",true,true,user.id] ) if gpx then gpxs.push([gpx.id, gpx.name, gpx.description]) end else - Trace.find(:all, :limit => 21, :conditions => ["visible=? AND (public=? OR user_id=?) AND MATCH(name) AGAINST (?)",true,true,uid,searchterm] ).each do |gpx| + Trace.find(:all, :limit => 21, :conditions => ["visible=? AND (public=? OR user_id=?) AND MATCH(name) AGAINST (?)",true,true,user.id,searchterm] ).each do |gpx| gpxs.push([gpx.id, gpx.name, gpx.description]) end end @@ -403,7 +438,7 @@ class AmfController < ApplicationController # 2. new relation id. def putrelation(renumberednodes, renumberedways, usertoken, changeset, version, relid, tags, members, visible) #:doc: - user = getuserid(usertoken) + user = getuser(usertoken) if !user then return -1,"You are not logged in, so the relation could not be saved." end relid = relid.to_i @@ -458,12 +493,12 @@ class AmfController < ApplicationController return [0, relid, relation.id, relation.version] end rescue OSM::APIChangesetAlreadyClosedError => ex - return [-1, "The changeset #{ex.changeset.id} was closed at #{ex.changeset.closed_at}"] + return [-1, "The changeset #{ex.changeset.id} was closed at #{ex.changeset.closed_at}."] rescue OSM::APIVersionMismatchError => ex # Really need to check to see whether this is a server load issue, and the # last version was in the same changeset, or belongs to the same user, then # we can return something different - return [-3, "You have taken too long to edit, please reload the area"] + return [-3, "You have taken too long to edit, please reload the area."] rescue OSM::APIAlreadyDeletedError => ex return [-1, "The object has already been deleted"] rescue OSM::APIError => ex @@ -475,7 +510,7 @@ class AmfController < ApplicationController # version and no longer used are deleted. # # Parameters: - # 0. hash of renumbered nodes + # 0. hash of renumbered nodes (added by amf_controller) # 1. current user token (for authentication) # 2. current changeset # 3. new way version @@ -492,7 +527,7 @@ class AmfController < ApplicationController # 4. way version, # 5. hash of node versions (node=>version) - def putway(renumberednodes, usertoken, changeset, version, originalway, pointlist, attributes, nodes) #:doc: + def putway(renumberednodes, usertoken, changeset, wayversion, originalway, pointlist, attributes, nodes) #:doc: # -- Initialise @@ -501,22 +536,23 @@ class AmfController < ApplicationController if pointlist.length < 2 then return -2,"Server error - way is only #{points.length} points long." end originalway = originalway.to_i + pointlist.collect! {|a| a.to_i } + + way=nil # this is returned, so scope it outside the transaction + nodeversions = {} Way.transaction do # -- Get unique nodes if originalway <= 0 - way = nil uniques = [] else way = Way.find(originalway) uniques = way.unshared_node_ids end - new_way = Way.new - #Ê-- Update each changed node + #-- Update each changed node - nodeversions = {} nodes.each do |a| lon = a[0].to_f lat = a[1].to_f @@ -537,12 +573,12 @@ class AmfController < ApplicationController # We're creating the node node.create_with_history(user) renumberednodes[id] = node.id - nodeversions[id] = node.version + nodeversions[node.id] = node.version else # We're updating an existing node previous=Node.find(id) previous.update_from(node, user) - nodeversions[id] = previous.version + nodeversions[previous.id] = previous.version end end @@ -559,31 +595,37 @@ class AmfController < ApplicationController # -- Save revised way - if way.tags!=attributes or way.nds!=nodes or !way.visible? - new_way = Way.new - new_way.tags = attributes - new_way.nds = pointlist - new_way.changeset_id = changeset - new_way.version = version + pointlist.collect! {|a| + renumberednodes[a] ? renumberednodes[a]:a + } # renumber nodes + new_way = Way.new + new_way.tags = attributes + new_way.nds = pointlist + new_way.changeset_id = changeset + new_way.version = wayversion + if originalway <= 0 + new_way.create_with_history(user) + way=new_way # so we can get way.id and way.version + elsif way.tags!=attributes or way.nds!=pointlist or !way.visible? way.update_from(new_way, user) end end # transaction [0, originalway, way.id, renumberednodes, way.version, nodeversions] rescue OSM::APIChangesetAlreadyClosedError => ex - return [-1, "The changeset #{ex.changeset.id} was closed at #{ex.changeset.closed_at}"] + return [-2, "Sorry, your changeset #{ex.changeset.id} has been closed (at #{ex.changeset.closed_at})."] rescue OSM::APIVersionMismatchError => ex # Really need to check to see whether this is a server load issue, and the # last version was in the same changeset, or belongs to the same user, then # we can return something different return [-3, "Sorry, someone else has changed this way since you started editing - please reload the area"] rescue OSM::APITooManyWayNodesError => ex - return [-1, "You have tried to upload a way with #{ex.provided}, however only #{ex.max} are allowed."] + return [-1, "You have tried to upload a really long way with #{ex.provided} points: only #{ex.max} are allowed."] rescue OSM::APIAlreadyDeletedError => ex - return [-1, "The object has already been deleted"] + return [-1, "The object has already been deleted."] rescue OSM::APIError => ex # Some error that we don't specifically catch - return [-2, "Something really bad happened :-()"] + return [-2, "Something really bad happened :-(."] end # Save POI to the database. @@ -777,17 +819,6 @@ class AmfController < ApplicationController end return user end - - def getuserid(token) - user = getuser(token) - return user ? user.id : nil; - end - - # Compare two floating-point numbers to within 0.0000001 - - def fpcomp(a,b) #:doc: - return ((a/0.0000001).round==(b/0.0000001).round) - end # Send AMF response