source: subversion/applications/editors/django/osmeditor/simple/views.py @ 13387

Last change on this file since 13387 was 13387, checked in by hughb, 10 years ago

Just more tweaks:

  • added user details to output and to osm object
  • added link to object browser
  • added name to heading where it exists
  • fixed #new_keys style (defaultly display=none again)
  • added some new app settings and osm object properties
  • made pending deletions more visually obvious
File size: 4.0 KB
Line 
1
2import xml.dom.minidom as m
3from django.conf import settings
4from django.shortcuts import render_to_response
5
6try:
7    import httplib2
8except:
9    from third import httplib2
10
11try:
12    from xml.etree.cElementTree import Element, SubElement, tostring
13except:
14    from third.ElementTree import Element, SubElement, tostring
15
16import urllib
17
18def get_xml(type, id):
19    url = "%s/%s/%s" % (settings.OSM_API, type, id)
20    u = urllib.urlopen(url)
21    data = u.read()
22    doc = m.parseString(data)
23    return doc
24
25def get_osm_obj(type, id, doc=None):
26    obj = {}
27    if not doc:
28        doc = get_xml(type, id)
29    parent = doc.getElementsByTagName(type)[0]
30    obj['timestamp'] = parent.getAttribute("timestamp")
31    if type == "node":
32        obj['lat'] = parent.getAttribute("lat")
33        obj['lon'] = parent.getAttribute("lon")
34    elif type == "way":
35        obj['child'] = []
36        obj['childtype'] = "node" #FIXME: there's probably a nicer place to assign this
37        for node in parent.getElementsByTagName("nd"):
38            obj['child'].append(node.getAttribute("ref"))
39    obj['id'] = int(id)
40    obj['type'] = type
41    obj['tags'] = {}
42    for tag in parent.getElementsByTagName("tag"):
43        obj['tags'][tag.getAttribute("k")] = tag.getAttribute("v")
44    obj['user'] = { 'id': parent.getAttribute("user") , 'uri': settings.OSM_USER % parent.getAttribute("user") }
45    obj['uri'] = settings.OSM_BROWSE % (type.lower(),id)
46    obj['name'] = obj['tags']['name'] or None; # not sure if this convenience key is worthwhile ..
47    return obj
48
49def edit_osm_obj(type, id, post):
50    xml = get_xml(type, id)
51    obj = get_osm_obj(type, id, xml)
52    if obj['timestamp'] != post['timestamp']:
53        raise Exception("Object changed since you started editing it.")
54    osm = Element('osm', {'version': '0.5'})
55    if type == "node":
56        parent = SubElement(osm, type, {'id':id, 
57                                        'lat':obj['lat'],
58                                        'lon':obj['lon']
59                                        })
60    elif type == "way":
61        parent = SubElement(osm, type, {'id':id, })
62        for nd in xml.getElementsByTagName("nd"):
63            nd = SubElement(parent, "nd", {'ref': nd.getAttribute("ref")})
64   
65    else:
66        raise Exception("%s not supported" % type)
67    changed = False
68    for key in filter(lambda x: x.startswith("delete_"), post.keys()):
69        k = key.replace("delete_key_", "")
70        if k in obj['tags']:
71            changed = True
72            del obj['tags'][k]
73        else:
74            raise Exception("Huh? %s is not in tags" % k)
75   
76    for key in filter(lambda x: x.startswith("key_"), post.keys()):
77        k = key.replace("key_", "")
78        if k in obj['tags'] and post[key] != obj['tags'][k]:
79            changed = True
80            obj['tags'][k] = post[key]
81   
82    for key in filter(lambda x: x.startswith("new_key_"), post.keys()):
83        new_id = key.replace("new_key_", "")
84        kname = "new_key_%s" % new_id
85        vname = "new_value_%s" % new_id
86        if kname in post and vname in post:
87            k = post[kname]
88            v = post[vname]
89            if k and v:
90                obj['tags'][k] = v
91                changed = True
92           
93    if not changed: return
94
95    for k, v in obj['tags'].items():
96        SubElement(parent, "tag", {'k': k, 'v': v})
97   
98    if not 'username' in post or not 'password' in post:
99        raise Exception("Need username and password")
100    xml = tostring(osm)
101    change_obj(type, id, xml, post['username'], post['password'])
102
103def change_obj(type, id, xml, username, password):   
104    url = "%s/%s/%s" % (settings.OSM_API, type, id)
105    http = httplib2.Http()   
106    http.add_credentials(username, password)
107    resp, content = http.request(url, "PUT", body=xml)   
108    if int(resp.status) != 200:
109        raise Exception(resp.status)
110
111def load(request, type="node", id=0):
112    if request.method == "POST":
113        edit_osm_obj(type, id, request.POST)
114    obj = get_osm_obj(type, id)
115    return render_to_response("obj.html",{'obj':obj})
116
117def home(request):
118    return render_to_response("home.html")
Note: See TracBrowser for help on using the repository browser.