diff options
Diffstat (limited to 'chimere/views.py')
-rw-r--r-- | chimere/views.py | 782 |
1 files changed, 526 insertions, 256 deletions
diff --git a/chimere/views.py b/chimere/views.py index 27d69e7..ef0539e 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -27,20 +27,18 @@ Views of the project import datetime from itertools import groupby import re -import simplejson as json from django.conf import settings -from django.contrib.gis.geos import GEOSGeometry +from django.contrib.gis.geos import GEOSGeometry, Polygon as GEOSPolygon from django.contrib.gis.gdal.error import OGRException from django.contrib.gis.measure import D from django.contrib.sites.models import get_current_site -from django.core import serializers from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.db.models import Q from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.shortcuts import get_object_or_404, redirect, render_to_response -from django.template import loader, RequestContext, defaultfilters +from django.template import RequestContext, defaultfilters from django.utils import simplejson as json from django.utils.http import urlquote from django.utils.translation import ugettext as _ @@ -48,17 +46,18 @@ from django.views.generic import TemplateView, ListView from chimere.actions import actions from chimere.models import Category, SubCategory, PropertyModel, Page,\ - Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile,\ - AggregatedRoute + Marker, Route, Polygon, SimpleArea, Area, Color, TinyUrl, RouteFile,\ + AggregatedRoute, AggregatedPolygon, PropertyModelChoice -from chimere.widgets import getMapJS, PointChooserWidget, \ - RouteChooserWidget, AreaWidget +from chimere.widgets import PointChooserWidget, RouteChooserWidget, AreaWidget,\ + PolygonChooserWidget from chimere.forms import MarkerForm, RouteForm, ContactForm, FileForm, \ - FullFileForm, MultimediaFileFormSet, PictureFileFormSet, notifySubmission,\ - notifyStaff, AreaForm, RoutingForm, getStaffEmails + FullFileForm, MultimediaFileFormSet, PictureFileFormSet, notifySubmission,\ + notifyStaff, AreaForm, RoutingForm, PolygonForm from chimere.route import router + def get_base_uri(request): base_uri = 'http://' if 'HTTP_REFERER' in request.META: @@ -71,14 +70,17 @@ def get_base_uri(request): base_uri += ":" + str(request.META['SERVER_PORT']) return base_uri -#TODO: convert to requestcontext +# TODO: convert to requestcontext + + def get_base_response(request, area_name=""): """ Get the base url """ - base_response_dct = {'media_path':settings.MEDIA_URL,} - base_response_dct['MOBILE'] = settings.MOBILE_TEST or \ - get_current_site(request).domain in settings.MOBILE_DOMAINS + base_response_dct = {'media_path': settings.MEDIA_URL} + base_response_dct['MOBILE'] = \ + settings.MOBILE_TEST or \ + get_current_site(request).domain in settings.MOBILE_DOMAINS base_url = reverse("chimere:index") if not base_url.startswith('/'): base_url = '/' + base_url @@ -107,8 +109,8 @@ def get_base_response(request, area_name=""): base_response_dct['area_name'] = area_name if area and area.external_css: base_response_dct['css_area'] = area.external_css - base_response_dct['dynamic_categories'] = True \ - if area and area.dynamic_categories else False + base_response_dct['dynamic_categories'] = \ + True if area and area.dynamic_categories else False base_response_dct['JQUERY_JS_URLS'] = settings.JQUERY_JS_URLS base_response_dct['JQUERY_CSS_URLS'] = settings.JQUERY_CSS_URLS base_response_dct['PROJECT_NAME'] = settings.PROJECT_NAME @@ -116,6 +118,7 @@ def get_base_response(request, area_name=""): base_response_dct['EXTRA_CSS'] = settings.EXTRA_CSS return base_response_dct, None + def getShareUrl(request, area_name='', network=''): """ Get a share url @@ -123,9 +126,11 @@ def getShareUrl(request, area_name='', network=''): data = getTinyfiedUrl(request, request.GET.urlencode(), area_name) for name, url, img in settings.CHIMERE_SHARE_NETWORKS: if defaultfilters.slugify(name) == network: - return HttpResponse(url % {'text':data['text'], 'url':data['url']}) + return HttpResponse(url % {'text': data['text'], + 'url': data['url']}) return HttpResponse('') + def getShareNetwork(request, area_name='', marker=None): """ Get URLs to share items @@ -133,14 +138,15 @@ def getShareNetwork(request, area_name='', marker=None): parameters = "" if marker: parameters = u'current_feature=%d' % marker.pk - parameters += u"&checked_categories=%s" % "_".join([str(m.id) \ - for m in marker.categories.all()]) + parameters += u"&checked_categories=%s" % "_".join( + [str(m.id) for m in marker.categories.all()]) net_dct = getTinyfiedUrl(request, parameters, area_name) share_networks = [] for network in settings.CHIMERE_SHARE_NETWORKS: share_networks.append((network[0], network[1] % net_dct, network[2])) return share_networks, net_dct + def index(request, area_name=None, default_area=None, simple=False, get_response=False): """ @@ -150,7 +156,7 @@ def index(request, area_name=None, default_area=None, simple=False, # only if user is not came yet today today = datetime.date.today().strftime('%y-%m-%d') news_visible = False - if not 'last_visit' in request.session or \ + if 'last_visit' not in request.session or \ request.session['last_visit'] != today: request.session['last_visit'] = today news_visible = True @@ -160,7 +166,7 @@ def index(request, area_name=None, default_area=None, simple=False, # don't mess with permalink zoomout = True if request.GET and 'lat' in request.GET \ - and 'lon' in request.GET: + and 'lon' in request.GET: zoomout = None if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') and \ settings.CHIMERE_ENABLE_ROUTING: @@ -174,24 +180,25 @@ def index(request, area_name=None, default_area=None, simple=False, except: pass response_dct.update({ - 'actions':actions(response_dct['area_name']), - 'action_selected':('view',), - 'error_message':'', - 'is_map':True, - 'news_visible': news_visible, - 'areas_visible': settings.CHIMERE_DISPLAY_AREAS, - 'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER, - 'dynamic_categories':response_dct['dynamic_categories'], - 'zoomout':zoomout, - 'has_default_area':Area.objects.filter(default=True).count(), - 'zoomout':zoomout, - 'has_search':hasattr(settings, 'CHIMERE_SEARCH_ENGINE') and \ - settings.CHIMERE_SEARCH_ENGINE - }) + 'actions': actions(response_dct['area_name']), + 'action_selected': ('view',), + 'error_message': '', + 'is_map': True, + 'news_visible': news_visible, + 'areas_visible': settings.CHIMERE_DISPLAY_AREAS + and Area.objects.filter(available=True).count() > 1, + 'map_layer': settings.CHIMERE_DEFAULT_MAP_LAYER, + 'dynamic_categories': response_dct['dynamic_categories'], + 'zoomout': zoomout, + 'has_default_area': Area.objects.filter(default=True).count(), + 'zoomout': zoomout, + 'has_search': hasattr(settings, 'CHIMERE_SEARCH_ENGINE') and + settings.CHIMERE_SEARCH_ENGINE + }) if hasattr(settings, 'CONTACT_EMAIL') and settings.CONTACT_EMAIL: response_dct['contact_email'] = settings.CONTACT_EMAIL response_dct['share_networks'], net_dct = \ - getShareNetwork(request, response_dct['area_name']) + getShareNetwork(request, response_dct['area_name']) tpl = 'chimere/main_map.html' response_dct['simple'] = simple if simple: @@ -201,6 +208,20 @@ def index(request, area_name=None, default_area=None, simple=False, return render_to_response(tpl, response_dct, context_instance=RequestContext(request)) + +def edit(request, area_name="", item_id=None, submited=False): + """ + Edition page + """ + response_dct, redir = get_base_response(request, area_name) + if redir: + return redir + current_actions = actions(response_dct['area_name']) + redir = action_do_redirect('edit-no-page', current_actions) + # a redir is always send... or there is a problem + return redirect(redir) + + def get_edit_page(redirect_url, item_cls, item_form, multimediafile_formset=MultimediaFileFormSet, picturefile_formset=PictureFileFormSet): @@ -218,19 +239,21 @@ def get_edit_page(redirect_url, item_cls, item_form, listed_subcats = [] if subcategories: for cat, subcats in subcategories: - listed_subcats.append((unicode(cat), - [(subcat.pk, subcat.name) for subcat in subcats])) + listed_subcats.append( + (unicode(cat), + [(subcat.pk, subcat.name) for subcat in subcats])) # if an item_id is provided: modification init_item, ref_item = None, None if item_id: try: init_item = item_cls.objects.get(pk=item_id) except: - return redirect(redirect_url, area_name + '/' if area_name \ + return redirect(redirect_url, area_name + '/' if area_name else ''), None, None ref_item = init_item - modified_item = item_cls.objects.filter(ref_item=init_item, - submiter_session_key=request.session.session_key) + modified_item = item_cls.objects.filter( + ref_item=init_item, + submiter_session_key=request.session.session_key) if modified_item.count(): init_item = modified_item.all()[0] response_dct['is_modification'] = True @@ -238,8 +261,8 @@ def get_edit_page(redirect_url, item_cls, item_form, init_multi = init_item.get_init_multi() if init_item else None init_picture = init_item.get_init_picture() if init_item else None if init_item and not request.user.is_superuser and \ - not init_item.submiter_session_key == \ - request.session.session_key: + not init_item.submiter_session_key == \ + request.session.session_key: # hide personal information for k in ('submiter_name', 'submiter_email', 'submiter_comment'): setattr(init_item, k, '') @@ -248,16 +271,20 @@ def get_edit_page(redirect_url, item_cls, item_form, if request.method == 'POST': inst = None # allow to directly modify only if owner or superuser - if init_item and (request.user.is_superuser or \ - init_item.submiter_session_key == \ - request.session.session_key): + if init_item and ( + request.user.is_superuser or + init_item.submiter_session_key == + request.session.session_key): inst = init_item form = item_form(request.POST, request.FILES, instance=inst, - subcategories=listed_subcats) - formset_multi = multimediafile_formset(request.POST, request.FILES, - initial=init_multi, prefix='multimedia') - formset_picture = picturefile_formset(request.POST, request.FILES, - initial=init_picture, prefix='picture') + subcategories=listed_subcats, + area_name=area_name) + formset_multi = multimediafile_formset( + request.POST, request.FILES, initial=init_multi, + prefix='multimedia') + formset_picture = picturefile_formset( + request.POST, request.FILES, initial=init_picture, + prefix='picture') # All validation rules pass if form.is_valid() and formset_multi.is_valid() and \ formset_picture.is_valid(): @@ -272,7 +299,7 @@ def get_edit_page(redirect_url, item_cls, item_form, item.status = 'M' if hasattr(ref_item, 'has_associated_marker'): item.has_associated_marker = \ - ref_item.has_associated_marker + ref_item.has_associated_marker elif not item.ref_item: # initialisation item.ref_item = item @@ -284,6 +311,7 @@ def get_edit_page(redirect_url, item_cls, item_form, marker = item if not isinstance(marker, Marker) \ + and hasattr(item, 'associated_marker') \ and item.associated_marker.count(): marker = item.associated_marker.all()[0] if marker: @@ -296,25 +324,47 @@ def get_edit_page(redirect_url, item_cls, item_form, base_uri = get_base_uri(request) notifySubmission(base_uri, item) response_dct = get_base_response(request, area_name) - return redirect(redirect_url + '-item', - area_name + '/' if area_name else '', - item.ref_item.pk, 'submited'), None, subcategories + return redirect( + redirect_url + '-item', + area_name + '/' if area_name else '', + item.ref_item.pk, 'submited'), None, subcategories else: - response_dct['error_message'] = _(u"There are missing field(s)" - u" and/or errors in the submited form.") + response_dct['error_message'] = _( + u"There are missing field(s)" + u" and/or errors in the submited form.") else: - form = item_form(instance=init_item, subcategories=listed_subcats) + form = item_form(instance=init_item, subcategories=listed_subcats, + area_name=area_name) formset_multi = multimediafile_formset(initial=init_multi, - prefix='multimedia') + prefix='multimedia') formset_picture = picturefile_formset(initial=init_picture, - prefix='picture') + prefix='picture') return None, (item_id, init_item, response_dct, form, formset_multi, formset_picture), subcategories return func -get_edit_marker = get_edit_page('chimere:edit', Marker, MarkerForm) -def edit(request, area_name="", item_id=None, submited=False): +def action_do_redirect(action_name, available_actions): + # redirect to an edit + is_edit = 'edit' in action_name + redir = None + for action, subactions in available_actions: + if action.id == action_name: + return + if not redir and action.id != action_name: + redir = action.url + for subaction in subactions: + if subaction.id == action_name: + return + if is_edit and 'edit' not in redir \ + and 'edit' in subaction.id: + redir = subaction.url + return redir + +get_edit_marker = get_edit_page('chimere:editmarker', Marker, MarkerForm) + + +def editMarker(request, area_name="", item_id=None, submited=False): """ Edition page """ @@ -323,32 +373,40 @@ def edit(request, area_name="", item_id=None, submited=False): if response: return response item_id, init_item, response_dct, form, formset_multi, formset_picture = \ - values + values + + # verify action is available + current_actions = actions(response_dct['area_name']) + redir = action_do_redirect('edit-marker', current_actions) + if redir: + return redirect(redir) + # get the "manualy" declared_fields. Ie: properties - declared_fields = form.declared_fields.keys() - declared_fields = PropertyModel.objects.filter(available=True).all() - filtered_properties = PropertyModel.objects.filter(available=True, - subcategories__id__isnull=False).all() + querys = PropertyModel.getAvailable(area_name=area_name) + declared_fields, filtered_properties = [], [] + for query in querys: + declared_fields += query.all() + filtered_properties += query.filter( + subcategories__id__isnull=False).all() point_value = init_item.point if init_item else None if request.POST and request.POST.get('point'): point_value = request.POST.get('point') response_dct.update({ - 'actions':actions(response_dct['area_name']), - 'action_selected':('contribute', 'edit'), - 'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER, - 'form':form, - 'formset_multi':formset_multi, - 'formset_picture':formset_picture, - 'dated':settings.CHIMERE_DAYS_BEFORE_EVENT, - 'extra_head':form.media, - 'marker_id':item_id, - 'sub_categories':sub_categories, - 'point_widget':PointChooserWidget().render('point', - point_value, - area_name=response_dct['area_name']), - 'properties':declared_fields, - 'filtered_properties':filtered_properties, - 'submited':submited + 'actions': current_actions, + 'action_selected': ('contribute', 'edit-marker'), + 'map_layer': settings.CHIMERE_DEFAULT_MAP_LAYER, + 'form': form, + 'formset_multi': formset_multi, + 'formset_picture': formset_picture, + 'dated': settings.CHIMERE_DAYS_BEFORE_EVENT, + 'extra_head': form.media, + 'marker_id': item_id, + 'sub_categories': sub_categories, + 'point_widget': PointChooserWidget().render( + 'point', point_value, area_name=response_dct['area_name']), + 'properties': declared_fields, + 'filtered_properties': filtered_properties, + 'submited': submited }) # manualy populate the custom widget if 'subcategory' in form.data and form.data['subcategory']: @@ -356,6 +414,7 @@ def edit(request, area_name="", item_id=None, submited=False): return render_to_response('chimere/edit.html', response_dct, context_instance=RequestContext(request)) + def uploadFile(request, category_id='', area_name=''): response_dct, redir = get_base_response(request, area_name) if redir: @@ -381,17 +440,20 @@ def uploadFile(request, category_id='', area_name=''): routefile.save() if not category_id: response_dct['gpx_id'] = routefile.pk - return render_to_response('chimere/upload_file.html', - response_dct, context_instance=RequestContext(request)) + return render_to_response( + 'chimere/upload_file.html', response_dct, + context_instance=RequestContext(request)) routefile.process() if not routefile.route: - response_dct['errors'] = _(u"Bad file. Please check it with an " - u"external software.") - response_dct.update({'form':form}) - return render_to_response('chimere/upload_file.html', - response_dct, context_instance=RequestContext(request)) - route = Route(name=form.cleaned_data['name'], route=routefile.route, - associated_file=routefile, status='S') + response_dct['errors'] = _( + u"Bad file. Please check it with an external software.") + response_dct.update({'form': form}) + return render_to_response( + 'chimere/upload_file.html', response_dct, + context_instance=RequestContext(request)) + route = Route(name=form.cleaned_data['name'], + route=routefile.route, associated_file=routefile, + status='S') route.save() route.categories.add(category) route.save() @@ -400,10 +462,11 @@ def uploadFile(request, category_id='', area_name=''): else: # An unbound form form = Form() - response_dct.update({'form':form}) + response_dct.update({'form': form}) return render_to_response('chimere/upload_file.html', response_dct, context_instance=RequestContext(request)) + def processRouteFile(request, area_name='', file_id=None): if file_id: try: @@ -412,8 +475,8 @@ def processRouteFile(request, area_name='', file_id=None): route = route_file.route if not route: return HttpResponse(status=500) - return HttpResponse('(' + json.dumps({'wkt':route, - 'file_id':file_id})+')', + return HttpResponse('(' + json.dumps({'wkt': route, + 'file_id': file_id}) + ')', 'application/javascript', status=200) except OSError as e: return HttpResponse(e.strerror, status=500) @@ -422,16 +485,23 @@ def processRouteFile(request, area_name='', file_id=None): get_edit_route = get_edit_page('chimere:editroute', Route, RouteForm) + def editRoute(request, area_name="", item_id=None, submited=False): """ Route edition page """ response, values, sub_categories = get_edit_route(request, area_name, - item_id, ['R', 'B']) + item_id, ['R', 'B']) if response: return response item_id, init_item, response_dct, form, formset_multi, formset_picture = \ - values + values + + # verify action is available + current_actions = actions(response_dct['area_name']) + redir = action_do_redirect('edit-route', current_actions) + if redir: + return redirect(redir) # get the "manualy" declared_fields. Ie: properties declared_fields = form.declared_fields.keys() @@ -441,20 +511,21 @@ def editRoute(request, area_name="", item_id=None, submited=False): if request.POST and request.POST.get('route'): route_value = request.POST.get('route') response_dct.update({ - 'actions':actions(response_dct['area_name']), - 'action_selected':('contribute', 'edit-route'), - 'error_message':'', - 'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER, - 'form':form, - 'formset_multi':formset_multi, - 'formset_picture':formset_picture, - 'dated':settings.CHIMERE_DAYS_BEFORE_EVENT, - 'extra_head':form.media, - 'sub_categories':sub_categories, - 'route_widget':RouteChooserWidget().render('route', route_value, - area_name=response_dct['area_name'], routefile_id='',), - 'properties':declared_fields, - 'submited':submited + 'actions': current_actions, + 'action_selected': ('contribute', 'edit-route'), + 'error_message': '', + 'map_layer': settings.CHIMERE_DEFAULT_MAP_LAYER, + 'form': form, + 'formset_multi': formset_multi, + 'formset_picture': formset_picture, + 'dated': settings.CHIMERE_DAYS_BEFORE_EVENT, + 'extra_head': form.media, + 'sub_categories': sub_categories, + 'route_widget': RouteChooserWidget().render( + 'route', route_value, area_name=response_dct['area_name'], + routefile_id='',), + 'properties': declared_fields, + 'submited': submited }) # manualy populate the custom widget if 'subcategory' in form.data and form.data['subcategory']: @@ -462,6 +533,60 @@ def editRoute(request, area_name="", item_id=None, submited=False): return render_to_response('chimere/edit_route.html', response_dct, context_instance=RequestContext(request)) +get_edit_polygon = get_edit_page('chimere:editpolygon', Polygon, PolygonForm) + + +def editPolygon(request, area_name="", item_id=None, submited=False): + """ + Polygon edition page + """ + response, values, sub_categories = get_edit_polygon(request, area_name, + item_id, ['P']) + if response: + return response + item_id, init_item, response_dct, form, formset_multi, formset_picture = \ + values + + # verify action is available + current_actions = actions(response_dct['area_name']) + redir = action_do_redirect('edit-polygon', current_actions) + if redir: + return redirect(redir) + + # get the "manualy" declared_fields. Ie: properties + querys = PropertyModel.getAvailable(area_name=area_name) + declared_fields, filtered_properties = [], [] + for query in querys: + declared_fields += query.all() + filtered_properties += query.filter( + subcategories__id__isnull=False).all() + polygon_value = init_item.polygon if init_item else None + if request.POST and request.POST.get('polygon'): + polygon_value = request.POST.get('polygon') + response_dct.update({ + 'actions': current_actions, + 'action_selected': ('contribute', 'edit-polygon'), + 'error_message': '', + 'map_layer': settings.CHIMERE_DEFAULT_MAP_LAYER, + 'form': form, + 'formset_multi': formset_multi, + 'formset_picture': formset_picture, + 'dated': settings.CHIMERE_DAYS_BEFORE_EVENT, + 'extra_head': form.media, + 'sub_categories': sub_categories, + 'polygon_widget': PolygonChooserWidget().render( + 'polygon', polygon_value, area_name=response_dct['area_name'],), + 'properties': declared_fields, + 'filtered_properties': filtered_properties, + 'submited': submited + }) + # manualy populate the custom widget + if 'subcategory' in form.data and form.data['subcategory']: + response_dct['current_category'] = int(form.data['subcategory']) + return render_to_response('chimere/edit_polygon.html', response_dct, + context_instance=RequestContext(request)) + + def submited(request, area_name="", action=""): """ Successful submission page @@ -469,14 +594,15 @@ def submited(request, area_name="", action=""): response_dct, redir = get_base_response(request, area_name) if redir: return redir - dct = {'actions':actions(response_dct['area_name']), - 'action_selected':action,} + dct = {'actions': actions(response_dct['area_name']), + 'action_selected': action} if hasattr(settings, 'CONTACT_EMAIL') and settings.CONTACT_EMAIL: response_dct['contact_email'] = settings.CONTACT_EMAIL response_dct.update(dct) return render_to_response('chimere/submited.html', response_dct, context_instance=RequestContext(request)) + def charte(request, area_name=""): """ Affichage de la charte @@ -484,11 +610,12 @@ def charte(request, area_name=""): response_dct, redir = get_base_response(request, area_name) if redir: return redir - response_dct.update({'actions':actions(response_dct['area_name']), - 'action_selected':('charte',)}) + response_dct.update({'actions': actions(response_dct['area_name']), + 'action_selected': ('charte',)}) return render_to_response('chimere/charte.html', response_dct, context_instance=RequestContext(request)) + def contactus(request, area_name=""): """ Contact page @@ -500,11 +627,12 @@ def contactus(request, area_name=""): form = ContactForm(request.POST) # All validation rules pass if form.is_valid(): - response = notifyStaff(_(u"Comments/request on the map"), - form.cleaned_data['content'], form.cleaned_data['email']) + response = notifyStaff( + _(u"Comments/request on the map"), + form.cleaned_data['content'], form.cleaned_data['email']) if response: - msg = _(u"Thank you for your contribution. It will be taken "\ - u"into account. If you have left your email you may "\ + msg = _(u"Thank you for your contribution. It will be taken " + u"into account. If you have left your email you may " u"be contacted soon for more details.") else: msg = _(u"Temporary error. Renew your message later.") @@ -513,12 +641,13 @@ def contactus(request, area_name=""): response_dct, redir = get_base_response(request, area_name) if redir: return redir - response_dct.update({'actions':actions(response_dct['area_name']), - 'action_selected':('contact',), - 'contact_form':form, 'message':msg}) + response_dct.update({'actions': actions(response_dct['area_name']), + 'action_selected': ('contact',), + 'contact_form': form, 'message': msg}) return render_to_response('chimere/contactus.html', response_dct, context_instance=RequestContext(request)) + def extraPage(request, area_name="", page_id=""): """ Extra dynamic pages @@ -530,22 +659,37 @@ def extraPage(request, area_name="", page_id=""): response_dct, redir = get_base_response(request, area_name) if redir: return redir - response_dct.update({'actions':actions(response_dct['area_name']), - 'action_selected':(page_id,), - 'content':page.content, - 'title':page.title}) + response_dct.update({'actions': actions(response_dct['area_name']), + 'action_selected': (page_id,), + 'content': page.content, + 'title': page.title}) tpl = page.template_path if page.template_path \ - else 'chimere/default_extra_page.html' + else 'chimere/default_extra_page.html' return render_to_response(tpl, response_dct, context_instance=RequestContext(request)) -def getDetail(request, area_name, marker_id): + +def getDetailUndefined(request, area_name): + return HttpResponse('') + + +def getDetail(request, area_name, key): ''' - Get the detail for a marker + Get the detail of a geographic item ''' + cls = Marker + pk = key + if '-' in key: + geo_type, pk = key.split('-') + if geo_type == 'route': + cls = Route + elif geo_type == 'aggroute': + cls = AggregatedRoute + elif geo_type == 'polygon': + cls = Polygon try: - marker = Marker.objects.filter(id=int(marker_id), - status__in=['A', 'S'])[0] + marker = cls.objects.filter(id=int(pk), + status__in=['A', 'S'])[0] except (ValueError, IndexError): return HttpResponse('no results') response_dct, redir = get_base_response(request, area_name) @@ -556,21 +700,23 @@ def getDetail(request, area_name, marker_id): if 'simple' in request.GET and request.GET['simple']: response_dct['simple'] = True response_dct['share_networks'], net_dct = \ - getShareNetwork(request, response_dct['area_name'], marker) + getShareNetwork(request, response_dct['area_name'], marker) response_dct['share_url'] = net_dct['url'] net_dct['to'] = settings.CONTACT_EMAIL if net_dct['to']: net_dct["body"] = _(settings.CHIMERE_MODIF_EMAIL) response_dct['modif_by_email'] = 'mailto:%(to)s&subject='\ - '%(text)s&body=%(body)s%(url)s' % net_dct + '%(text)s&body=%(body)s%(url)s' % net_dct # to be sure there is unique IDs during a browsing response_dct['time_now'] = datetime.datetime.now().strftime('%H%M%S') response_dct['dated'] = settings.CHIMERE_DAYS_BEFORE_EVENT \ - and marker.start_date + and marker.start_date response_dct['routing_enabled'] = settings.CHIMERE_ENABLE_ROUTING + response_dct['properties'] = marker.getProperties(area_name=area_name) return render_to_response('chimere/detail.html', response_dct, context_instance=RequestContext(request)) + def getDescriptionDetail(request, area_name, category_id): ''' Get the description for a category @@ -586,6 +732,7 @@ def getDescriptionDetail(request, area_name, category_id): return render_to_response('chimere/category_detail.html', response_dct, context_instance=RequestContext(request)) + def checkDate(q): """ Filter a queryset to manage dates @@ -595,60 +742,127 @@ def checkDate(q): today = datetime.date.today() after = today + datetime.timedelta(settings.CHIMERE_DAYS_BEFORE_EVENT) - q = q & ( Q(start_date__isnull=True) - | Q(start_date__gte=today, start_date__lte=after) - | Q(start_date__lte=today, end_date__gte=today) - ) + q = q & (Q(start_date__isnull=True) | Q(start_date__gte=today, + start_date__lte=after) | Q( + start_date__lte=today, end_date__gte=today)) return q + def _getGeoObjects(area_name, category_ids, status='A', getjson=True, - item_types=('Marker', 'Route')): + item_types=('Marker', 'Route', 'Polygon'), + bounding_box=None, zoom_level=None): ''' - Get markers and routes + Get geo objects ''' + zoom_need_reload = None items = [] - current_cat, colors, idx = None, None, 0 empty = [] if not getjson else {} + subcategories = list( + SubCategory.getAvailable(None, area_name, public=True, + instance=True).all()) + aggregated_category_ids = [] + try: + zoom_level = int(zoom_level) + except ValueError: + zoom_level = None + if zoom_level: + # pop from main category list + len_subcats = len(subcategories) + for idx, subcat in enumerate(reversed(subcategories)): + if not subcat.min_zoom: + continue + if zoom_level < subcat.min_zoom: + if not zoom_need_reload or zoom_need_reload > subcat.min_zoom: + zoom_need_reload = subcat.min_zoom + aggregated_category_ids.append( + subcategories.pop(len_subcats - 1 - idx).pk) + + category_ids = [subcat.pk for subcat in subcategories] # marker if 'Marker' in item_types: try: q = checkDate(Q(status__in=status, categories__in=category_ids)) - query = Marker.objects.filter(q).distinct('pk').order_by('-pk') + query = Marker.objects.filter(q) + if bounding_box: + query = query.filter(point__contained=bounding_box) + query = query.distinct('pk').order_by('-pk') except: - return empty + return empty, zoom_need_reload - category_ids = [int(cat_id) for cat_id in category_ids] if getjson: for geo_object in list(query): items += json.loads(geo_object.getGeoJSON(category_ids)) else: items += list(query) + # polygon + if 'Polygon' in item_types: + try: + q = checkDate(Q(status__in=status, categories__in=category_ids)) + query = Polygon.objects.filter(q) + if bounding_box: + query = query.filter(polygon__contained=bounding_box) + query = query.distinct('pk').order_by('-pk') + except: + return empty, zoom_need_reload + + if aggregated_category_ids: + query = AggregatedPolygon.objects.filter( + status__in=status, + subcategory__in=aggregated_category_ids).order_by( + 'subcategory', '-pk') + # no bounding box filter + if getjson: + for poly in query.all(): + items.append(json.loads(poly.getGeoJSON())) + else: + items += list(query) + else: + if getjson: + current_cat, colors, idx = None, None, 0 + items += Polygon.getGeoJSONs( + query, limit_to_categories=category_ids) + else: + items += list(query) + # routes if 'Route' in item_types: - query = AggregatedRoute.objects.filter(status__in=status, - subcategory__in=category_ids).order_by('subcategory', '-pk') + # TODO: manage non aggregated and bounding box in non-aggregated + query = AggregatedRoute.objects.filter( + status__in=status, subcategory__in=category_ids).order_by( + 'subcategory', '-pk') if getjson: + current_cat, colors, idx = None, None, 0 for route in query.all(): - c_cat = route.subcategory - if not current_cat or current_cat != c_cat: - idx = 0 - current_cat = c_cat - colors = list(Color.objects.filter( - color_theme=c_cat.color_theme)) - if colors: - items.append(json.loads( - route.getGeoJSON(color=colors[idx % len(colors)].code))) - else: - items.append(json.loads(route.getGeoJSON(color='000'))) - idx += 1 + color = "" + # aggregated view has no color and no categories + if hasattr(route, 'color') and route.color: + color = route.color + elif hasattr(route, 'categories'): + c_cat = None + for cat in route.categories.all(): + if cat.id in category_ids: + c_cat = cat + break + if c_cat and not current_cat or current_cat != c_cat: + idx = 0 + current_cat = c_cat + colors = list(Color.objects.filter( + color_theme=c_cat.color_theme)) + if colors: + color = colors[idx % len(colors)].code + idx += 1 + else: + color = "#000" + items.append(json.loads(route.getGeoJSON(color=color))) else: items += list(query) if not items: - return empty - return items + return empty, zoom_need_reload + return items, zoom_need_reload + def getGeoObjects(request, area_name, category_ids, status): ''' @@ -659,12 +873,27 @@ def getGeoObjects(request, area_name, category_ids, status): status = status.split('_') category_ids = unicode(category_ids).split('_') - jsons = _getGeoObjects(area_name, category_ids, status) + bounding_box = [] + for attr in ['min_lon', 'min_lat', 'max_lon', 'max_lat']: + value = request.GET.get(attr, None) + if not value: + bounding_box = None + break + bounding_box.append(value) + if bounding_box: + bounding_box = GEOSPolygon.from_bbox(bounding_box) + zoom_level = request.GET.get('zoom_level', None) + + jsons, zoom_need_reload = _getGeoObjects( + area_name, category_ids, status, bounding_box=bounding_box, + zoom_level=zoom_level) if not jsons: - return HttpResponse('no results') - data = json.dumps({"type": "FeatureCollection", "features":jsons}) + return HttpResponse("[]", content_type="application/json") + data = json.dumps({"type": "FeatureCollection", "features": jsons, + "zoom_need_reload": zoom_need_reload or ''}) return HttpResponse(data, content_type="application/json") + def getMarker(request, area_name, pk): q = Marker.objects.filter(pk=pk, status='A') if not q.count(): @@ -672,6 +901,7 @@ def getMarker(request, area_name, pk): data = q.all()[0].getGeoJSON() return HttpResponse(data, content_type="application/json") + def get_all_categories(request, area_name=None): ''' Get all available categories in JSON @@ -680,16 +910,17 @@ def get_all_categories(request, area_name=None): area = context_data["area"] subcategories = [] if area: - subcategories = list(area.getCategories('A', - area_name=context_data['area_name'])) + subcategories = list(area.getCategories( + 'A', area_name=context_data['area_name'])) else: categories = SubCategory.getAvailable() for cat, subcats in categories: subcategories += subcats subcats = [subcat.getJSONDict() for subcat in subcategories] - jsons = json.dumps({'categories':subcats}) + jsons = json.dumps({'categories': subcats}) return HttpResponse(jsons) + def get_available_categories(request, area_name=None, area=None, status='A', force=None): ''' @@ -700,21 +931,23 @@ def get_available_categories(request, area_name=None, area=None, status='A', if redir: return redir if area and area.dynamic_categories and \ - not "current_extent" in request.GET: + "current_extent" not in request.GET: context_data['sub_categories'] = [] - return render_to_response('chimere/blocks/categories.html', context_data, - context_instance=RequestContext(request)) + return render_to_response( + 'chimere/blocks/categories.html', context_data, + context_instance=RequestContext(request)) if not area or not area.dynamic_categories: # Categories are not updated dynamicaly when the user move the map # so we return ALL the categories subcategories = SubCategory.getAvailable( - area_name=context_data['area_name']) + area_name=context_data['area_name']) context_data['sub_categories'] = subcategories - return render_to_response('chimere/blocks/categories.html', context_data, - context_instance=RequestContext(request)) + return render_to_response( + 'chimere/blocks/categories.html', context_data, + context_instance=RequestContext(request)) default_message = "<p class='warning'>%s</p>" % \ - _("No category available in this area.") - if not "status" in request.GET: # there must be a status + _("No category available in this area.") + if "status" not in request.GET: # there must be a status status = 'A' try: status = status.split('_') @@ -725,18 +958,20 @@ def get_available_categories(request, area_name=None, area=None, status='A', # bad extent format return HttpResponse(default_message) # if not force and area.isIn(SimpleArea(cookie.AREA):return - categories = area.getCategories(status, area_name=context_data['area_name']) + categories = area.getCategories( + status, area_name=context_data['area_name']) if not categories: return HttpResponse(default_message) get_cat = lambda subcat: subcat.category get_cat_order = lambda subcat: (subcat.category.order, subcat.category.pk, subcat.order) categories = sorted(categories, key=get_cat_order) - subcategories = [(cat, list(subcats)) \ - for cat, subcats in groupby(categories, get_cat)] + subcategories = [(cat, list(subcats)) + for cat, subcats in groupby(categories, get_cat)] context_data['sub_categories'] = subcategories return render_to_response('chimere/blocks/categories.html', context_data, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) + def getCategory(request, area_name='', category_id=0): ''' @@ -745,14 +980,15 @@ def getCategory(request, area_name='', category_id=0): try: category = SubCategory.objects.get(pk=category_id) except ObjectDoesNotExist: - return HttpResponse('no results') - return HttpResponse(category.getJSON()) + return HttpResponse('[]', content_type="application/json") + return HttpResponse(category.getJSON(), content_type="application/json") + def getTinyfiedUrl(request, parameters, area_name=''): ''' Get the tinyfied version of parameters ''' - data = {"urn": "", "url":"", "text":""} + data = {"urn": "", "url": "", "text": ""} try: urn = TinyUrl.getUrnByParameters(parameters) except: @@ -760,8 +996,8 @@ def getTinyfiedUrl(request, parameters, area_name=''): response_dct, redir = get_base_response(request, area_name) if redir: return redir - url = reverse('chimere:tiny', args=[(response_dct['area_name'] \ - if response_dct['area_name'] else '') + '/', urn]) + url = reverse('chimere:tiny', args=[(response_dct['area_name'] + if response_dct['area_name'] else '') + '/', urn]) if not url.startswith('http'): url = get_base_uri(request) + url url = re.sub("([^:])\/\/", "\g<1>/", url) @@ -778,6 +1014,7 @@ def getTinyfiedUrl(request, parameters, area_name=''): data["text"] = urlquote(text) return data + def redirectFromTinyURN(request, area_name='', tiny_urn=''): """ Redirect from a tiny Urn @@ -788,6 +1025,7 @@ def redirectFromTinyURN(request, area_name='', tiny_urn=''): return redir return HttpResponseRedirect(response_dct['extra_url'] + parameters) + class CategoryDirectoryView(ListView): template_name = "chimere/category_directory.html" @@ -796,26 +1034,27 @@ class CategoryDirectoryView(ListView): if self.area_name: self.area_name = self.area_name.split('/')[0] area = get_object_or_404(Area, urn=self.area_name, available=True) - q = area.subcategories.filter(available=True, - category__available=True - ).order_by('category__order', 'category__id', 'order') + q = area.subcategories.filter( + available=True, category__available=True).order_by( + 'category__order', 'category__id', 'order') if q.count(): return q - return SubCategory.objects.filter(available=True, - category__available=True - ).order_by('category__order', 'category__id', 'order') + return SubCategory.objects.filter( + available=True, category__available=True).order_by( + 'category__order', 'category__id', 'order') def get_context_data(self, *args, **kwargs): context = super(CategoryDirectoryView, self).get_context_data( - *args, **kwargs) + *args, **kwargs) new_context, redirect = get_base_response(self.request, self.area_name) context.update(new_context) context.update({ - 'actions':actions(self.area_name), - 'action_selected':('categories',), + 'actions': actions(self.area_name), + 'action_selected': ('categories',), }) return context + class CategoryView(TemplateView): template_name = "chimere/category_directory_detail.html" @@ -842,24 +1081,26 @@ class CategoryView(TemplateView): if not self.category: raise Http404(_("Category does not exist")) - items = _getGeoObjects(self.area_name, [unicode(self.category.pk)], - getjson=False, item_types=('Marker',)) + items, zoom_need_reload = _getGeoObjects( + self.area_name, [unicode(self.category.pk)], getjson=False, + item_types=('Marker',)) return items def get_context_data(self, *args, **kwargs): context = super(CategoryView, self).get_context_data( - *args, **kwargs) + *args, **kwargs) self.items = self.get_geo_items() new_context, redirect = get_base_response(self.request, self.area_name) context.update(new_context) context.update({ - 'actions':actions(self.area_name), - 'action_selected':('categories',), - 'category':self.category, - 'items':self.items + 'actions': actions(self.area_name), + 'action_selected': ('categories',), + 'category': self.category, + 'items': self.items }) return context + def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2, transport='foot', speed=''): ''' @@ -870,7 +1111,8 @@ def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2, lon2, lat2 = float(lon2), float(lat2) steps = [float(lonlat) for lonlat in lonlat_steps.split('_') if lonlat] # regroup by 2 - steps = [(steps[i*2], steps[i*2+1]) for i in range(len(steps)/2)] + steps = [(steps[i * 2], steps[i * 2 + 1]) + for i in range(len(steps) / 2)] except ValueError: return HttpResponse('no results') @@ -879,8 +1121,9 @@ def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2, transport = settings.CHIMERE_ROUTING_TRANSPORT[0][0] if speed: speed = unicode(speed) - available_speed = [unicode(sp) - for sp, lbl in settings.CHIMERE_ROUTING_SPEEDS[transport]] + available_speed = [ + unicode(sp) + for sp, lbl in settings.CHIMERE_ROUTING_SPEEDS[transport]] if speed not in available_speed: speed = None if not speed: @@ -903,12 +1146,12 @@ def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2, message = '' if cats.count(): st_string = '{"type":"Feature", "geometry":{ "type": "Point", '\ - '"coordinates": [ %f, %f ] }, "properties":{"icon_path":"%s",'\ - '"icon_width":%d, "icon_height":%d}}' + '"coordinates": [ %f, %f ] }, "properties":{"icon_path":"%s",'\ + '"icon_width":%d, "icon_height":%d}}' points = [(m.point, m.categories.all()[0].icon) - for m in list(Marker.objects.filter(status='A', - categories__in=cats, point__distance_lte=(route, D(m=15)) - ).all())] + for m in list(Marker.objects.filter( + status='A', categories__in=cats, + point__distance_lte=(route, D(m=15))).all())] for pt, icon in points: st = st_string % (pt.x, pt.y, icon.image.url, icon.image.width, icon.image.height) @@ -924,21 +1167,22 @@ def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2, if pts: pt = pts[0] st = st_string % (pt.x, pt.y, icon.image.url, icon.image.width, - icon.image.height) + icon.image.height) jsons.append(st) if points or intersect: message = getattr(settings, 'CHIMERE_ROUTING_WARN_MESSAGE', '') if message: message = ', "message":%s' % jsonencoder.encode( - "%s" % _(message)) + "%s" % _(message)) else: message = '' data = '{"properties":{"transport":%s, "total":%s, "description":%s}, '\ '"type": "FeatureCollection", "features":[%s]%s}' % ( - jsonencoder.encode(transport), total, desc, ",".join(jsons), - message) + jsonencoder.encode(transport), total, desc, ",".join(jsons), + message) return HttpResponse(data) + def rss(request, area_name=''): ''' Redirect to RSS subscription page @@ -946,15 +1190,15 @@ def rss(request, area_name=''): response_dct, redir = get_base_response(request, area_name) if redir: return redir - response_dct.update({'actions':actions(response_dct['area_name']), - 'action_selected':('rss',), - 'category_rss_feed':'',}) + response_dct.update({'actions': actions(response_dct['area_name']), + 'action_selected': ('rss',), + 'category_rss_feed': ''}) # If the form has been submited if request.method == "POST": # User has defined the kind of POI he is interested in : POI in a area # (GET method is used for the link with RSS icon in the browser) if 'rss_category' in request.POST: - #User wants to follow all the new POI + # User wants to follow all the new POI if request.POST['rss_category'] == 'global': feeds_link = reverse('chimere:feeds-global') return redirect(feeds_link) @@ -962,59 +1206,60 @@ def rss(request, area_name=''): elif request.POST['rss_category'] == 'poi': response_dct['category_rss_feed'] = 'category' response_dct['sub_categories'] = SubCategory.getAvailable() - return render_to_response('chimere/feeds/rss.html', - response_dct, - context_instance=RequestContext(request)) + return render_to_response( + 'chimere/feeds/rss.html', response_dct, + context_instance=RequestContext(request)) # User wants to follow all the new POI situated in a defined area elif request.POST['rss_category'] == 'area': # An unbound form form = AreaForm() area_widget = AreaWidget().render('area', None) response_dct.update({ - 'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER, - 'extra_head':form.media, - 'form':form, - 'category_rss_feed':'area', - 'area_id':Area.getAvailable(), - 'area_widget':area_widget + 'map_layer': settings.CHIMERE_DEFAULT_MAP_LAYER, + 'extra_head': form.media, + 'form': form, + 'category_rss_feed': 'area', + 'area_id': Area.getAvailable(), + 'area_widget': area_widget }) - return render_to_response('chimere/feeds/rss.html', - response_dct, - context_instance=RequestContext(request)) + return render_to_response( + 'chimere/feeds/rss.html', response_dct, + context_instance=RequestContext(request)) # Error when submitting the form else: error = _("Incorrect choice in the list") - response_dct.update({'error_message':error, - 'category_rss_feed':'', - 'sub_categories':SubCategory.getAvailable()}) - return render_to_response('chimere/feeds/rss.html', - response_dct, - context_instance=RequestContext(request)) + response_dct.update({ + 'error_message': error, + 'category_rss_feed': '', + 'sub_categories': SubCategory.getAvailable()}) + return render_to_response( + 'chimere/feeds/rss.html', response_dct, + context_instance=RequestContext(request)) # User has specified the category or subcategory he wants to follow => # we redirect him towards the related rss feed if 'subcategory' in request.POST and request.POST['subcategory'] != '': cat_id = request.POST['subcategory'] - if cat_id.find("cat_") != -1 : + if cat_id.find("cat_") != -1: cat_id = cat_id.split('_')[1] feeds_link = reverse('chimere:feeds-cat', - kwargs={'category_id':cat_id}) + kwargs={'category_id': cat_id}) return redirect(feeds_link) else: feeds_link = reverse('chimere:feeds-subcat', - kwargs={'category_id':cat_id}) + kwargs={'category_id': cat_id}) return redirect(feeds_link) # User has specified the ID of the area he wants to follow if 'id_area' in request.POST and request.POST['id_area'] != '': feeds_link = reverse('chimere:feeds-areaid', - kwargs={'area_id':request.POST['id_area']}) + kwargs={'area_id': request.POST['id_area']}) return redirect(feeds_link) # User has specified the area he wants to follow => we redirect him # towards the related rss feed (using upper left and lower right - # coordinates) + # coordinates) elif 'upper_left_lat' in request.POST and \ request.POST['upper_left_lat'] != '' and \ 'upper_left_lon' in request.POST and \ @@ -1022,13 +1267,13 @@ def rss(request, area_name=''): 'lower_right_lon' in request.POST and \ request.POST['lower_right_lon'] != '' and \ 'lower_right_lat' in request.POST and \ - request.POST['lower_right_lat'] != '' : + request.POST['lower_right_lat'] != '': coords = request.POST['upper_left_lat'] + '_' + \ - request.POST['upper_left_lon'] + '_' + \ - request.POST['lower_right_lat'] + '_' + \ - request.POST['lower_right_lon'] + request.POST['upper_left_lon'] + '_' + \ + request.POST['lower_right_lat'] + '_' + \ + request.POST['lower_right_lon'] feeds_link = reverse('chimere:feeds-area', - kwargs={'area':coords}) + kwargs={'area': coords}) return redirect(feeds_link) # GET method is used for linking with the RSS icon in the browser when user @@ -1039,18 +1284,20 @@ def rss(request, area_name=''): return redirect(feeds_link) if request.GET['rss_category'] == 'poi': response_dct['category_rss_feed'] = 'category' - response_dct['sub_categories'] = SubCategory.getAvailable(['M','B']) + response_dct['sub_categories'] = SubCategory.getAvailable( + ['M', 'B']) return render_to_response('chimere/feeds/rss.html', response_dct, context_instance=RequestContext(request)) if request.GET['rss_category'] == 'area': # An unbound form form = AreaForm() - response_dct.update({'map_layer':settings.MAP_LAYER, - 'extra_head':form.media, - 'form':form, - 'category_rss_feed':'area', - 'area_id':Area.getAvailable(), - 'area_widget':AreaWidget().render('area', None)}) + response_dct.update({ + 'map_layer': settings.MAP_LAYER, + 'extra_head': form.media, + 'form': form, + 'category_rss_feed': 'area', + 'area_id': Area.getAvailable(), + 'area_widget': AreaWidget().render('area', None)}) return render_to_response('chimere/feeds/rss.html', response_dct, context_instance=RequestContext(request)) @@ -1059,7 +1306,27 @@ def rss(request, area_name=''): return render_to_response('chimere/feeds/rss.html', response_dct, context_instance=RequestContext(request)) -from django.core.paginator import Paginator, InvalidPage +# from django.core.paginator import Paginator, InvalidPage + + +def property_choice_list(request, area_name='', property_slug=''): + data = {} + try: + pm = PropertyModel.objects.get(slug=property_slug, available=True) + except PropertyModel.DoesNotExist: + return HttpResponse(json.dumps(data), + content_type="application/json") + if not request.GET or not request.GET.get('term') or \ + pm.areas.count() and not pm.areas.filter(urn=area_name).count(): + return HttpResponse(json.dumps(data), + content_type="application/json") + fltr = {'propertymodel': pm, 'available': True, + 'value__icontains': request.GET.get('term')} + q = PropertyModelChoice.objects.filter(**fltr).order_by('value') + data = [{"id": p.pk, "value": p.value} for p in q.all()] + return HttpResponse(json.dumps(data), + content_type="application/json") + SearchView = None autocomplete = None @@ -1067,25 +1334,28 @@ if hasattr(settings, 'CHIMERE_SEARCH_ENGINE') \ and settings.CHIMERE_SEARCH_ENGINE: from haystack.views import SearchView as HaystackSearchView from haystack.query import SearchQuerySet + class SearchView(HaystackSearchView): def extra_context(self, *args, **kwargs): context = super(SearchView, self).extra_context(*args, **kwargs) - context["autocomplete"] = settings.HAYSTACK_AUTOCOMPLETE \ - if hasattr(settings, 'HAYSTACK_AUTOCOMPLETE') else False + context["autocomplete"] = \ + settings.HAYSTACK_AUTOCOMPLETE \ + if hasattr(settings, 'HAYSTACK_AUTOCOMPLETE') else False return context + def autocomplete(request): sqs = SearchQuerySet().autocomplete( - content_auto=request.GET.get('q', ''))[:5] + content_auto=request.GET.get('q', ''))[:5] suggestions = [result.object.name for result in sqs if result.object] spelling = [] if not suggestions: spelling = SearchQuerySet().spelling_suggestion( - request.GET.get('q', '')) or [] + request.GET.get('q', '')) or [] # convert to list spelling... # make sure it returns a JSON object, not a bare list. # otherwise, it could be vulnerable to an XSS attack. the_data = json.dumps({ 'results': suggestions, - 'spelling':spelling, + 'spelling': spelling, }) return HttpResponse(the_data, content_type='application/json') |