django-web-galleries/django_web_galleries/web_galleries/views.py

354 lines
9.8 KiB
Python

import secrets
from django.views import View
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.contrib.auth.mixins import UserPassesTestMixin
from django.urls import reverse
from django.shortcuts import (
render,
redirect,
get_object_or_404
)
from .forms import (
ImageUploadForm,
GalleryCreatingForm,
AccessCodeForm,
VisitorNameForm
)
from .models import (
Image,
Visitor,
Gallery
)
class VisitorSessionMixin(View):
def get_visitor(self):
if self.request.session:
if 'visitor_session' in self.request.session:
if Visitor.objects.filter(session_id=self.request.session['visitor_session']).exists():
return Visitor.objects.get(session_id=self.request.session['visitor_session'])
else:
visitor = Visitor.objects.create()
self.request.session['visitor_session'] = visitor.session_id
return visitor
else:
return None
def can_access_image(self, image):
if image.private:
return self.get_visitor() == image.uploaded_by or self.get_visitor() in image.visible_to.all()
else:
return True
def can_access_gallery(self, gallery):
if gallery.private:
return self.get_visitor() == gallery.created_by or self.get_visitor() in gallery.visitors.all()
else:
return True
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['visitor'] = self.get_visitor()
return context
class ImageUploadView(VisitorSessionMixin, View):
def get(self, request):
form = ImageUploadForm()
return render(
request,
'upload_image/upload.html',
{
'form': form,
'visitor': self.get_visitor()
}
)
def post(self, request):
form = ImageUploadForm(
request.POST,
request.FILES
)
if form.is_valid():
image = form.save(commit=False)
if image.private:
image.access_code = secrets.token_hex(16)
image.uploaded_by = self.get_visitor()
image.save()
return redirect(
reverse('home')
)
else:
form = ImageUploadForm()
return render(
request,
'upload_image/upload.html',
{
'form': form,
'visitor': self.get_visitor()
}
)
class PublicImageListView(ListView):
model = Image
paginate_by = 20
context_object_name = 'images'
template_name = 'list_images/image_list.html'
def get_queryset(self):
return Image.objects.all().filter(private=False).order_by('-uploaded_when')[:10]
class MyImagesListView(VisitorSessionMixin, View):
def get(self, request):
visitor = self.get_visitor()
uploaded_images = Image.objects.all().filter(
uploaded_by=self.get_visitor()
)
shared_images = Image.objects.all().filter(
visible_to__in=(visitor, )
)
return render(
request,
'image/my_images.html',
{
'uploaded_images': uploaded_images,
'shared_images': shared_images,
'visitor': self.get_visitor()
}
)
class GalleryCreateView(VisitorSessionMixin, View):
def get(self, request):
form = GalleryCreatingForm()
return render(
request,
'gallery/create_gallery.html',
{
'form': form,
'visitor': self.get_visitor()
}
)
def post(self, request):
form = GalleryCreatingForm(
request.POST,
request.FILES
)
if form.is_valid():
gallery = form.save(commit=False)
if gallery.private:
gallery.access_code = secrets.token_hex(16)
gallery.created_by = self.get_visitor()
gallery.save()
for image in request.FILES.getlist('images'):
imageObject = Image.objects.create(
image_file=image,
uploaded_by=gallery.created_by,
private=gallery.private,
access_code=gallery.access_code
)
imageObject.galleries.add(gallery)
imageObject.save()
gallery.save()
return redirect(
reverse('home')
)
else:
form = ImageUploadForm()
return render(
request,
'upload_image/upload.html',
{
'form': form,
'visitor': self.get_visitor()
}
)
class MyGalleriesListView(VisitorSessionMixin, View):
def get(self, request):
visitor = self.get_visitor()
created_galleries = Gallery.objects.all().filter(
created_by=self.get_visitor()
)
invited_galleries = Gallery.objects.all().filter(
visitors__in=(visitor, )
)
return render(
request,
'gallery/my_galleries.html',
{
'created_galleries': created_galleries,
'invited_galleries': invited_galleries,
'visitor': self.get_visitor()
}
)
class GalleryDetailView(VisitorSessionMixin, UserPassesTestMixin, DetailView):
model = Gallery
template_name = 'gallery/gallery_detail.html'
context_object_name = 'gallery'
def test_func(self):
return self.can_access_gallery(
self.get_object()
)
def handle_no_permission(self):
return redirect(
reverse(
'gallery_gain_access',
kwargs={
'gallery_id': self.get_object().id
}
)
)
class ImageDetailView(VisitorSessionMixin, UserPassesTestMixin, DetailView):
model = Image
template_name = 'image/image_detail.html'
context_object_name = 'image'
def test_func(self):
return self.can_access_image(
self.get_object()
)
def handle_no_permission(self):
return redirect(
reverse('home')
)
class GainAccessToGalleryView(VisitorSessionMixin, View):
def _redirect_to_gallery(self, gallery):
return redirect(
reverse(
'gallery',
kwargs={
'pk': gallery.id
}
)
)
def get(self, request, gallery_id):
gallery = get_object_or_404(
Gallery,
id=gallery_id
)
if self.can_access_gallery(gallery):
return self._redirect_to_gallery(gallery)
else:
return render(
self.request,
'gallery/gallery_no_access.html',
{
'form': AccessCodeForm(),
'visitor': self.get_visitor()
}
)
def post(self, request, gallery_id):
gallery = get_object_or_404(
Gallery,
id=gallery_id
)
if self.can_access_gallery(gallery):
return self._redirect_to_gallery(gallery)
else:
form = AccessCodeForm(
request.POST
)
if form.is_valid():
access_code = form.cleaned_data['access_code']
if access_code == gallery.access_code:
gallery.visitors.add(self.get_visitor())
gallery.save()
self.get_visitor().save()
return self._redirect_to_gallery(gallery)
return render(
self.request,
'gallery/gallery_no_access.html',
{
'form': AccessCodeForm(),
'visitor': self.get_visitor()
}
)
class RevokeAccessToGallery(VisitorSessionMixin, View):
def get(self, request, gallery_id, visitor_id):
gallery = get_object_or_404(Gallery, id=gallery_id)
visitor = self.get_visitor()
if visitor == gallery.created_by:
visitor_to_remove = get_object_or_404(Visitor, id=visitor_id)
if visitor_to_remove in gallery.visitors.all():
gallery.visitors.remove(visitor_to_remove)
gallery.access_code = secrets.token_hex(16)
gallery.save()
return redirect(
reverse(
'gallery',
kwargs={
'pk': gallery.id
}
)
)
class VisitorSettingsView(VisitorSessionMixin, View):
def get(self, request):
name_form = VisitorNameForm(
initial={
'name': self.get_visitor().name
}
)
return render(
request,
'visitor/visitor_settings.html',
{
'name_form': name_form,
'visitor': self.get_visitor()
}
)
def post(self, request):
name_form = VisitorNameForm(
request.POST
)
if name_form.is_valid():
visitor = self.get_visitor()
visitor.name = name_form.cleaned_data['name']
visitor.save()
name_form = VisitorNameForm(
initial={
'name': self.get_visitor().name
}
)
return render(
request,
'visitor/visitor_settings.html',
{
'name_form': name_form,
'visitor': self.get_visitor()
}
)