Test coverage report: user_media.views

# user_media.views: 175 total statements, 100.0% covered

Generated: Wed 2013-11-27 14:17 CET

Source file: /home/tobi/Projects/django-user-media/src/user_media/views.py

Stats: 160 executed, 0 missed, 15 excluded, 182 ignored

1. `"""Views for the ``django-user-media`` app."""`
2. `from django.conf import settings`
3. `from django.contrib.auth.decorators import login_required`
4. `from django.contrib.contenttypes.models import ContentType`
5. `from django.db.models import ObjectDoesNotExist`
6. `from django.http import Http404, HttpResponse`
7. `from django.template import RequestContext`
8. `from django.template.loader import render_to_string`
9. `from django.utils.decorators import method_decorator`
10. `from django.utils.translation import ugettext_lazy as _`
11. `from django.views.generic import CreateView, DeleteView, FormView, UpdateView`
12. ``
13. `from django_libs.views_mixins import AjaxResponseMixin`
14. `from easy_thumbnails.files import get_thumbnailer`
15. `from simplejson import dumps`
16. ``
17. `from user_media.forms import UserMediaImageForm, UserMediaImageSingleUploadForm`
18. `from user_media.models import UserMediaImage`
19. ``
20. ``
21. `class UserMediaImageViewMixin(object):`
22. `"""`
23. `Mixin for views that deal with `UserMediaImage` objects.`
24. ``
25. `When using this mixin please make sure that you call `_add_next_and_user()``
26. `in your `dispatch()` method.`
27. ``
28. `"""`
29. `model = UserMediaImage`
30. ``
31. `def _add_next_and_user(self, request):`
32. `self.next = request.POST.get('next', '') or request.GET.get('next', '')`
33. `self.user = request.user`
34. ``
35. `def get_context_data(self, **kwargs):`
36. `"""`
37. `Adds `next` to the context.`
38. ``
39. `This makes sure that the `next` parameter doesn't get lost if the`
40. `form was submitted invalid.`
41. ``
42. `"""`
43. `ctx = super(UserMediaImageViewMixin, self).get_context_data(**kwargs)`
44. `ctx.update({`
45. `'action': self.action,`
46. `'next': self.next,`
47. `})`
48. `return ctx`
49. ``
50. `def get_success_url(self):`
51. `"""`
52. `Returns the success URL.`
53. ``
54. `This is either the given `next` URL parameter or the content object's`
55. ``get_absolute_url` method's return value.`
56. ``
57. `"""`
58. `if self.next:`
59. `return self.next`
60. `if self.object and self.object.content_object:`
61. `return self.object.content_object.get_absolute_url()`
62. `raise Exception(`
63. `'No content object given. Please provide ``next`` in your POST'`
64. `' data')`
65. ``
66. ``
67. `class CreateImageView(AjaxResponseMixin, UserMediaImageViewMixin, CreateView):`
68. `action = 'create'`
69. `form_class = UserMediaImageForm`
70. `ajax_template_prefix = 'partials/ajax_'`
71. ``
72. `@method_decorator(login_required)`
73. `def dispatch(self, request, *args, **kwargs):`
74. `"""Adds useful objects to the class and performs security checks."""`
75. `self._add_next_and_user(request)`
76. `self.content_object = None`
77. `self.content_type = None`
78. `self.object_id = kwargs.get('object_id', None)`
79. ``
80. `if kwargs.get('content_type'):`
81. `# Check if the user forged the URL and posted a non existant`
82. `# content type`
83. `try:`
84. `self.content_type = ContentType.objects.get(`
85. `model=kwargs.get('content_type'))`
86. `except ContentType.DoesNotExist:`
87. `raise Http404`
88. ``
89. `if self.content_type:`
90. `# Check if the user forged the URL and tries to append the image to`
91. `# an object that does not exist`
92. `try:`
93. `self.content_object = \`
94. `self.content_type.get_object_for_this_type(`
95. `pk=self.object_id)`
96. `except ObjectDoesNotExist:`
97. `raise Http404`
98. ``
99. `if self.content_object and hasattr(self.content_object, 'user'):`
100. `# Check if the user forged the URL and tries to append the image to`
101. `# an object that does not belong to him`
102. `if not self.content_object.user == self.user:`
103. `raise Http404`
104. ``
105. `return super(CreateImageView, self).dispatch(request, *args, **kwargs)`
106. ``
107. `def get_context_data(self, **kwargs):`
108. `ctx = super(CreateImageView, self).get_context_data(**kwargs)`
109. `ctx.update({`
110. `'content_type': self.content_type,`
111. `'object_id': self.object_id,`
112. `})`
113. `return ctx`
114. ``
115. `def get_form_kwargs(self):`
116. `kwargs = super(CreateImageView, self).get_form_kwargs()`
117. `kwargs.update({`
118. `'user': self.user,`
119. `'content_type': self.content_type,`
120. `'object_id': self.object_id,`
121. `})`
122. `return kwargs`
123. ``
124. ``
125. `class DeleteImageView(AjaxResponseMixin, UserMediaImageViewMixin, DeleteView):`
126. `"""Deletes an `UserMediaImage` object."""`
127. `action = 'delete'`
128. `model = UserMediaImage`
129. `ajax_template_prefix = 'partials/ajax_'`
130. ``
131. `@method_decorator(login_required)`
132. `def dispatch(self, request, *args, **kwargs):`
133. `"""Adds useful objects to the class."""`
134. `self._add_next_and_user(request)`
135. `return super(DeleteImageView, self).dispatch(request, *args, **kwargs)`
136. ``
137. `def get_context_data(self, **kwargs):`
138. `ctx = super(DeleteImageView, self).get_context_data(**kwargs)`
139. `ctx.update({`
140. `'image_pk': self.object.pk,`
141. `})`
142. `return ctx`
143. ``
144. `def get_queryset(self):`
145. `"""`
146. `Making sure that a user can only delete his own images.`
147. ``
148. `Even when he forges the request URL.`
149. ``
150. `"""`
151. `queryset = super(DeleteImageView, self).get_queryset()`
152. `queryset = queryset.filter(user=self.user)`
153. `return queryset`
154. ``
155. ``
156. `class UpdateImageView(AjaxResponseMixin, UserMediaImageViewMixin, UpdateView):`
157. `"""Updates an existing `UserMediaImage` object."""`
158. `action = 'update'`
159. `model = UserMediaImage`
160. `form_class = UserMediaImageForm`
161. `ajax_template_prefix = 'partials/ajax_'`
162. ``
163. `@method_decorator(login_required)`
164. `def dispatch(self, request, *args, **kwargs):`
165. `"""Adds useful objects to the class."""`
166. `self._add_next_and_user(request)`
167. `return super(UpdateImageView, self).dispatch(request, *args, **kwargs)`
168. ``
169. `def get_context_data(self, **kwargs):`
170. `ctx = super(UpdateImageView, self).get_context_data(**kwargs)`
171. `ctx.update({`
172. `'content_type': self.object.content_type,`
173. `'object_id': self.object.object_id,`
174. `'image_pk': self.object.pk,`
175. `})`
176. `return ctx`
177. ``
178. `def get_form_kwargs(self):`
179. `kwargs = super(UpdateImageView, self).get_form_kwargs()`
180. `kwargs.update({`
181. `'user': self.user,`
182. `'content_type': self.object.content_type,`
183. `'object_id': self.object.object_id,`
184. `})`
185. `return kwargs`
186. ``
187. `def get_queryset(self):`
188. `"""`
189. `Making sure that a user can only edit his own images.`
190. ``
191. `Even when he forges the request URL.`
192. ``
193. `"""`
194. `queryset = super(UpdateImageView, self).get_queryset()`
195. `queryset = queryset.filter(user=self.user)`
196. `return queryset`
197. ``
198. ``
199. `class AJAXMultipleImageUploadView(CreateView):`
200. `"""Ajax view to handle the multiple image upload."""`
201. `model = UserMediaImage`
202. `form_class = UserMediaImageForm`
203. ``
204. `@method_decorator(login_required)`
205. `def dispatch(self, request, *args, **kwargs):`
206. `self.obj_id = kwargs.get('obj_id', None)`
207. `self.user = request.user`
208. ``
209. `if not request.is_ajax():`
210. `# Since we use a jquery modal and a jquery upload we should only`
211. `# allow ajax calls`
212. `raise Http404`
213. ``
214. `# Check if the user posted a non existant content type`
215. `try:`
216. `self.c_type = ContentType.objects.get(model=kwargs.get('c_type'))`
217. `except ContentType.DoesNotExist:`
218. `raise Http404`
219. ``
220. `# Check if the content object exists`
221. `try:`
222. `self.content_object = self.c_type.get_object_for_this_type(`
223. `pk=self.obj_id)`
224. `except ObjectDoesNotExist:`
225. `raise Http404`
226. ``
227. `# Check for permissions`
228. `if (not hasattr(self.content_object, 'user')`
229. `or not self.content_object.user == self.user):`
230. `raise Http404`
231. `return super(AJAXMultipleImageUploadView, self).dispatch(`
232. `request, *args, **kwargs)`
233. ``
234. `def get_form_kwargs(self):`
235. `kwargs = super(AJAXMultipleImageUploadView, self).get_form_kwargs()`
236. `# Prepare context for UserMediaImage form`
237. `kwargs.update({`
238. `'user': self.user,`
239. `'content_type': self.c_type,`
240. `'object_id': self.obj_id,`
241. `})`
242. `return kwargs`
243. ``
244. `def form_valid(self, form):`
245. `# Check if maximum amount of pictures has been reached`
246. `try:`
247. `max_pictures = int(self.request.POST.get('maximum'))`
248. `except (TypeError, ValueError):`
249. `max_pictures = getattr(settings, 'USER_MEDIA_UPLOAD_MAXIMUM', 3)`
250. `stored_images = self.user.usermediaimage_set.filter(`
251. `object_id=self.obj_id, content_type=self.c_type)`
252. `if stored_images.count() >= max_pictures:`
253. `return HttpResponse(_('Maximum amount limit exceeded.'))`
254. ``
255. `# Save the UserMediaImage`
256. `self.object = form.save()`
257. `f = self.request.FILES.get('image')`
258. ``
259. `# Generate and get the thumbnail of the uploaded image`
260. `thumbnailer = get_thumbnailer(self.object.image.name)`
261. `thumb = thumbnailer.get_thumbnail({'crop': True, 'upscale': True,`
262. `'size': (50, 50)})`
263. ``
264. `# Prepare context for the list item html`
265. `context_data = {`
266. `'image': self.object,`
267. `'mode': 'multiple',`
268. `}`
269. `context = RequestContext(self.request, context_data)`
270. ``
271. `# Prepare the json response`
272. `data = {'files': [{`
273. `'name': f.name,`
274. `'url': self.object.image.url,`
275. `'thumbnail_url': thumb.url,`
276. `'list_item_html': render_to_string(`
277. `'user_media/partials/image.html', context),`
278. `}]}`
279. `response = HttpResponse(dumps(data), mimetype='application/json')`
280. `response['Content-Disposition'] = 'inline; filename=files.json'`
281. `return response`
282. ``
283. ``
284. `class AJAXSingleImageUploadView(FormView):`
285. `"""Ajax view to handle the single image upload."""`
286. `form_class = UserMediaImageSingleUploadForm`
287. `template_name = 'user_media/partials/image.html'`
288. ``
289. `@method_decorator(login_required)`
290. `def dispatch(self, request, *args, **kwargs):`
291. `if not request.is_ajax() or not request.method == 'POST':`
292. `raise Http404`
293. `self.user = request.user`
294. `# Check if the user posted a non existant content type`
295. `try:`
296. `self.c_type = ContentType.objects.get(model=kwargs.get('c_type'))`
297. `except ContentType.DoesNotExist:`
298. `raise Http404`
299. ``
300. `# Check if the content object exists`
301. `try:`
302. `self.content_object = self.c_type.get_object_for_this_type(`
303. `pk=kwargs.get('obj_id'))`
304. `except ObjectDoesNotExist:`
305. `raise Http404`
306. ``
307. `# Check if content_object has the requested image field`
308. `if hasattr(self.content_object, kwargs.get('field')):`
309. `self.field_name = kwargs.get('field')`
310. `self.image_field = getattr(self.content_object, self.field_name)`
311. `else:`
312. `raise Http404`
313. ``
314. `# Check for permissions`
315. `if (not hasattr(self.content_object, 'user')`
316. `or not self.content_object.user == self.user):`
317. `raise Http404`
318. `return super(AJAXSingleImageUploadView, self).dispatch(`
319. `request, *args, **kwargs)`
320. ``
321. `def get_form_kwargs(self):`
322. `kwargs = super(AJAXSingleImageUploadView, self).get_form_kwargs()`
323. `kwargs.update({`
324. `'instance': self.content_object,`
325. `'image_field': self.field_name,`
326. `})`
327. `return kwargs`
328. ``
329. `def form_valid(self, form):`
330. `# Save the image`
331. `self.content_object = form.save()`
332. `f = self.request.FILES.get(self.field_name)`
333. `image = getattr(self.content_object, self.field_name)`
334. ``
335. `# Generate and get the thumbnail of the uploaded image`
336. `thumbnailer = get_thumbnailer(image.name)`
337. `thumb = thumbnailer.get_thumbnail({'crop': True, 'upscale': True,`
338. `'size': (50, 50)})`
339. ``
340. `# Prepare context for the list item html`
341. `context_data = {`
342. `'image': image,`
343. `'mode': 'single',`
344. `'size': self.request.POST.get('size') or '150x150',`
345. `}`
346. `context = RequestContext(self.request, context_data)`
347. ``
348. `# Prepare the json response`
349. `data = {'files': [{`
350. `'name': f.name,`
351. `'url': image.url,`
352. `'thumbnail_url': thumb.url,`
353. `'list_item_html': render_to_string(self.template_name, context),`
354. `}]}`
355. `response = HttpResponse(dumps(data), mimetype='application/json')`
356. `response['Content-Disposition'] = 'inline; filename=files.json'`
357. `return response`