refactor some of the common image code into a PictureViewMixin, and make pictures work with the devserver
This commit is contained in:
parent
c532dac146
commit
b151192d02
|
@ -3,6 +3,8 @@ from django.shortcuts import redirect
|
|||
from django.urls import reverse
|
||||
from . import models
|
||||
from django.contrib import messages
|
||||
import sys, mimetypes
|
||||
from django.http import Http404, HttpResponse
|
||||
|
||||
|
||||
class CreateProposalMixin(SingleObjectMixin):
|
||||
|
@ -46,3 +48,42 @@ class EnsureUserOwnsProposalMixin(SingleObjectMixin):
|
|||
# alright, continue with the request
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class PictureViewMixin(SingleObjectMixin):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# do we have the requested picture?
|
||||
if kwargs['picture'] == 'thumbnail':
|
||||
if self.get_object().picture_small:
|
||||
self.picture = self.get_object().picture_small
|
||||
else:
|
||||
raise Http404()
|
||||
elif kwargs['picture'] == 'large':
|
||||
if self.get_object().picture_large:
|
||||
self.picture = self.get_object().picture_large
|
||||
else:
|
||||
raise Http404()
|
||||
else:
|
||||
# only 'thumbnail' and 'large' pictures supported
|
||||
raise Http404()
|
||||
|
||||
# alright, continue with the request
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_picture_response(self):
|
||||
if 'runserver' in sys.argv or 'runserver_plus' in sys.argv:
|
||||
# this is a local devserver situation, guess mimetype from extension and return picture directly
|
||||
response = HttpResponse(self.picture, content_type=mimetypes.types_map[".%s" % self.picture.name.split(".")[-1]])
|
||||
else:
|
||||
# make nginx serve the picture using X-Accel-Redirect
|
||||
# (this works for nginx only, other webservers use x-sendfile)
|
||||
# maybe make the header name configurable
|
||||
response = HttpResponse()
|
||||
response['X-Accel-Redirect'] = '/public/speakerproposals/%(campslug)s/%(proposaluuid)s/%(filename)s' % {
|
||||
'campslug': self.camp.slug,
|
||||
'proposaluuid': self.get_object().uuid,
|
||||
'filename': os.path.basename(self.picture.name),
|
||||
}
|
||||
response['Content-Type'] = ''
|
||||
return response
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.contrib import messages
|
|||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
from camps.mixins import CampViewMixin
|
||||
from .mixins import CreateProposalMixin, EnsureUnapprovedProposalMixin, EnsureUserOwnsProposalMixin, EnsureWritableCampMixin
|
||||
from .mixins import CreateProposalMixin, EnsureUnapprovedProposalMixin, EnsureUserOwnsProposalMixin, EnsureWritableCampMixin, PictureViewMixin
|
||||
from . import models
|
||||
import datetime, os
|
||||
|
||||
|
@ -77,7 +77,7 @@ class SpeakerProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwn
|
|||
|
||||
|
||||
@method_decorator(require_safe, name='dispatch')
|
||||
class SpeakerProposalPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
|
||||
class SpeakerProposalPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, PictureViewMixin, DetailView):
|
||||
model = models.SpeakerProposal
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
@ -85,31 +85,8 @@ class SpeakerProposalPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOw
|
|||
if self.get_object().user != request.user:
|
||||
raise Http404()
|
||||
|
||||
# do we have the requested picture?
|
||||
if kwargs['picture'] == 'thumbnail':
|
||||
if self.get_object().picture_small:
|
||||
picture = self.get_object().picture_small
|
||||
else:
|
||||
raise Http404()
|
||||
elif kwargs['picture'] == 'large':
|
||||
if self.get_object().picture_large:
|
||||
picture = self.get_object().picture_large
|
||||
else:
|
||||
raise Http404()
|
||||
else:
|
||||
# only 'thumbnail' and 'large' pictures supported
|
||||
raise Http404()
|
||||
|
||||
# make nginx return the picture using X-Accel-Redirect
|
||||
# (this works for nginx only, other webservers use x-sendfile),
|
||||
# TODO: what about runserver mode here?
|
||||
response = HttpResponse()
|
||||
response['X-Accel-Redirect'] = '/public/speakerproposals/%(campslug)s/%(proposaluuid)s/%(filename)s' % {
|
||||
'campslug': self.camp.slug,
|
||||
'proposaluuid': self.get_object().uuid,
|
||||
'filename': os.path.basename(picture.name),
|
||||
}
|
||||
response['Content-Type'] = ''
|
||||
# get and return the response
|
||||
response = self.get_picture_response()
|
||||
return response
|
||||
|
||||
|
||||
|
@ -163,38 +140,11 @@ class EventProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsP
|
|||
|
||||
|
||||
@method_decorator(require_safe, name='dispatch')
|
||||
class SpeakerPictureView(CampViewMixin, DetailView):
|
||||
class SpeakerPictureView(CampViewMixin, PictureViewMixin, DetailView):
|
||||
model = models.Speaker
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
# is the speaker public, or owned by current user?
|
||||
if not self.get_object().is_public and self.get_object().user != request.user:
|
||||
raise Http404()
|
||||
|
||||
# do we have the requested picture?
|
||||
if kwargs['picture'] == 'thumbnail':
|
||||
if self.get_object().picture_small:
|
||||
picture = self.get_object().picture_small
|
||||
else:
|
||||
raise Http404()
|
||||
elif kwargs['picture'] == 'large':
|
||||
if self.get_object().picture_large:
|
||||
picture = self.get_object().picture_large
|
||||
else:
|
||||
raise Http404()
|
||||
else:
|
||||
raise Http404()
|
||||
|
||||
# make nginx return the picture using X-Accel-Redirect
|
||||
# (this works for nginx only, other webservers use x-sendfile),
|
||||
# TODO: what about runserver mode here?
|
||||
response = HttpResponse()
|
||||
response['X-Accel-Redirect'] = '/public/speakers/%(campslug)s/%(speakerslug)s/%(filename)s' % {
|
||||
'campslug': self.camp.slug,
|
||||
'speakerslug': self.get_object().slug,
|
||||
'filename': os.path.basename(picture.name),
|
||||
}
|
||||
response['Content-Type'] = ''
|
||||
response = self.get_picture_response()
|
||||
return response
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue