summaryrefslogtreecommitdiff
path: root/chimere/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'chimere/views.py')
-rw-r--r--chimere/views.py204
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')