annotate user_photos/views.py @ 972:7138883966b3

Started unit tests for hotlinking images.
author Brian Neal <bgneal@gmail.com>
date Wed, 23 Sep 2015 21:26:09 -0500
parents 4f265f61874b
children d9cd3180c12c
rev   line source
bgneal@695 1 """Views for the user_photos application."""
bgneal@722 2 import json
bgneal@722 3
bgneal@695 4 from django.conf import settings
bgneal@704 5 from django.contrib.auth import get_user_model
bgneal@695 6 from django.contrib.auth.decorators import login_required
bgneal@722 7 from django.http import (HttpResponse, HttpResponseForbidden,
bgneal@971 8 HttpResponseNotAllowed, JsonResponse)
bgneal@704 9 from django.shortcuts import render, redirect, get_object_or_404
bgneal@704 10 from django.views.generic import ListView
bgneal@710 11 from django.views.decorators.http import require_POST
bgneal@704 12 from django.utils.decorators import method_decorator
bgneal@710 13 from django.contrib import messages
bgneal@695 14
bgneal@971 15 from user_photos.forms import HotLinkImageForm, UploadForm
bgneal@704 16 from user_photos.models import Photo
bgneal@718 17 from user_photos.s3 import delete_photos
bgneal@695 18
bgneal@695 19
bgneal@695 20 @login_required
bgneal@695 21 def upload(request):
bgneal@695 22 """This view function receives an uploaded image file from a user.
bgneal@695 23 The photo will be resized if necessary and a thumbnail image will be
bgneal@695 24 created. The image and thumbnail will then be uploaded to the Amazon
bgneal@695 25 S3 service for storage.
bgneal@695 26
bgneal@695 27 """
bgneal@695 28 form = None
bgneal@696 29 uploads_enabled = settings.USER_PHOTOS_ENABLED
bgneal@695 30
bgneal@695 31 if uploads_enabled:
bgneal@695 32 if request.method == 'POST':
bgneal@696 33 form = UploadForm(request.POST, request.FILES, user=request.user)
bgneal@695 34 if form.is_valid():
bgneal@696 35 photo = form.save()
bgneal@696 36 return redirect(photo)
bgneal@695 37 else:
bgneal@696 38 form = UploadForm(user=request.user)
bgneal@695 39
bgneal@695 40 return render(request, 'user_photos/upload_form.html', {
bgneal@695 41 'enabled': uploads_enabled,
bgneal@695 42 'form': form,
bgneal@695 43 },
bgneal@695 44 status=200 if uploads_enabled else 503)
bgneal@704 45
bgneal@704 46
bgneal@722 47 def upload_ajax(request):
bgneal@722 48 """This view is the ajax version of the upload function, above.
bgneal@722 49
bgneal@722 50 We return a JSON object response to the client with the following name
bgneal@722 51 & value pairs:
bgneal@722 52 'success' : false for failure and true for success
bgneal@722 53 'msg' : string error message if success is false
bgneal@722 54 'url' : the image URL as a string if success
bgneal@722 55
bgneal@722 56 If a non-200 status code is returned the response will simply be a text
bgneal@722 57 string error message.
bgneal@722 58
bgneal@722 59 """
bgneal@722 60 if not request.user.is_authenticated():
bgneal@724 61 return HttpResponseForbidden('Please login to use this service')
bgneal@722 62 if not request.is_ajax() or request.method != 'POST':
bgneal@724 63 return HttpResponseNotAllowed('This method is not allowed')
bgneal@722 64
bgneal@722 65 ret = {'success': False, 'msg': '', 'url': ''}
bgneal@722 66 if settings.USER_PHOTOS_ENABLED:
bgneal@722 67 form = UploadForm(request.POST, request.FILES, user=request.user)
bgneal@722 68 if form.is_valid():
bgneal@722 69 photo = form.save()
bgneal@722 70 ret['success'] = True
bgneal@722 71 ret['url'] = photo.url
bgneal@722 72 else:
bgneal@722 73 # gather form error messages
bgneal@722 74 errors = []
bgneal@722 75 non_field_errors = form.non_field_errors().as_text()
bgneal@722 76 if non_field_errors:
bgneal@722 77 errors.append(non_field_errors)
bgneal@722 78 for field_errors in form.errors.values():
bgneal@722 79 errors.append(field_errors.as_text())
bgneal@722 80 ret['msg'] = '\n'.join(errors)
bgneal@722 81 else:
bgneal@722 82 ret['msg'] = 'Photo uploads are temporarily disabled'
bgneal@722 83
bgneal@722 84 return HttpResponse(json.dumps(ret), content_type='application/json')
bgneal@722 85
bgneal@722 86
bgneal@704 87 class GalleryView(ListView):
bgneal@704 88 """A ListView for displaying a user's photos"""
bgneal@704 89
bgneal@704 90 template_name = 'user_photos/gallery.html'
bgneal@704 91 context_object_name = 'photos'
bgneal@704 92 paginate_by = 50
bgneal@704 93 allow_empty = True
bgneal@704 94
bgneal@704 95 def get_queryset(self):
bgneal@704 96 self.gallery_owner = get_object_or_404(get_user_model(),
bgneal@704 97 username=self.kwargs['username'])
bgneal@704 98 return Photo.objects.filter(user=self.gallery_owner).order_by('-upload_date')
bgneal@704 99
bgneal@704 100 def get_context_data(self, **kwargs):
bgneal@704 101 context = super(GalleryView, self).get_context_data(**kwargs)
bgneal@704 102 context['gallery_owner'] = self.gallery_owner
bgneal@704 103 return context
bgneal@704 104
bgneal@704 105 @method_decorator(login_required)
bgneal@704 106 def dispatch(self, *args, **kwargs):
bgneal@704 107 return super(GalleryView, self).dispatch(*args, **kwargs)
bgneal@710 108
bgneal@710 109
bgneal@710 110 @login_required
bgneal@710 111 @require_POST
bgneal@710 112 def delete(request):
bgneal@718 113 """A view function to allow a user to delete their own photos."""
bgneal@718 114
bgneal@718 115 ret_view, username = 'user_photos-gallery', request.user.username
bgneal@718 116
bgneal@718 117 if not settings.USER_PHOTOS_ENABLED:
bgneal@718 118 messages.error(request, "This function is disabled temporarily")
bgneal@718 119 return redirect(ret_view, username)
bgneal@718 120
bgneal@710 121 photo_ids = []
bgneal@710 122 for photo_id in request.POST.getlist('photo_id'):
bgneal@710 123 try:
bgneal@710 124 n = int(photo_id)
bgneal@710 125 except ValueError:
bgneal@710 126 continue
bgneal@710 127 photo_ids.append(n)
bgneal@710 128
bgneal@710 129 count = 0
bgneal@710 130 if photo_ids:
bgneal@710 131 qs = Photo.objects.filter(user=request.user, pk__in=photo_ids)
bgneal@718 132 count = len(qs)
bgneal@718 133 if count:
bgneal@718 134 delete_photos(qs)
bgneal@718 135 qs.delete()
bgneal@710 136
bgneal@718 137 msg = "{} photo{} deleted".format(count, '' if count == 1 else 's')
bgneal@718 138 messages.add_message(request,
bgneal@718 139 messages.SUCCESS if count > 0 else messages.WARNING,
bgneal@718 140 msg)
bgneal@710 141
bgneal@718 142 return redirect(ret_view, username)
bgneal@971 143
bgneal@971 144
bgneal@971 145 def hotlink_image(request):
bgneal@971 146 """This view is responsible for accepting an image URL from a user and
bgneal@971 147 converting it to a URL pointing into our S3 bucket if necessary.
bgneal@971 148
bgneal@971 149 We return a JSON object response to the client with the following name
bgneal@971 150 & value pairs:
bgneal@971 151 'error_msg': string error message if an error occurred
bgneal@971 152 'url': the image URL as a string if success
bgneal@971 153 """
bgneal@971 154 ret = {'error_msg': '', 'url': ''}
bgneal@971 155 status_code = 400
bgneal@971 156
bgneal@971 157 if not request.user.is_authenticated():
bgneal@971 158 ret['error_msg'] = 'Please login to use this service'
bgneal@972 159 return JsonResponse(ret, status=403)
bgneal@971 160 if not request.is_ajax() or request.method != 'POST':
bgneal@971 161 ret['error_msg'] = 'This method is not allowed'
bgneal@972 162 return JsonResponse(ret, status=405)
bgneal@971 163
bgneal@971 164 if settings.USER_PHOTOS_ENABLED:
bgneal@972 165 form = HotLinkImageForm(request.POST, user=request.user)
bgneal@971 166 if form.is_valid():
bgneal@971 167 try:
bgneal@971 168 ret['url'] = form.save()
bgneal@971 169 status_code = 200
bgneal@971 170 except Exception as ex:
bgneal@971 171 ret['error_msg'] = str(ex)
bgneal@971 172 status_code = 500
bgneal@971 173 else:
bgneal@971 174 # gather form error messages
bgneal@971 175 errors = []
bgneal@971 176 non_field_errors = form.non_field_errors().as_text()
bgneal@971 177 if non_field_errors:
bgneal@971 178 errors.append(non_field_errors)
bgneal@971 179 for field_errors in form.errors.values():
bgneal@971 180 errors.append(field_errors.as_text())
bgneal@971 181 ret['error_msg'] = '\n'.join(errors)
bgneal@971 182 else:
bgneal@971 183 ret['error_msg'] = 'Image linking is temporarily disabled'
bgneal@971 184 status_code = 403
bgneal@971 185
bgneal@971 186 return JsonResponse(ret, status=status_code)
bgneal@971 187