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

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

Fixed faulty "traces of nuts" detection condition; handled error rendering a page for relations containing relation members, which possibly only conceals a problem in parser(?)

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