d3a1b039f557b2afc129f050106b5282db23b897
[rails.git] / app / controllers / way_controller.rb
1 class WayController < ApplicationController
2   require 'xml/libxml'
3
4   session :off
5   before_filter :authorize, :only => [:create, :update, :delete]
6   before_filter :check_write_availability, :only => [:create, :update, :delete]
7   before_filter :check_read_availability, :except => [:create, :update, :delete]
8   after_filter :compress_output
9
10   def create
11     if request.put?
12       way = Way.from_xml(request.raw_post, true)
13
14       if way
15         if !way.preconditions_ok?
16           render :text => "", :status => :precondition_failed
17         else
18           way.version = 0
19           way.user_id = @user.id
20           way.save_with_history!
21
22           render :text => way.id.to_s, :content_type => "text/plain"
23         end
24       else
25         render :nothing => true, :status => :bad_request
26       end
27     else
28       render :nothing => true, :status => :method_not_allowed
29     end
30   end
31
32   def read
33     begin
34       way = Way.find(params[:id])
35
36       response.headers['Last-Modified'] = way.timestamp.rfc822
37
38       if way.visible
39         render :text => way.to_xml.to_s, :content_type => "text/xml"
40       else
41         render :text => "", :status => :gone
42       end
43     rescue ActiveRecord::RecordNotFound
44       render :nothing => true, :status => :not_found
45     end
46   end
47
48   def update
49     begin
50       way = Way.find(params[:id])
51       new_way = Way.from_xml(request.raw_post)
52       if new_way.version != way.version
53         render :text => "Version mismatch: Provided " + new_way.version.to_s + ", server had: " + way.version.to_s, :status => :bad_request
54         return
55       end  
56         
57
58       if new_way and new_way.id == way.id
59         way.update_from(new_way, @user)
60         render :text => way.version.to_s, :content_type => "text/plain"
61       else
62         render :nothing => true, :status => :bad_request
63       end
64     rescue OSM::APIPreconditionFailedError
65       render :text => "", :status => :precondition_failed
66     rescue ActiveRecord::RecordNotFound
67       render :nothing => true, :status => :not_found
68     end
69   end
70
71   # This is the API call to delete a way
72   def delete
73     begin
74       way = Way.find(params[:id])
75       way.delete_with_relations_and_history(@user)
76
77       # if we get here, all is fine, otherwise something will catch below.  
78       render :nothing => true
79     rescue OSM::APIAlreadyDeletedError
80       render :text => "", :status => :gone
81     rescue OSM::APIPreconditionFailedError
82       render :text => "", :status => :precondition_failed
83     rescue ActiveRecord::RecordNotFound
84       render :nothing => true, :status => :not_found
85     end
86   end
87
88   def full
89     begin
90       way = Way.find(params[:id])
91
92       if way.visible
93         nd_ids = way.nds + [-1]
94         nodes = Node.find(:all, :conditions => "visible = 1 AND id IN (#{nd_ids.join(',')})")
95
96         # Render
97         doc = OSM::API.new.get_xml_doc
98         nodes.each do |node|
99           doc.root << node.to_xml_node()
100         end
101         doc.root << way.to_xml_node()
102
103         render :text => doc.to_s, :content_type => "text/xml"
104       else
105         render :text => "", :status => :gone
106       end
107     rescue ActiveRecord::RecordNotFound
108       render :nothing => true, :status => :not_found
109     end
110   end
111
112   def ways
113     begin
114       ids = params['ways'].split(',').collect { |w| w.to_i }
115     rescue
116       ids = []
117     end
118
119     if ids.length > 0
120       doc = OSM::API.new.get_xml_doc
121
122       Way.find(ids).each do |way|
123         doc.root << way.to_xml_node
124       end
125
126       render :text => doc.to_s, :content_type => "text/xml"
127     else
128       render :nothing => true, :status => :bad_request
129     end
130   end
131
132   def ways_for_node
133     wayids = WayNode.find(:all, :conditions => ['node_id = ?', params[:id]]).collect { |ws| ws.id[0] }.uniq
134
135     doc = OSM::API.new.get_xml_doc
136
137     Way.find(wayids).each do |way|
138       doc.root << way.to_xml_node
139     end
140
141     render :text => doc.to_s, :content_type => "text/xml"
142   end
143 end