ojuso-map/apps/map/views.py
2019-08-20 00:10:20 +02:00

262 lines
7.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import logging
from dal import autocomplete
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import UserPassesTestMixin
from django.core.mail import send_mail
from django.db.models import Q
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.urls import reverse_lazy
from django.utils.translation import get_language
from django.views import View
from django.views.generic import DetailView
from django.views.generic.base import TemplateView
from django.views.generic.edit import CreateView
from django.views.generic.edit import UpdateView
from . import forms
from . import models
from apps.files.models import File
logger = logging.getLogger(__name__)
NOTIFY_MESSAGE = """
Hello,
Someone has submitted a new case study to the Ojuso website. Please
follow the below link to look over and approve it:
%s%s
Case Study Robot
"""
class Map(TemplateView):
template_name = "map/index.html"
class CreateCaseStudySelector(LoginRequiredMixin, TemplateView):
template_name = "map/form-selector.html"
class CreatePointOfInterest(LoginRequiredMixin, CreateView):
"""View for base case study form."""
template_name = "map/form-poi.html"
success_url = "/case-study/create/success/"
model = models.PointOfInterest
form_class = forms.PointOfInterest
def send_email(study_id):
"""Sends email to moderator to approve case study."""
try:
send_mail(
"New case study submitted",
NOTIFY_MESSAGE
% (
settings.SITE_URL,
reverse("admin:map_casestudy_change", args=[study_id]),
),
"noreply@ojuso.org",
[settings.DATABASE_EMAIL],
fail_silently=False,
)
except Exception:
logging.exception("Sending mail failed")
# XXX This is bad. We should do something more useful with the error
# than this.
def delete_user_draft(user_id):
""" Delete the draft of a given user """
try:
draft = models.CaseStudyDraft.objects.get(author=user_id)
draft.delete()
except models.CaseStudyDraft.DoesNotExist:
pass
class FilesHandlerMixin:
def remove_bad_fields(self, form):
form.cleaned_data.pop("official_project_documents", None)
form.cleaned_data.pop("other_documents", None)
form.cleaned_data.pop("shapefiles", None)
form.cleaned_data.pop("images", None)
def add_file_refs(self, form):
self.object.official_project_documents.set(
form.cleaned_data.get("official_project_documents_files", [])
)
self.object.other_documents.set(
form.cleaned_data.get("other_documents_files", [])
)
self.object.shapefiles.set(form.cleaned_data.get("shapefiles_files", []))
self.object.images.set(form.cleaned_data.get("images_files", []))
def handle_files(self, form):
self.remove_bad_fields(form)
self.object = form.save()
self.add_file_refs(form)
self.object.save()
class BaseCreateForm(LoginRequiredMixin, FilesHandlerMixin, CreateView):
"""View for base case study form."""
template_name = "map/form-case_study.html"
success_url = reverse_lazy("form-success")
model = models.CaseStudy
def form_valid(self, form):
self.handle_files(form)
self.object.author = self.request.user
self.object.language = get_language()
self.object.form_type = self.form_type
self.object.save()
send_email(self.object.id)
delete_user_draft(self.request.user)
return super().form_valid(form)
class CreateShortCaseStudy(BaseCreateForm):
"""View for short version of case study form."""
form_class = forms.ShortCaseStudyForm
form_type = "short"
class CreateLongCaseStudy(BaseCreateForm):
"""View for long version of case study form."""
form_class = forms.LongCaseStudyForm
form_type = "long"
class CreateCaseStudySuccess(TemplateView):
template_name = "map/form-success.html"
class ViewCaseStudyDetail(DetailView):
template_name = "map/detail.html"
model = models.CaseStudy
context_object_name = "case_study"
class BaseEditForm(LoginRequiredMixin, FilesHandlerMixin, UpdateView):
"""View for base case study form."""
template_name = "map/form-case_study.html"
success_url = reverse_lazy("form-success")
model = models.CaseStudy
def form_valid(self, form):
self.handle_files(form)
return super().form_valid(form)
class EditCaseStudy(UserPassesTestMixin, BaseEditForm):
form_class = forms.ShortCaseStudyForm
def test_func(self):
if settings.FFCAN_EDIT is False:
return False
object = self.get_object()
if object.author:
author = object.author.id
else:
author = -1
return self.request.user.is_authenticated and (author is self.request.user.id)
class SpatialRefSysAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = models.SpatialRefSys.objects.all()
if self.q:
qs = qs.filter(
Q(auth_name__icontains=self.q) | Q(auth_srid__icontains=self.q)
)
return qs
class DraftsAPI(LoginRequiredMixin, View):
"""
Retrieve or save a draft.
XXX This should be refactored to use csrf protection.
"""
def get(self, request):
draft = get_object_or_404(models.CaseStudyDraft, author=request.user)
return HttpResponse(draft.data, content_type="application/json")
def put(self, request):
try:
draft = models.CaseStudyDraft.objects.get(author=request.user)
draft.data = request.body.decode()
draft.save()
return HttpResponse(status=200) # OK
except models.CaseStudyDraft.DoesNotExist:
# If it doesn't exist, create it
models.CaseStudyDraft.objects.create(
author=request.user, data=request.body.decode()
)
return HttpResponse(status=201) # Created
def delete(self, request):
draft = get_object_or_404(models.CaseStudyDraft, author=request.user)
data = json.loads(draft.data)
for k in [
"official_project_documents",
"other_documents",
"shapefiles",
"images",
]:
try:
keyname = k + "_files"
field = data["data"]["form"][keyname]
# Ignore empty fields
if field["value"] == "":
continue
file_list = json.loads(field["value"])
# Delete those items
for item in file_list:
try:
f = File.objects.get(id=item["id"])
if f.user != self.request.user:
continue
f.delete()
except File.DoesNotExist:
continue
except Exception: # XXX What are we guarding against here?
continue
draft.delete()
return HttpResponse(status=204)