annotate user_photos/views.py @ 861:e4f8d87c3d30

Configure Markdown logger to reduce noise in logs. Markdown is logging at the INFO level whenever it loads an extension. This looks like it has been fixed in master at GitHub. But until then we will explicitly configure the MARKDOWN logger to log at WARNING or higher.
author Brian Neal <bgneal@gmail.com>
date Mon, 01 Dec 2014 18:36:27 -0600
parents 8b027e7a7977
children 4f265f61874b
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@722 8 HttpResponseNotAllowed)
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@695 15 from user_photos.forms import 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)