annotate user_photos/views.py @ 1107:977e76f7f736

POTD converted to V3 design.
author Brian Neal <bgneal@gmail.com>
date Wed, 06 Jul 2016 21:41:16 -0500
parents d9cd3180c12c
children 364f8ec48612
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@1096 87 def upload_ajax_v3(request):
bgneal@1096 88 """This view is the V3 ajax version of the upload function, above.
bgneal@1096 89
bgneal@1096 90 We return a JSON object response to the client with the following name
bgneal@1096 91 & value pairs:
bgneal@1096 92 'msg' : string error message if success is false
bgneal@1096 93 'url' : the image URL as a string if success
bgneal@1096 94 """
bgneal@1096 95 ret = {'error_msg': '', 'url': ''}
bgneal@1096 96 status_code = 400
bgneal@1096 97
bgneal@1096 98 if not request.user.is_authenticated():
bgneal@1096 99 ret['error_msg'] = 'Please login to use this service'
bgneal@1096 100 return JsonResponse(ret, status=403)
bgneal@1096 101 if not request.is_ajax() or request.method != 'POST':
bgneal@1096 102 ret['error_msg'] = 'This method is not allowed'
bgneal@1096 103 return JsonResponse(ret, status=405)
bgneal@1096 104
bgneal@1096 105 if settings.USER_PHOTOS_ENABLED:
bgneal@1096 106 form = UploadForm(request.POST, request.FILES, user=request.user)
bgneal@1096 107 if form.is_valid():
bgneal@1096 108 try:
bgneal@1096 109 photo = form.save()
bgneal@1096 110 ret['url'] = photo.url
bgneal@1096 111 status_code = 200
bgneal@1096 112 except Exception as ex:
bgneal@1096 113 ret['error_msg'] = str(ex)
bgneal@1096 114 status_code = 500
bgneal@1096 115 else:
bgneal@1096 116 # gather form error messages
bgneal@1096 117 errors = []
bgneal@1096 118 non_field_errors = form.non_field_errors().as_text()
bgneal@1096 119 if non_field_errors:
bgneal@1096 120 errors.append(non_field_errors)
bgneal@1096 121 for field_errors in form.errors.values():
bgneal@1096 122 errors.append(field_errors.as_text())
bgneal@1096 123 ret['msg'] = '\n'.join(errors)
bgneal@1096 124 else:
bgneal@1096 125 ret['msg'] = 'Photo uploads are temporarily disabled'
bgneal@1096 126 status_code = 403
bgneal@1096 127
bgneal@1096 128 return JsonResponse(ret, status=status_code)
bgneal@1096 129
bgneal@1096 130
bgneal@704 131 class GalleryView(ListView):
bgneal@704 132 """A ListView for displaying a user's photos"""
bgneal@704 133
bgneal@704 134 template_name = 'user_photos/gallery.html'
bgneal@704 135 context_object_name = 'photos'
bgneal@704 136 paginate_by = 50
bgneal@704 137 allow_empty = True
bgneal@704 138
bgneal@704 139 def get_queryset(self):
bgneal@704 140 self.gallery_owner = get_object_or_404(get_user_model(),
bgneal@704 141 username=self.kwargs['username'])
bgneal@704 142 return Photo.objects.filter(user=self.gallery_owner).order_by('-upload_date')
bgneal@704 143
bgneal@704 144 def get_context_data(self, **kwargs):
bgneal@704 145 context = super(GalleryView, self).get_context_data(**kwargs)
bgneal@704 146 context['gallery_owner'] = self.gallery_owner
bgneal@704 147 return context
bgneal@704 148
bgneal@704 149 @method_decorator(login_required)
bgneal@704 150 def dispatch(self, *args, **kwargs):
bgneal@704 151 return super(GalleryView, self).dispatch(*args, **kwargs)
bgneal@710 152
bgneal@710 153
bgneal@710 154 @login_required
bgneal@710 155 @require_POST
bgneal@710 156 def delete(request):
bgneal@718 157 """A view function to allow a user to delete their own photos."""
bgneal@718 158
bgneal@718 159 ret_view, username = 'user_photos-gallery', request.user.username
bgneal@718 160
bgneal@718 161 if not settings.USER_PHOTOS_ENABLED:
bgneal@718 162 messages.error(request, "This function is disabled temporarily")
bgneal@718 163 return redirect(ret_view, username)
bgneal@718 164
bgneal@710 165 photo_ids = []
bgneal@710 166 for photo_id in request.POST.getlist('photo_id'):
bgneal@710 167 try:
bgneal@710 168 n = int(photo_id)
bgneal@710 169 except ValueError:
bgneal@710 170 continue
bgneal@710 171 photo_ids.append(n)
bgneal@710 172
bgneal@710 173 count = 0
bgneal@710 174 if photo_ids:
bgneal@710 175 qs = Photo.objects.filter(user=request.user, pk__in=photo_ids)
bgneal@718 176 count = len(qs)
bgneal@718 177 if count:
bgneal@718 178 delete_photos(qs)
bgneal@718 179 qs.delete()
bgneal@710 180
bgneal@718 181 msg = "{} photo{} deleted".format(count, '' if count == 1 else 's')
bgneal@718 182 messages.add_message(request,
bgneal@718 183 messages.SUCCESS if count > 0 else messages.WARNING,
bgneal@718 184 msg)
bgneal@710 185
bgneal@718 186 return redirect(ret_view, username)
bgneal@971 187
bgneal@971 188
bgneal@971 189 def hotlink_image(request):
bgneal@971 190 """This view is responsible for accepting an image URL from a user and
bgneal@971 191 converting it to a URL pointing into our S3 bucket if necessary.
bgneal@971 192
bgneal@971 193 We return a JSON object response to the client with the following name
bgneal@971 194 & value pairs:
bgneal@971 195 'error_msg': string error message if an error occurred
bgneal@971 196 'url': the image URL as a string if success
bgneal@971 197 """
bgneal@971 198 ret = {'error_msg': '', 'url': ''}
bgneal@971 199 status_code = 400
bgneal@971 200
bgneal@971 201 if not request.user.is_authenticated():
bgneal@971 202 ret['error_msg'] = 'Please login to use this service'
bgneal@972 203 return JsonResponse(ret, status=403)
bgneal@971 204 if not request.is_ajax() or request.method != 'POST':
bgneal@971 205 ret['error_msg'] = 'This method is not allowed'
bgneal@972 206 return JsonResponse(ret, status=405)
bgneal@971 207
bgneal@971 208 if settings.USER_PHOTOS_ENABLED:
bgneal@972 209 form = HotLinkImageForm(request.POST, user=request.user)
bgneal@971 210 if form.is_valid():
bgneal@971 211 try:
bgneal@971 212 ret['url'] = form.save()
bgneal@971 213 status_code = 200
bgneal@971 214 except Exception as ex:
bgneal@971 215 ret['error_msg'] = str(ex)
bgneal@971 216 status_code = 500
bgneal@971 217 else:
bgneal@971 218 # gather form error messages
bgneal@971 219 errors = []
bgneal@971 220 non_field_errors = form.non_field_errors().as_text()
bgneal@971 221 if non_field_errors:
bgneal@971 222 errors.append(non_field_errors)
bgneal@971 223 for field_errors in form.errors.values():
bgneal@971 224 errors.append(field_errors.as_text())
bgneal@971 225 ret['error_msg'] = '\n'.join(errors)
bgneal@971 226 else:
bgneal@971 227 ret['error_msg'] = 'Image linking is temporarily disabled'
bgneal@971 228 status_code = 403
bgneal@971 229
bgneal@971 230 return JsonResponse(ret, status=status_code)
bgneal@971 231