various fixes
[rails.git] / app / controllers / node_controller.rb
1 class NodeController < ApplicationController
2   require 'xml/libxml'
3   
4   before_filter :authorize
5
6   def create
7     if request.put?
8       doc = XML::Document.new(request.raw_post) #THIS IS BROKEN, libxml docus dont talk about creating a doc from a string
9       doc.find('//osm/node').each do |pt|
10         render :text => 'arghsd.rkugt;dsrt'
11         return
12         lat = pt.attributes['lat'].to_f
13         lon = pt.attributes['lon'].to_f
14         node_id = pt.attributes['id'].to_i
15
16         if lat > 90 or lat < -90 or lon > 180 or lon < -180  or node_id != 0
17           render :nothing => true, :status => 400 # BAD REQUEST
18           return
19         end
20
21         tags = []
22
23         pt.elements.each('tag') do |tag|
24           tags << [tag.attributes['k'],tag.attributes['v']]
25         end
26         tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';')
27         tags = '' if tags.nil?
28
29         now = Time.now
30
31         node = Node.new
32         node.latitude = lat
33         node.longitude = lon
34         node.visible = 1
35         node.tags = tags
36         node.timestamp = now
37         node.user_id = @user.id
38
39         #FIXME add a node to the old nodes table too
40
41         if node.save
42           render :text => node.id
43         else
44           render :nothing => true, :status => 500
45         end
46       end
47     end
48
49         render :text => 'WRONG!           '
50         return
51
52   end
53
54   def rest
55     unless Node.exists?(params[:id])
56       render :nothing => true, :status => 400
57       return
58     end
59
60     node = Node.find(params[:id])
61
62
63     case request.method
64     when :get
65       doc = XML::Document.new
66
67       # this needs a new libxml:
68       # doc.encoding = "UTF-8"  
69
70       root = XML::Node.new 'osm'
71       root['version'] = '0.4'
72       root['generator'] = 'OpenStreetMap server'
73       doc.root = root
74       el1 = XML::Node.new 'node'
75       el1['id'] = node.id.to_s
76       el1['lat'] = node.latitude.to_s
77       el1['lon'] = node.longitude.to_s
78       split_tags(el1, node.tags)
79       el1['visible'] = node.visible.to_s
80       el1['timestamp'] = node.timestamp.xmlschema
81       root << el1
82
83       render :text => doc.to_s
84
85       #
86       # DELETE
87       #
88     when :delete
89
90       if node.visible
91         node.visible = 0
92         node.save
93       else
94         render :nothing => true, :status => 410
95       end
96
97       #
98       # PUT
99       #
100     when :put
101
102       doc = XML::Document.new(request.raw_post)
103       doc.elements.each('osm/node') do |pt|
104         lat = pt.attributes['lat'].to_f
105         lon = pt.attributes['lon'].to_f
106         node_id = pt.attributes['id'].to_i
107
108         if lat > 90 or lat < -90 or lon > 180 or lon < -180  or node_id != params[:id]
109           render :nothing => true, :status => 400 # BAD REQUEST
110           return
111         end
112
113         tags = []
114
115         pt.elements.each('tag') do |tag|
116           tags << [tag.attributes['k'],tag.attributes['v']]
117         end
118         tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';')
119         tags = '' if tags.nil?
120
121         now = Time.now
122
123         node.latitude = lat
124         node.longitude = lon
125         node.visible = 1
126         node.tags = tags
127         node.timestamp = now
128         node.user_id = @user.id
129
130         #FIXME add a node to the old nodes table too
131
132         if node.save
133           render :text => node.id
134         else
135           render :nothing => true, :status => 500
136         end
137       end
138     end
139   end
140
141
142   def dummy
143     if request.post?
144       userid = dao.useridfromcreds(r.user, r.get_basic_auth_pw)
145       doc = Document.new $stdin.read
146
147       doc.elements.each('osm/node') do |pt|
148         lat = pt.attributes['lat'].to_f
149         lon = pt.attributes['lon'].to_f
150         xmlnodeid = pt.attributes['id'].to_i
151
152         tags = []
153         pt.elements.each('tag') do |tag|
154           tags << [tag.attributes['k'],tag.attributes['v']]
155         end
156
157         tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';')
158
159         tags = '' unless tags
160         if xmlnodeid == nodeid && userid != 0
161           if nodeid == 0
162             new_node_id = dao.create_node(lat, lon, userid, tags)
163             if new_node_id
164               puts new_node_id
165               exit
166             else
167               exit HTTP_INTERNAL_SERVER_ERROR
168             end
169           else
170             node = dao.getnode(nodeid)
171             if node
172               #FIXME: need to check the node hasn't moved too much
173               if dao.update_node?(nodeid, userid, lat, lon, tags)
174                 exit
175               else
176                 exit HTTP_INTERNAL_SERVER_ERROR
177               end
178             else
179               exit HTTP_NOT_FOUND
180             end
181           end
182
183         else
184           exit BAD_REQUEST
185         end
186       end
187       exit HTTP_INTERNAL_SERVER_ERROR
188
189
190     end
191   end
192
193
194   def dummydummy
195
196     #
197     # POST ???
198     #
199
200     if request.post?
201       nodeid = r.args.match(/nodeid=([0-9]+)/).captures.first.to_i
202       userid = dao.useridfromcreds(r.user, r.get_basic_auth_pw)
203       doc = Document.new $stdin.read
204
205       doc.elements.each('osm/node') do |pt|
206         lat = pt.attributes['lat'].to_f
207         lon = pt.attributes['lon'].to_f
208         xmlnodeid = pt.attributes['id'].to_i
209
210         tags = []
211         pt.elements.each('tag') do |tag|
212           tags << [tag.attributes['k'],tag.attributes['v']]
213         end
214
215         tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';')
216
217         tags = '' unless tags
218         if xmlnodeid == nodeid && userid != 0
219           if nodeid == 0
220             new_node_id = dao.create_node(lat, lon, userid, tags)
221             if new_node_id
222               puts new_node_id
223               exit
224             else
225               exit HTTP_INTERNAL_SERVER_ERROR
226             end
227           else
228             node = dao.getnode(nodeid)
229             if node
230               #FIXME: need to check the node hasn't moved too much
231               if dao.update_node?(nodeid, userid, lat, lon, tags)
232                 exit
233               else
234                 exit HTTP_INTERNAL_SERVER_ERROR
235               end
236             else
237               exit HTTP_NOT_FOUND
238             end
239           end
240
241         else
242           exit BAD_REQUEST
243         end
244       end
245       exit HTTP_INTERNAL_SERVER_ERROR
246
247     end
248
249     #
250     # GET ???
251     #
252
253     if request.get?
254       node = node.find(params[:id])
255       doc = document.new
256       doc.encoding = "utf-8"
257       root = node.new 'osm'
258       root['version'] = '0.4'
259       root['generator'] = 'openstreetmap server'
260       doc.root = root
261       el1 = node.new 'node'
262       el1['id'] = node.id.to_s
263       el1['lat'] = node.latitude.to_s
264       el1['lon'] = node.longitude.to_s
265       split_tags(el1, node.tags)
266       el1['visible'] = node.visible.to_s
267       el1['timestamp'] = node.timestamp
268       root << el1
269
270       render :text => doc.to_s, :template => false
271     end
272
273     #
274     # DELETE????
275     # 
276
277     if request.delete?
278       userid = dao.useridfromcreds(r.user, r.get_basic_auth_pw)
279       #cgi doesnt work with DELETE so extract manually:
280       nodeid = r.args.match(/nodeid=([0-9]+)/).captures.first.to_i
281
282       if userid > 0 && nodeid != 0
283         node = dao.getnode(nodeid)
284         if node
285           if node.visible  
286             if dao.delete_node?(nodeid, userid)
287               exit
288             else
289               exit HTTP_INTERNAL_SERVER_ERROR
290             end
291           else
292             exit HTTP_GONE
293           end
294         else
295           exit HTTP_NOT_FOUND
296         end
297       else
298         exit BAD_REQUEST
299
300       end
301
302
303     end
304
305
306   end
307
308   private
309   def split_tags(el, tags)
310     tags.split(';').each do |tag|
311       parts = tag.split('=')
312       key = ''
313       val = ''
314       key = parts[0].strip unless parts[0].nil?
315       val = parts[1].strip unless parts[1].nil?
316       if key != '' && val != ''
317         el2 = Node.new('tag')
318         el2['k'] = key.to_s
319         el2['v'] = val.to_s
320         el << el2
321       end
322     end
323   end
324
325 end