diff options
Diffstat (limited to 'chimere/views.py')
| -rw-r--r-- | chimere/views.py | 222 | 
1 files changed, 189 insertions, 33 deletions
| diff --git a/chimere/views.py b/chimere/views.py index 22bd50a..7c02216 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -29,27 +29,32 @@ from itertools import groupby  import re  from django.conf import settings +from django.contrib.gis.geos import GEOSGeometry +from django.contrib.gis.gdal.error import OGRException +from django.contrib.gis.measure import D  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.template import loader, RequestContext -from django.utils import simplejson +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 chimere.actions import actions -from chimere.models import Category, SubCategory, PropertyModel, \ -     Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile, \ -     get_users_by_area +from chimere.models import Category, SubCategory, PropertyModel, Page,\ +     Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile,\ +     AggregatedRoute  from chimere.widgets import getMapJS, PointChooserWidget, \                              RouteChooserWidget, AreaWidget  from chimere.forms import MarkerForm, RouteForm, ContactForm, FileForm, \       FullFileForm, MultimediaFileFormSet, PictureFileFormSet, notifySubmission,\ -     notifyStaff, AreaForm +     notifyStaff, AreaForm, RoutingForm, getStaffEmails + +from chimere.route import router  def get_base_uri(request):      base_uri = 'http://' @@ -101,9 +106,36 @@ def get_base_response(area_name=""):              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      return base_response_dct, None -def index(request, area_name=None, default_area=None, simple=False): +def getShareUrl(request, area_name='', network=''): +    """ +    Get a share url +    """ +    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('') + +def getShareNetwork(request, area_name='', marker=None): +    """ +    Get URLs to share items +    """ +    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()]) +    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):      """      Main page      """ @@ -123,6 +155,10 @@ def index(request, area_name=None, default_area=None, simple=False):      if request.GET and 'lat' in request.GET \        and 'lon' in request.GET:          zoomout = None +    if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') and \ +       settings.CHIMERE_ENABLE_ROUTING: +        response_dct['itinerary_form'] = RoutingForm() +        response_dct['routing_transport'] = settings.CHIMERE_ROUTING_TRANSPORT      if request.GET and 'current_feature' in request.GET:          try:              m = Marker.objects.get(pk=request.GET['current_feature']) @@ -131,18 +167,26 @@ def index(request, area_name=None, default_area=None, simple=False):          except:              pass      response_dct.update({ -         'actions':actions, 'action_selected':('view',), +         'actions':actions(response_dct['area_name']), +         'action_selected':('view',),           'error_message':'',           '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          }) +    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'])      tpl = 'chimere/main_map.html'      if simple:          tpl = 'chimere/main_map_simple.html' +    if get_response: +        return tpl, response_dct      return render_to_response(tpl, response_dct,                                context_instance=RequestContext(request)) @@ -278,7 +322,7 @@ def edit(request, area_name="", item_id=None, submited=False):      if request.POST and request.POST.get('point'):          point_value = request.POST.get('point')      response_dct.update({ -        'actions':actions, +        'actions':actions(response_dct['area_name']),          'action_selected':('contribute', 'edit'),          'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER,          'form':form, @@ -357,7 +401,7 @@ def processRouteFile(request, area_name='', file_id=None):              route = route_file.route              if not route:                  return HttpResponse(status=500) -            return HttpResponse('('+simplejson.dumps({'wkt':route, +            return HttpResponse('(' + json.dumps({'wkt':route,                                                    'file_id':file_id})+')',                                  'application/javascript', status=200)          except OSError as e: @@ -386,7 +430,7 @@ 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, +        'actions':actions(response_dct['area_name']),          'action_selected':('contribute', 'edit-route'),          'error_message':'',          'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER, @@ -414,7 +458,8 @@ def submited(request, area_name="", action=""):      response_dct, redir = get_base_response(area_name)      if redir:          return redir -    response_dct.update({'actions':actions, 'action_selected':action,}) +    response_dct.update({'actions':actions(response_dct['area_name']), +                         'action_selected':action,})      return render_to_response('chimere/submited.html', response_dct,                                context_instance=RequestContext(request)) @@ -425,7 +470,8 @@ def charte(request, area_name=""):      response_dct, redir = get_base_response(area_name)      if redir:          return redir -    response_dct.update({'actions':actions, '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)) @@ -453,11 +499,32 @@ def contactus(request, area_name=""):      response_dct, redir = get_base_response(area_name)      if redir:          return redir -    response_dct.update({'actions':actions, 'action_selected':('contact',), +    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 +    """ +    try: +        page = Page.objects.get(available=True, mnemonic=page_id) +    except ObjectDoesNotExist: +        return redirect(reverse('chimere:index')) +    response_dct, redir = get_base_response(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}) +    tpl = page.template_path if page.template_path \ +                             else 'chimere/default_extra_page.html' +    return render_to_response(tpl, response_dct, +                              context_instance=RequestContext(request)) +  def getDetail(request, area_name, marker_id):      '''      Get the detail for a marker @@ -474,15 +541,14 @@ def getDetail(request, area_name, marker_id):      if request.method == 'GET':          if 'simple' in request.GET and request.GET['simple']:              response_dct['simple'] = True -    parameters = u'current_feature=%s' % marker_id -    parameters += u"&checked_categories=%s" % "_".join([str(m.id) \ -                                              for m in marker.categories.all()]) -    net_dct = getTinyfiedUrl(request, parameters, response_dct['area_name']) -    share_networks = [] +    response_dct['share_networks'], net_dct = \ +                   getShareNetwork(request, response_dct['area_name'], marker)      response_dct['share_url'] = net_dct['url'] -    for network in settings.CHIMERE_SHARE_NETWORKS: -        share_networks.append((network[0], network[1] % net_dct, network[2])) -    response_dct['share_networks'] = share_networks +    net_dct['to'] = settings.CONTACT_EMAIL +    if net_dct['to']: +        net_dct["body"] = _(settings.CHIMERE_MODIF_EMAIL) +        response_dct['modif_by_email'] = 'mailto:?to=%(to)s&subject='\ +                               '%(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 \ @@ -528,17 +594,12 @@ def getGeoObjects(request, area_name, category_ids, status):          status = 'A'      status = status.split('_')      category_ids = category_ids.split('_') -    try: -        q = checkDate(Q(status__in=status, categories__in=category_ids)) -        query = Route.objects.filter(q) -    except: -        return HttpResponse('no results') -    query.order_by('categories') -    routes = list(query) +    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 routes: -        c_cat = route.categories.all()[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 @@ -560,10 +621,28 @@ def getGeoObjects(request, area_name, category_ids, status):      data = '{"type": "FeatureCollection", "features":[%s]}' % ",".join(jsons)      return HttpResponse(data) +def get_all_categories(request, area_name=None): +    ''' +    Get all available categories in JSON +    ''' +    context_data, redir = get_base_response(area_name) +    area = context_data["area"] +    subcategories = [] +    if area: +        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}) +    return HttpResponse(jsons) +  def get_available_categories(request, area_name=None, area=None, status='A',                               force=None):      ''' -    Get categories for a designed area +    Get category menu for a designed area      '''      context_data, redir = get_base_response(area_name)      area = context_data["area"] @@ -608,6 +687,16 @@ def get_available_categories(request, area_name=None, area=None, status='A',      return render_to_response('chimere/blocks/categories.html', context_data,                                         context_instance=RequestContext(request)) +def getCategory(request, area_name='', category_id=0): +    ''' +    Get the JSON for a category (mainly in order to get the description) +    ''' +    try: +        category = SubCategory.objects.get(pk=category_id) +    except ObjectDoesNotExist: +        return HttpResponse('no results') +    return HttpResponse(category.getJSON()) +  def getTinyfiedUrl(request, parameters, area_name=''):      '''      Get the tinyfied version of parameters @@ -648,6 +737,72 @@ def redirectFromTinyURN(request, area_name='', tiny_urn=''):          return redir      return HttpResponseRedirect(response_dct['extra_url'] + parameters) +def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2, +          transport='foot', speed=''): +    ''' +    Get the JSON for a route +    ''' +    try: +        lon1, lat1 = float(lon1), float(lat1) +        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)] +    except ValueError: +        return HttpResponse('no results') +    jsons, desc, total = router.route(lon1, lat1, lon2, lat2, steps=steps, +                                      transport=transport, speed=speed) +    if not jsons: +        return HttpResponse('no results') +    jsonencoder = json.JSONEncoder() +    total = jsonencoder.encode(total) +    desc = jsonencoder.encode(desc) + +    # get associated POIs +    try: +        route = GEOSGeometry(jsons[0]) +    except OGRException: +        return HttpResponse(_(u"Bad geometry"), status=500) +    cats = SubCategory.objects.filter(routing_warn=True) +    message = '' +    if cats.count(): +        st_string = '{"type":"Feature", "geometry":{ "type": "Point", '\ +                 '"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 pt, icon in points: +            st = st_string % (pt.x, pt.y, icon.image.url, icon.image.width, +                              icon.image.height) +            jsons.append(st) +        routes = Route.objects.filter(status='A', categories__in=cats, +                                      route__crosses=route) +        intersect = False +        for rout in routes.intersection(route): +            pts = rout.intersection +            icon = rout.categories.all()[0].icon +            if hasattr(pts, 'x'): +                pts = [pts] +            if pts: +                pt = pts[0] +                st = st_string % (pt.x, pt.y, icon.image.url, icon.image.width, +                              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)) +            else: +                message = '' +    data = '{"properties":{"transport":%s, "total":%s, "description":%s}, '\ +           '"type": "FeatureCollection", "features":[%s]%s}' % ( +            jsonencoder.encode(transport), total, desc, ",".join(jsons), +            message) +    return HttpResponse(data) +  def rss(request, area_name=''):      '''      Redirect to RSS subscription page @@ -655,7 +810,8 @@ def rss(request, area_name=''):      response_dct, redir = get_base_response(area_name)      if redir:          return redir -    response_dct.update({'actions':actions, 'action_selected':('rss',), +    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": | 
