diff options
Diffstat (limited to 'chimere/views.py')
-rw-r--r-- | chimere/views.py | 204 |
1 files changed, 174 insertions, 30 deletions
diff --git a/chimere/views.py b/chimere/views.py index a417fad..88619ce 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2008-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2008-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> # # RSS : Copyright (C) 2010 Pierre Clarenc <pierre.crc_AT_gmailDOTcom>, # Samuel Renard <renard.samuel_AT_gmailDOTcom>, @@ -27,6 +27,7 @@ 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 @@ -37,12 +38,13 @@ 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 -from django.shortcuts import redirect, render_to_response +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.utils import simplejson as json from django.utils.http import urlquote from django.utils.translation import ugettext as _ +from django.views.generic import TemplateView, ListView from chimere.actions import actions from chimere.models import Category, SubCategory, PropertyModel, Page,\ @@ -175,13 +177,16 @@ def index(request, area_name=None, default_area=None, simple=False, '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 + '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 @@ -596,6 +601,55 @@ def checkDate(q): ) return q +def _getGeoObjects(area_name, category_ids, status='A', getjson=True, + item_types=('Marker', 'Route')): + ''' + Get markers and routes + ''' + items = [] + current_cat, colors, idx = None, None, 0 + empty = [] if not getjson else {} + + # 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') + except: + return empty + + 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) + + # routes + if 'Route' in item_types: + query = AggregatedRoute.objects.filter(status__in=status, + subcategory__in=category_ids).order_by('subcategory', '-pk') + if getjson: + 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 + else: + items += list(query) + + if not items: + return empty + return items + def getGeoObjects(request, area_name, category_ids, status): ''' Get the JSON for markers and routes @@ -603,33 +657,20 @@ def getGeoObjects(request, area_name, category_ids, status): if not status: status = 'A' status = status.split('_') - category_ids = category_ids.split('_') - query = AggregatedRoute.objects.filter(status__in=status, - subcategory__in=category_ids).order_by('subcategory') - jsons = [] - 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: - jsons.append(route.getGeoJSON(color=colors[idx % len(colors)].code)) - else: - jsons.append(route.getGeoJSON(color='000')) - idx += 1 - try: - q = checkDate(Q(status__in=status, categories__in=category_ids)) - query = Marker.objects.filter(q).distinct('pk').order_by('pk') - except: - return HttpResponse('no results') - category_ids = [int(cat_id) for cat_id in category_ids] - jsons += [geo_object.getGeoJSON(category_ids) for geo_object in list(query)] + category_ids = unicode(category_ids).split('_') + + jsons = _getGeoObjects(area_name, category_ids, status) if not jsons: return HttpResponse('no results') - data = '{"type": "FeatureCollection", "features":[%s]}' % ",".join(jsons) - return HttpResponse(data) + data = json.dumps({"type": "FeatureCollection", "features":jsons}) + 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(): + return HttpResponse('{}') + data = q.all()[0].getGeoJSON() + return HttpResponse(data, content_type="application/json") def get_all_categories(request, area_name=None): ''' @@ -688,7 +729,7 @@ def get_available_categories(request, area_name=None, area=None, status='A', if not categories: return HttpResponse(default_message) get_cat = lambda subcat: subcat.category - get_cat_order = lambda subcat: (subcat.category.order, 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)) \ @@ -747,6 +788,78 @@ 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" + + def get_queryset(self): + self.area_name = self.kwargs.get('area_name', None) + 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') + if q.count(): + return q + 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) + 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',), + }) + return context + +class CategoryView(TemplateView): + template_name = "chimere/category_directory_detail.html" + + def get_geo_items(self): + # TODO: simplify on v2.3 when slug are available + category_slug = self.kwargs.get('category_slug') + self.area_name = self.kwargs.get('area_name', None) + q = None + 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) + if not q.count(): + q = None + if not q: + q = SubCategory.objects.filter(available=True, + category__available=True) + self.category = None + for subcat in q: + if defaultfilters.slugify(subcat.name) == category_slug: + self.category = subcat + break + if not self.category: + raise Http404(_("Category does not exist")) + + items = _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) + 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 + }) + return context + def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2, transport='foot', speed=''): ''' @@ -945,3 +1058,34 @@ def rss(request, area_name=''): else: return render_to_response('chimere/feeds/rss.html', response_dct, context_instance=RequestContext(request)) + +from django.core.paginator import Paginator, InvalidPage + +SearchView = None +autocomplete = None +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 + return context + def autocomplete(request): + sqs = SearchQuerySet().autocomplete( + 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 [] + # 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, + }) + return HttpResponse(the_data, content_type='application/json') |