more segment bits
authorSteve Coast <steve@asklater.com>
Thu, 24 Aug 2006 19:09:23 +0000 (19:09 +0000)
committerSteve Coast <steve@asklater.com>
Thu, 24 Aug 2006 19:09:23 +0000 (19:09 +0000)
app/controllers/old_segment_controller.rb [new file with mode: 0644]
app/controllers/segment_controller.rb
app/helpers/old_segment_helper.rb [new file with mode: 0644]
app/models/old_segment.rb [new file with mode: 0644]
app/models/segment.rb
db/migrate/007_create_old_segments.rb [new file with mode: 0644]

diff --git a/app/controllers/old_segment_controller.rb b/app/controllers/old_segment_controller.rb
new file mode 100644 (file)
index 0000000..e07026f
--- /dev/null
@@ -0,0 +1,2 @@
+class OldSegmentController < ApplicationController
+end
index b6e0c661e08a6fb26eec380adc21528307a23464..21de13be84f56ab1bb2ce9d579c5886c167ed60a 100644 (file)
@@ -1,2 +1,74 @@
 class SegmentController < ApplicationController
 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
 end
diff --git a/app/helpers/old_segment_helper.rb b/app/helpers/old_segment_helper.rb
new file mode 100644 (file)
index 0000000..3650f0a
--- /dev/null
@@ -0,0 +1,2 @@
+module OldSegmentHelper
+end
diff --git a/app/models/old_segment.rb b/app/models/old_segment.rb
new file mode 100644 (file)
index 0000000..26e2b6a
--- /dev/null
@@ -0,0 +1,18 @@
+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
index 6e52a73ab557aeafd01957e6db834592f9fec2b9..19d7b2b636c738f1f5d4d41fcb2729e30813e27a 100644 (file)
@@ -1,2 +1,103 @@
 class Segment < ActiveRecord::Base
 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
 end
diff --git a/db/migrate/007_create_old_segments.rb b/db/migrate/007_create_old_segments.rb
new file mode 100644 (file)
index 0000000..6288ec0
--- /dev/null
@@ -0,0 +1,11 @@
+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