import json import datetime from django.conf import settings from django.contrib import messages from django.core.urlresolvers import reverse from django.core.mail import send_mail from django.core.signing import BadSignature from django.http import ( JsonResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseNotFound) from django.shortcuts import render, redirect, get_object_or_404 from django.template.loader import get_template from django.views.generic import View import pytz from .forms import ManageActionForm, PublicContribForm from .models import Contrib from .decorators import prevent_robots from .tokens import ContribTokenManager, URLTokenManager, TokenError @prevent_robots() def add_contrib(request): if request.method == 'GET': form = PublicContribForm() elif request.method == 'POST': form = PublicContribForm(request.POST) if form.is_valid(): contrib = form.save() # Send notification email to site administrator if len(settings.NOTIFICATION_EMAILS) > 0: context = { 'contrib_url': settings.SITE_URL + reverse('display_map') + '#{}'.format(contrib.id), 'contrib': contrib, } subject = get_template( admin_subject = get_template( 'contribmap/mails/new_contrib_moderator_notice.subject') admin_body = get_template( 'contribmap/mails/new_contrib_moderator_notice.txt') send_mail( admin_subject.render(context), admin_body.render(context), settings.DEFAULT_FROM_EMAIL, settings.NOTIFICATION_EMAILS, ) return redirect(reverse('thanks')) return render(request, 'contribmap/wifi-form.html', { 'form': form, 'isp':settings.ISP, }) def manage_contrib(request, pk): """ Contribution management by the user itself Auth is done by signed token """ try: token = request.GET['token'] except KeyError: return HttpResponseForbidden( 'Missing authorization token') pk = int(pk) try: contrib = ContribTokenManager().get_instance_if_allowed(token, pk) except TokenError: return HttpResponseForbidden( 'Bad signature, or expired token') else: if not contrib: return HttpResponseNotFound("Inexistant Contrib") wanabe_expiration_date = contrib.get_postponed_expiration_date( datetime.datetime.now(pytz.utc)) if request.POST: action_form = ManageActionForm(request.POST) if not action_form.is_valid(): return HttpResponseBadRequest('Action invalide') action = action_form.cleaned_data['action'] if action == action_form.ACTION_DELETE: contrib.delete() messages.add_message( request, messages.INFO, 'Votre demande a bien été supprimée.') return redirect(reverse('display_map')) elif action == action_form.ACTION_RENEW: contrib.expiration_date = wanabe_expiration_date contrib.save() messages.add_message( request, messages.INFO, "Votre demande a été prolongée jusqu'au {:%d/%m/%Y}".format( contrib.expiration_date)) else: return HttpResponseBadRequest('Action invalide') return render(request, 'contribmap/manage_contrib.html', { 'contrib': contrib, 'wanabe_expiration_date': wanabe_expiration_date, 'delete_form': ManageActionForm({ 'action': ManageActionForm.ACTION_DELETE }), 'renew_form': ManageActionForm({ 'action': ManageActionForm.ACTION_RENEW }), 'messages': messages.api.get_messages(request), 'isp': settings.ISP, }) def display_map(request): private_mode = request.user.is_authenticated() if private_mode: json_url = reverse('private_json') else: json_url = reverse('public_json') return render(request, 'contribmap/map.html', { 'private_mode': private_mode, 'json_url': json_url, 'isp':settings.ISP, }) def thanks(request): return render(request, 'contribmap/thanks.html', { 'isp':settings.ISP, }) def legal(request): return render(request, 'contribmap/legal.html', { 'isp':settings.ISP, }) class JSONContribView(View): def get(self, request): return JsonResponse({ "id": self.ID, "license": self.LICENSE, "features": self.get_features(), }) PLACE_PROPERTIES = [ 'floor', 'angles', 'orientations', 'roof', 'floor', 'floor_total'] class PublicJSON(JSONContribView): ID = 'public' LICENSE = { "type": "ODC-BY-1.0", "url": "http:\/\/opendatacommons.org\/licenses\/by\/1.0\/" } def get_features(self): contribs = Contrib.objects.all() data = [] for i in contribs: if not i.is_public(): continue data.append({ "id": i.pk, "type": "Feature", "geometry": { "coordinates": [ i.longitude, i.latitude ], "type": "Point", }, "properties": { "contrib_type": i.contrib_type, "name": i.get_public_field('name'), "place": { k: i.get_public_field(k) for k in self.PLACE_PROPERTIES }, "comment": i.get_public_field('comment'), } }) return data class PrivateJSON(JSONContribView): ID = 'private' LICENSE = { "type": "Copyright", } def dispatch(self, request, *args, **kwargs): if hasattr(request, 'user') and request.user.is_staff: return super().dispatch(request, *args, **kwargs) else: return HttpResponseForbidden('Need staff access') def get_features(self): contribs = Contrib.objects.all() data = [] for i in contribs: data.append({ "id": i.pk, "type": "Feature", "geometry": { "coordinates": [ i.longitude, i.latitude, ], "type": "Point", }, "properties": { "contrib_type": i.contrib_type, "name": i.name, "place": { k: getattr(i, k) for k in self.PLACE_PROPERTIES }, "comment": i.comment, "phone": i.phone, "email": i.email } }) return data