ojuso-map/apps/map/views.py

267 lines
7.3 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
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.core.mail import send_mail
from django.db.models import Q
from django.http import Http404, HttpResponse
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, UpdateView
from dal import autocomplete
from apps.files.models import File
from .models import CaseStudy, CaseStudyDraft, SpatialRefSys, PointOfInterest
from .forms import ShortCaseStudyForm, LongCaseStudyForm, PointOfInterest
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 = PointOfInterest
form_class = 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:
# XXX This is bad. We should do something more useful with the error
# than this.
pass
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):
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 = 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 = ShortCaseStudyForm
form_type = "short"
class CreateLongCaseStudy(BaseCreateForm):
"""View for long version of case study form."""
form_class = LongCaseStudyForm
form_type = "long"
class CreateCaseStudySuccess(TemplateView):
template_name = 'map/form-success.html'
class ViewCaseStudyDetail(DetailView):
template_name = "map/detail.html"
model = 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 = CaseStudy
def form_valid(self, form):
self.handle_files(form)
return super().form_valid(form)
class EditCaseStudy(UserPassesTestMixin, BaseEditForm):
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
return self.request.user.is_authenticated and (
author is self.request.user.id
)
class SpatialRefSysAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = 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_object(self, request):
try:
return CaseStudyDraft.objects.get(author=request.user)
except:
return None
def get(self, request):
draft = self.get_object(request)
if draft == None:
return HttpResponse(status=404) # Not Found
else:
return HttpResponse(draft.data, content_type="application/json")
def put(self, request):
# Find an existing object is there is one
draft = self.get_object(request)
if draft == None:
# If there isn't, create a new draft...
draft = CaseStudyDraft(author=request.user, data=request.body.decode())
draft.save()
return HttpResponse(status=201) # Created
else:
draft.data = request.body.decode()
draft.save()
return HttpResponse(status=200) # OK
def delete(self, request):
draft = self.get_object(request)
if draft != None:
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:
continue
draft.delete()
return HttpResponse(status=204)