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

Last change on this file since 13754 was 13754, checked in by crschmidt, 11 years ago

add tools for reversing one-way directionality

File size: 5.4 KB
RevLine 
[13349]1from django.conf import settings
[13463]2from django import forms
[13349]3from django.shortcuts import render_to_response
[13467]4from django.http import HttpResponse, HttpResponseRedirect
[13681]5from django.forms.util import ValidationError
[13564]6import urllib
[13487]7
[13349]8try:
9    import httplib2
10except:
11    from third import httplib2
12
[13479]13from lib import osmparser
14
15def osmparser_obj(type, id, xml=None):
16    if not xml:
17        xml = get_xml_string(type, id)
[13487]18    output = osmparser.parseString(xml, site_url=settings.OSM_SERVER)
[13479]19    return output["%ss" % type][int(id)] 
20
21def get_xml_string(type, id):
[13472]22    url = "%s/%s/%s/full" % (settings.OSM_API, type, id)
23    if type == "node":
24        url = url.replace('/full','') # required because the API 404s on node/x/full - wtf?
[13487]25    h = httplib2.Http()   
26    (resp, content) = h.request(url)
27    if int(resp.status) != 200:
28        raise Exception("%s returned %s" % (url, resp.status))
29    return content
[13349]30
[13463]31def edit_osm_obj(type, id, post, session={}):
[13479]32    obj = osmparser_obj(type, id)
33    if obj.timestamp != post['timestamp']:
[13349]34        raise Exception("Object changed since you started editing it.")
35   
[13690]36    if 'action' in post and post['action'] == "delete":
37        username = post.get('username', None) or session.get("username", None)
38        password = post.get('password', None) or session.get("password", None)
39        if not username or not password:
40            raise Exception("Need username and password")
41        id = obj.id   
42        obj.delete(username, password)
43        obj.id = id
44    else:
45        changed = False
[13754]46        if 'reverse' in post and type == "way":
47            obj.nodes.reverse()
48            changed = True
[13690]49        for key in filter(lambda x: x.startswith("delete_"), post.keys()):
50            k = key.replace("delete_key_", "")
51            if k in obj.tags:
52                changed = True
53                del obj.tags[k]
54            else:
55                raise Exception("Huh? %s is not in tags" % k)
56       
57        for key in filter(lambda x: x.startswith("key_"), post.keys()):
58            k = key.replace("key_", "")
59            if k in obj.tags and post[key] != obj.tags[k]:
60                changed = True
61                obj.tags[k] = post[key]
[13350]62   
[13690]63        for key in filter(lambda x: x.startswith("new_key_"), post.keys()):
64            new_id = key.replace("new_key_", "")
65            kname = "new_key_%s" % new_id
66            vname = "new_value_%s" % new_id
67            if kname in post and vname in post:
68                k = post[kname]
69                v = post[vname]
70                if k and v:
71                    obj.tags[k] = v
72                    changed = True
73               
74        if changed:
[13349]75
[13690]76            username = post.get('username', None) or session.get("username", None)
77            password = post.get('password', None) or session.get("password", None)
78            if not username or not password:
79                raise Exception("Need username and password")
80            obj.save(username, password)
[13487]81    return obj
[13349]82
[13492]83def tag_sorter(a, b):
84    if ':' in a and not ':' in b:
85        return 1
86    elif ':' in b and not ':' in a:
87        return -1
88    return cmp(a,b)
89
[13349]90def load(request, type="node", id=0):
91    if request.method == "POST":
[13487]92        obj = edit_osm_obj(type, id, request.POST, request.session)
93        return HttpResponseRedirect(obj.local_url())   
[13479]94    xml = get_xml_string(type, id)
95    obj = osmparser_obj(type, id, xml=xml)
[13463]96   
[13492]97    tag_list = obj.tags.keys()
98    tag_list.sort(tag_sorter)
99    sorted_tags = []
100    for k in tag_list:
101        sorted_tags.append((k, obj.tags[k]))
102    return render_to_response("obj.html",{'obj':obj, 'obj_xml': xml, 
103        'sorted_tags': sorted_tags,
[13463]104        'logged_in': ('username' in request.session)})
[13349]105
106def home(request):
[13463]107    return render_to_response("home.html", {'logged_in': 'username' in request.session})
108
109class UserForm(forms.Form):
110    email = forms.CharField(max_length=255)
111    password = forms.CharField(widget=forms.PasswordInput)
112
[13681]113    def clean(self):
114        if self.cleaned_data.get('password') and self.cleaned_data.get('password'):
115            http = httplib2.Http()   
116            http.add_credentials(self.cleaned_data['email'], self.cleaned_data['password'])
117            url = "%s/user/details" % (settings.OSM_API)
118            resp, content = http.request(url, "GET")
119            if int(resp.status) == 200:
120                return self.cleaned_data
121            else:
122                raise ValidationError("Could not authenticate against OSM API") 
123                       
124
[13463]125def login(request):
126    if request.method == "POST":
127        form = UserForm(request.POST)
128        if form.is_valid():
[13681]129            request.session['username'] = form.cleaned_data['email']
130            request.session['password'] = form.cleaned_data['password']
131            return HttpResponseRedirect("/")
[13463]132    else:
133        form = UserForm()
134    return render_to_response("login.html", {'form': form})   
[13467]135
[13493]136def logout(request):
137    request.session.flush()
138    return HttpResponseRedirect("/")   
139
[13683]140def help(request):
141    return render_to_response("help.html")
142
[13467]143def api_proxy(request, url):
144    http = httplib2.Http()   
[13691]145    if 'username' in request.session:
[13683]146        http.add_credentials(request.session['username'], request.session['password'])
[13564]147    url = "%s/%s?%s" % (settings.OSM_API, url, urllib.urlencode(request.GET))
[13683]148    body = (request.raw_post_data or None)
149    resp, content = http.request(url, request.method, body=body)
[13564]150    return HttpResponse(content, content_type="application/osm+xml", status=resp.status)
Note: See TracBrowser for help on using the repository browser.