#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2008-2010 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # See the file COPYING for details. """ Views of the project """ import datetime from itertools import groupby from django.utils.translation import ugettext as _ from django.shortcuts import render_to_response from django.template import loader from django.http import HttpResponseRedirect, HttpResponse from django.core import serializers from django.utils.http import urlquote from chimere import settings from chimere.main.actions import actions from chimere.main.models import Category, SubCategory, PropertyModel, Marker, \ Route, News, SimpleArea, Area, Color, TinyUrl from chimere.main.widgets import getMapJS, PointChooserWidget, \ RouteChooserWidget, URL_OSM_JS, URL_OSM_CSS from chimere.main.forms import MarkerForm, RouteForm, ContactForm, \ notifySubmission, notifyStaff def get_base_response(area_name=""): """ Get the base url """ base_response_dct = {'media_path':settings.MEDIA_URL,} base_url = settings.EXTRA_URL if not base_url.startswith('/'): base_url = '/' + base_url if area_name: if base_url[-1] != '/': base_url += '/' base_url += area_name + '/' base_response_dct['extra_url'] = base_url if settings.CSS_AREAS and area_name: base_response_dct['css_area'] = area_name + ".css" base_response_dct['area_name'] = area_name return base_response_dct def index(request, area_name=None, default_area=None, simple=False): """ Main page """ extra = "" tab = " "*4 for url in URL_OSM_CSS: extra += tab + '' % url for url in URL_OSM_JS + ["%sbase.js" % settings.MEDIA_URL, "%smain_map.js" % settings.MEDIA_URL,]: extra += tab + '\n' % url extra += tab + '\n' # show the welcome page today = datetime.date.today().strftime('%y-%m-%d') display_welcome = None if not 'last_visit' in request.session or \ request.session['last_visit'] != today: request.session['last_visit'] = today display_welcome = True response_dct = get_base_response(area_name) areas = None if settings.DISPLAY_AREAS: areas = Area.getAvailable() response_dct.update({'actions':actions, 'action_selected':('view',), 'error_message':'', 'default_area':default_area, 'extra_head':extra + getMapJS(area_name), 'welcome':welcome(request, display_welcome), 'areas':areas, 'map_layer':settings.MAP_LAYER, 'dynamic_categories':settings.DYNAMIC_CATEGORIES, }) # manage permalink if request.GET: for key in ('zoom', 'lon', 'lat', 'display_submited', 'current_feature'): if key in request.GET and request.GET[key]: response_dct['p_'+key] = request.GET[key] else: response_dct['p_'+key] = None if 'checked_categories' in request.GET \ and request.GET['checked_categories']: cats = request.GET['checked_categories'].split('_') response_dct['p_checked_categories'] = ",".join(cats) else: response_dct['p_checked_categories'] = ''; tpl = 'main_map.html' if simple: tpl = 'main_map_simple.html' return render_to_response(tpl, response_dct) def edit(request, area_name=""): """ Edition page """ # If the form has been submited if request.method == 'POST': form = MarkerForm(request.POST, request.FILES) # All validation rules pass if form.is_valid(): marker = form.save() # set the submited status marker.status = 'S' marker.save() notifySubmission(marker) response_dct = get_base_response(area_name) return HttpResponseRedirect(response_dct['extra_url'] + \ 'submited/edit') else: # An unbound form form = MarkerForm() # get the « manualy » declared_fields. Ie: properties declared_fields = form.declared_fields.keys() response_dct = get_base_response(area_name) response_dct.update({'actions':actions, 'action_selected':('contribute', 'edit'), 'error_message':'', 'map_layer':settings.MAP_LAYER, 'form':form, 'extra_head':form.media, 'sub_categories':SubCategory.getAvailable(['M', 'B'], area_name), 'point_widget':PointChooserWidget().render('point', None, area_name=area_name), 'properties':declared_fields, }) # 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('edit.html', response_dct) def editRoute(request, area_name=""): """ Route edition page """ # If the form has been submited if request.method == 'POST': form = RouteForm(request.POST, request.FILES) # All validation rules pass if form.is_valid(): route = form.save() # set the submited status route.status = 'S' route.save() notifySubmission(route) response_dct = get_base_response(area_name) return HttpResponseRedirect(response_dct['extra_url'] + \ 'submited/edit') else: # An unbound form form = RouteForm() # get the « manualy » declared_fields. Ie: properties declared_fields = form.declared_fields.keys() response_dct = get_base_response(area_name) response_dct.update({'actions':actions, 'action_selected':('contribute', 'edit_route'), 'error_message':'', 'map_layer':settings.MAP_LAYER, 'form':form, 'extra_head':form.media, 'sub_categories':SubCategory.getAvailable(['R', 'B'], area_name), 'route_widget':RouteChooserWidget().render('route', None, area_name=area_name), 'properties':declared_fields }) # 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('edit_route.html', response_dct) def welcome(request, display=None): """ Welcome string """ response_dct = {'display':display} response_dct['news_lst'] = News.objects.filter(available=True) return loader.render_to_string('welcome.html', response_dct) def submited(request, area_name="", action=""): """ Successful submission page """ response_dct = get_base_response(area_name) response_dct.update({'actions':actions, 'action_selected':action,}) return render_to_response('submited.html', response_dct) def contactus(request, area_name=""): """ Contact page """ form = None msg = '' # If the form has been submited if request.method == 'POST': 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']) if response: msg = _(u"Thank you for your contribution. It will be taken \ into account. If you have left your email you may be contacted soon for more \ details.") else: msg = _(u"Temporary error. Renew your message later.") else: form = ContactForm() response_dct = get_base_response(area_name) response_dct.update({'actions':actions, 'action_selected':('contact',), 'contact_form':form, 'message':msg}) return render_to_response('contactus.html', response_dct) def getDetail(request, area_name, marker_id): ''' Get the detail for a marker ''' try: marker = Marker.objects.filter(id=int(marker_id), status='A')[0] except (ValueError, IndexError): return HttpResponse('no results') response_dct = get_base_response() response_dct['marker'] = marker 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=%d" % marker.subcategory.id net_dct = getTinyfiedUrl(parameters, area_name) share_networks = [] for network in settings.SHARE_NETWORKS: share_networks.append((network[0], network[1] % net_dct, network[2])) response_dct['share_networks'] = share_networks return render_to_response('detail.html', response_dct) def getDescriptionDetail(request, area_name, category_id): ''' Get the description for a category ''' try: category = Category.objects.filter(id=int(category_id))[0] except (ValueError, IndexError): return HttpResponse('no results') response_dct = get_base_response(area_name) response_dct['category'] = category return render_to_response('category_detail.html', response_dct) def getGeoObjects(request, area_name, category_ids, status): ''' Get the JSON for markers and routes ''' if not status: status = 'A' status = status.split('_') try: query = Route.objects.filter(status__in=status, subcategory__in=category_ids.split('_')) except: return HttpResponse('no results') query.order_by('subcategory') routes = list(query) jsons = [] current_cat, colors, idx = None, None, 0 for route in routes: if not current_cat or current_cat != route.subcategory: idx = 0 current_cat = route.subcategory colors = list(Color.objects.filter(color_theme=\ route.subcategory.color_theme)) jsons.append(route.getGeoJSON(color=colors[idx % len(colors)].code)) idx += 1 try: query = Marker.objects.filter(status__in=status, subcategory__in=category_ids.split('_')) except: return HttpResponse('no results') jsons += [geo_object.getGeoJSON() for geo_object in list(query)] if not jsons: return HttpResponse('no results') data = '{"type": "FeatureCollection", "features":[%s]}' % ",".join(jsons) return HttpResponse(data) def getAvailableCategories(request, area_name=None, area=None, status='A', force=None): ''' Get categories for a designed area ''' if settings.DYNAMIC_CATEGORIES and not area: return "" response_dct = get_base_response('area_name') if not settings.DYNAMIC_CATEGORIES: subcategories = SubCategory.getAvailable() response_dct['sub_categories'] = subcategories return render_to_response('categories.html', response_dct) default_message = "

%s

" % \ _("No category available in this area.") if not status: # there must be a status status = 'A' try: status = status.split('_') area = area.replace('M', '-').replace('D', '.') area = SimpleArea([float(pt) for pt in area.split('_')]) except: # bad area format return HttpResponse(default_message) # if not force and area.isIn(SimpleArea(cookie.AREA):return categories = area.getCategories(status) if not categories: return HttpResponse(default_message) get_cat = lambda subcat: subcat.category get_cat_order = lambda subcat: (subcat.category.order, subcat.category, subcat.order) categories = sorted(categories, key=get_cat_order) subcategories = [(cat, list(subcats)) \ for cat, subcats in groupby(categories, get_cat)] response_dct['sub_categories'] = subcategories return render_to_response('categories.html', response_dct) def getTinyfiedUrl(parameters, area_name=''): ''' Get the tinyfied version of parameters ''' data = {"urn": "", "url":"", "text":""} try: urn = TinyUrl.getUrnByParameters(parameters) except: return {} response_dct = get_base_response(area_name) url = settings.SERVER_URL if url[-1] == '/': url = url[:-1] url += response_dct['extra_url'] + 'ty/' + urn text = settings.PROJECT_NAME if 'current_feature' in parameters: for item in parameters.split('&'): if 'current_feature' in item: try: text = unicode(Marker.objects.get(id=item.split('=')[1])) except (IndexError, Marker.DoesNotExist): pass data["urn"] = urlquote(urn) data["url"] = urlquote(url) data["text"] = urlquote(text) return data def redirectFromTinyURN(request, area_name='', tiny_urn=''): """ Redirect from a tiny Urn """ parameters = '?' + TinyUrl.getParametersByUrn(tiny_urn) response_dct = get_base_response(area_name) return HttpResponseRedirect(response_dct['extra_url'] + parameters)