--- /dev/null
+class OldSegmentController < ApplicationController
+end
class SegmentController < ApplicationController
+
+ require 'xml/libxml'
+
+ before_filter :authorize
+
+ def create
+ if request.put?
+ segment = Segment.from_xml(request.raw_post, true)
+
+ if segment
+ segment.user_id = @user.id
+ if segment.save_with_history
+
+ render :text => segment.id
+ else
+ render :nothing => true, :status => 500
+ end
+ return
+
+ else
+ render :nothing => true, :status => 400 # if we got here the doc didnt parse
+ return
+ end
+ end
+
+ render :nothing => true, :status => 500 # something went very wrong
+ end
+
+ def rest
+ unless Segment.exists?(params[:id])
+ render :nothing => true, :status => 400
+ return
+ end
+
+ segment = Segment.find(params[:id])
+
+ case request.method
+
+ when :get
+ render :text => segment.to_xml.to_s
+ return
+
+ when :delete
+ if segment.visible
+ segment.visible = 0
+ segment.save_with_history
+ render :nothing => true
+ else
+ render :nothing => true, :status => 410
+ end
+
+ when :put
+ new_segment = Segment.from_xml(request.raw_post)
+
+ segment.timestamp = Time.now
+ segment.user_id = @user.id
+
+ segment.latitude = new_segment.latitude
+ segment.longitude = new_segment.longitude
+ segment.tags = new_segment.tags
+
+ if segment.id == new_segment.id and segment.save_with_history
+ render :nothing => true, :status => 200
+ else
+ render :nothing => true, :status => 500
+ end
+ return
+ end
+
+ end
+
+
end
--- /dev/null
+module OldSegmentHelper
+end
--- /dev/null
+class OldSegment < ActiveRecord::Base
+ set_table_name 'segments'
+
+ belongs_to :user
+
+ def self.from_segment(segment)
+ old_segment = OldSegment.new
+ old_segment.node_a = segment.node_a
+ old_segment.node_b = segment.node_b
+ old_segment.visible = segment.visible
+ old_segment.tags = segment.tags
+ old_segment.timestamp = segment.timestamp
+ old_segment.user_id = segment.user_id
+ old_segment.id = segment.id
+ return old_segment
+ end
+
+end
class Segment < ActiveRecord::Base
+ require 'xml/libxml'
+ set_table_name 'current_segments'
+
+ validates_numericality_of :segment_a
+ validates_numericality_of :segment_b
+ # FIXME validate a nd b exist and are visible
+
+ has_many :old_segments, :foreign_key => :id
+ belongs_to :user
+
+
+ def self.from_xml(xml, create=false)
+ p = XML::Parser.new
+ p.string = xml
+ doc = p.parse
+
+ segment = Segment.new
+
+ doc.find('//osm/segment').each do |pt|
+
+ segment.segment_a = pt['from'].to_i
+ segment.segment_b = pt['to'].to_i
+
+ if pt['id'] != '0'
+ segment.id = pt['id'].to_i
+ end
+
+ segment.visible = pt['visible'] == '1'
+
+ if create
+ segment.timestamp = Time.now
+ else
+ if pt['timestamp']
+ segment.timestamp = Time.parse(pt['timestamp'])
+ end
+ end
+
+ tags = []
+
+ pt.find('tag').each do |tag|
+ tags << [tag['k'],tag['v']]
+ end
+
+ tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';')
+ tags = '' if tags.nil?
+
+ segment.tags = tags
+
+ end
+ return segment
+ end
+
+ def save_with_history
+ begin
+ Segment.transaction do
+ old_segment = OldSegment.from_segment(self)
+ self.save
+ old_segment.save
+ end
+ return true
+ rescue Exception => ex
+ return nil
+ end
+ end
+
+ def to_xml
+ doc = XML::Document.new
+ doc.encoding = 'UTF-8'
+ root = XML::Segment.new 'osm'
+ root['version'] = '0.4'
+ root['generator'] = 'OpenStreetMap server'
+ doc.root = root
+ el1 = XML::Segment.new 'segment'
+ el1['id'] = self.id.to_s
+ el1['lat'] = self.latitude.to_s
+ el1['lon'] = self.longitude.to_s
+ split_tags(el1, self.tags)
+ el1['visible'] = self.visible.to_s
+ el1['timestamp'] = self.timestamp.xmlschema
+ root << el1
+ return doc
+ end
+
+ private
+ def split_tags(el, tags)
+ tags.split(';').each do |tag|
+ parts = tag.split('=')
+ key = ''
+ val = ''
+ key = parts[0].strip unless parts[0].nil?
+ val = parts[1].strip unless parts[1].nil?
+ if key != '' && val != ''
+ el2 = Segment.new('tag')
+ el2['k'] = key.to_s
+ el2['v'] = val.to_s
+ el << el2
+ end
+ end
+ end
+
+
end
--- /dev/null
+class CreateOldSegments < ActiveRecord::Migration
+ def self.up
+ create_table :old_segments do |t|
+ # t.column :name, :string
+ end
+ end
+
+ def self.down
+ drop_table :old_segments
+ end
+end