ojuso-map/apps/map/views.py

267 lines
7.3 KiB
Python
Raw Normal View History

import json
2019-08-19 21:53:34 +00:00
import logging
2019-08-19 21:53:34 +00:00
from dal import autocomplete
from django.conf import settings
2019-08-19 21:53:34 +00:00
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
2019-08-19 21:52:27 +00:00
from django.http import HttpResponse
2019-08-19 21:53:34 +00:00
from django.shortcuts import get_object_or_404
from django.urls import reverse
2019-03-04 19:48:29 +00:00
from django.urls import reverse_lazy
from django.utils.translation import get_language
2018-04-14 02:40:42 +00:00
from django.views import View
from django.views.generic import DetailView
from django.views.generic.base import TemplateView
2019-08-19 21:53:34 +00:00
from django.views.generic.edit import CreateView
from django.views.generic.edit import UpdateView
2019-08-19 21:52:27 +00:00
from . import forms
2019-08-19 21:53:34 +00:00
from . import models
from .forms import LongCaseStudyForm
from .forms import ShortCaseStudyForm
from .models import CaseStudy
from .models import CaseStudyDraft
from .models import SpatialRefSys
from apps.files.models import File
2019-08-19 21:52:27 +00:00
logger = logging.getLogger(__name__)
2018-04-14 02:40:42 +00:00
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
"""
2017-06-16 16:06:22 +00:00
2019-08-19 21:37:32 +00:00
class Map(TemplateView):
template_name = "map/index.html"
2017-06-16 16:06:22 +00:00
class CreateCaseStudySelector(LoginRequiredMixin, TemplateView):
template_name = "map/form-selector.html"
2017-06-16 16:06:22 +00:00
class CreatePointOfInterest(LoginRequiredMixin, CreateView):
"""View for base case study form."""
2019-08-19 21:37:32 +00:00
template_name = "map/form-poi.html"
success_url = "/case-study/create/success/"
2019-08-19 21:52:27 +00:00
model = models.PointOfInterest
form_class = forms.PointOfInterest
2019-03-04 19:48:29 +00:00
def send_email(study_id):
"""Sends email to moderator to approve case study."""
2019-03-04 19:48:29 +00:00
try:
send_mail(
2019-08-19 21:37:32 +00:00
"New case study submitted",
NOTIFY_MESSAGE
% (
settings.SITE_URL,
2019-08-19 21:37:32 +00:00
reverse("admin:map_casestudy_change", args=[study_id]),
),
2019-08-19 21:37:32 +00:00
"noreply@ojuso.org",
[settings.DATABASE_EMAIL],
fail_silently=False,
)
2019-08-19 21:52:27 +00:00
except Exception:
logging.exception("Sending mail failed")
2019-03-04 19:48:29 +00:00
# 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 = CaseStudyDraft.objects.get(author=user_id)
draft.delete()
except CaseStudyDraft.DoesNotExist:
pass
class FilesHandlerMixin:
def remove_bad_fields(self, form):
2019-08-19 21:37:32 +00:00
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)
2018-04-23 05:15:33 +00:00
2019-03-04 19:48:29 +00:00
def add_file_refs(self, form):
2019-08-19 21:37:32 +00:00
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", []))
2018-04-23 05:15:33 +00:00
def handle_files(self, form):
2019-03-04 19:48:29 +00:00
self.remove_bad_fields(form)
self.object = form.save()
self.add_file_refs(form)
2018-05-30 03:16:22 +00:00
self.object.save()
2019-03-04 19:48:29 +00:00
class BaseCreateForm(LoginRequiredMixin, FilesHandlerMixin, CreateView):
"""View for base case study form."""
2019-08-19 21:37:32 +00:00
template_name = "map/form-case_study.html"
success_url = reverse_lazy("form-success")
2019-03-04 19:48:29 +00:00
model = CaseStudy
2019-03-04 19:48:29 +00:00
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()
2019-03-04 19:48:29 +00:00
send_email(self.object.id)
delete_user_draft(self.request.user)
return super().form_valid(form)
class CreateShortCaseStudy(BaseCreateForm):
2017-10-09 23:58:36 +00:00
"""View for short version of case study form."""
2019-08-19 21:37:32 +00:00
form_class = ShortCaseStudyForm
form_type = "short"
class CreateLongCaseStudy(BaseCreateForm):
2017-10-09 23:58:36 +00:00
"""View for long version of case study form."""
2019-08-19 21:37:32 +00:00
form_class = LongCaseStudyForm
form_type = "long"
class CreateCaseStudySuccess(TemplateView):
2019-08-19 21:37:32 +00:00
template_name = "map/form-success.html"
2017-10-09 23:58:36 +00:00
class ViewCaseStudyDetail(DetailView):
template_name = "map/detail.html"
model = CaseStudy
context_object_name = "case_study"
2018-04-14 02:40:42 +00:00
2019-03-04 19:48:29 +00:00
class BaseEditForm(LoginRequiredMixin, FilesHandlerMixin, UpdateView):
"""View for base case study form."""
2019-08-19 21:37:32 +00:00
template_name = "map/form-case_study.html"
success_url = reverse_lazy("form-success")
2019-03-04 19:48:29 +00:00
model = CaseStudy
def form_valid(self, form):
self.handle_files(form)
return super().form_valid(form)
2019-03-04 19:48:29 +00:00
class EditCaseStudy(UserPassesTestMixin, BaseEditForm):
2019-03-04 19:48:29 +00:00
form_class = 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
2019-08-19 21:37:32 +00:00
return self.request.user.is_authenticated and (author is self.request.user.id)
2019-03-04 19:48:29 +00:00
class SpatialRefSysAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = SpatialRefSys.objects.all()
if self.q:
qs = qs.filter(
2019-08-19 21:37:32 +00:00
Q(auth_name__icontains=self.q) | Q(auth_srid__icontains=self.q)
)
return qs
class DraftsAPI(LoginRequiredMixin, View):
2019-04-07 16:47:03 +00:00
"""
Retrieve or save a draft.
XXX This should be refactored to use csrf protection.
"""
2018-04-14 02:40:42 +00:00
def get(self, request):
2019-08-19 21:52:27 +00:00
draft = get_object_or_404(models.CaseStudyDraft, author=request.user)
2019-08-19 21:52:27 +00:00
return HttpResponse(draft.data, content_type="application/json")
2018-04-14 02:40:42 +00:00
def put(self, request):
2019-08-19 21:52:27 +00:00
try:
draft = CaseStudyDraft.objects.get(author=request.user)
draft.data = request.body.decode()
2018-04-14 02:40:42 +00:00
draft.save()
2019-08-19 21:37:32 +00:00
return HttpResponse(status=200) # OK
2018-04-14 02:40:42 +00:00
2019-08-19 21:52:27 +00:00
except models.CaseStudyDraft.DoesNotExist:
# If it doesn't exist, create it
2019-08-19 21:53:34 +00:00
CaseStudyDraft.objects.create(
author=request.user, data=request.body.decode()
)
2019-08-19 21:52:27 +00:00
return HttpResponse(status=201) # Created
2019-08-19 21:52:27 +00:00
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
2019-08-19 21:52:27 +00:00
file_list = json.loads(field["value"])
2019-08-19 21:52:27 +00:00
# Delete those items
for item in file_list:
try:
f = File.objects.get(id=item["id"])
if f.user != self.request.user:
continue
2019-08-19 21:52:27 +00:00
f.delete()
except File.DoesNotExist:
continue
2019-08-19 21:52:27 +00:00
except Exception: # XXX What are we guarding against here?
continue
2019-08-19 21:52:27 +00:00
draft.delete()
2018-04-23 05:15:33 +00:00
2018-04-14 02:40:42 +00:00
return HttpResponse(status=204)