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)
|