Mercurial > public > sg101
comparison user_photos/forms.py @ 749:b6e98717690b
For #59, add user photo de-duplication for uploads.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Mon, 30 Dec 2013 15:05:43 -0600 |
parents | 094492e66eb9 |
children | 51a2051588f5 |
comparison
equal
deleted
inserted
replaced
748:e5869846d0dc | 749:b6e98717690b |
---|---|
1 """Forms for the user_photos application.""" | 1 """Forms for the user_photos application.""" |
2 import datetime | 2 import datetime |
3 import hashlib | |
3 | 4 |
4 from django import forms | 5 from django import forms |
5 from django.conf import settings | 6 from django.conf import settings |
6 | 7 |
7 from core.s3 import S3Bucket | 8 from core.s3 import S3Bucket |
47 | 48 |
48 def save(self): | 49 def save(self): |
49 """Processes the image and creates a new Photo object, which is saved to | 50 """Processes the image and creates a new Photo object, which is saved to |
50 the database. The new Photo instance is returned. | 51 the database. The new Photo instance is returned. |
51 | 52 |
53 Note that we do de-duplication. A signature is computed for the photo. | |
54 If the user has already uploaded a file with the same signature, that | |
55 photo object is returned instead. | |
56 | |
52 This function should only be called if is_valid() returns True. | 57 This function should only be called if is_valid() returns True. |
53 | 58 |
54 """ | 59 """ |
60 # Check for duplicate uploads from this user | |
61 signature = self._signature() | |
62 try: | |
63 return Photo.objects.get(user=self.user, signature=signature) | |
64 except Photo.DoesNotExist: | |
65 pass | |
66 | |
67 # This must not be a duplicate, proceed with upload to S3 | |
55 bucket = S3Bucket(access_key=settings.USER_PHOTOS_ACCESS_KEY, | 68 bucket = S3Bucket(access_key=settings.USER_PHOTOS_ACCESS_KEY, |
56 secret_key=settings.USER_PHOTOS_SECRET_KEY, | 69 secret_key=settings.USER_PHOTOS_SECRET_KEY, |
57 base_url=settings.USER_PHOTOS_BASE_URL, | 70 base_url=settings.USER_PHOTOS_BASE_URL, |
58 bucket_name=settings.USER_PHOTOS_BUCKET) | 71 bucket_name=settings.USER_PHOTOS_BUCKET) |
59 | 72 |
64 bucket=bucket, | 77 bucket=bucket, |
65 metadata=metadata, | 78 metadata=metadata, |
66 new_size=settings.USER_PHOTOS_MAX_SIZE, | 79 new_size=settings.USER_PHOTOS_MAX_SIZE, |
67 thumb_size=settings.USER_PHOTOS_THUMB_SIZE) | 80 thumb_size=settings.USER_PHOTOS_THUMB_SIZE) |
68 | 81 |
69 photo = Photo(user=self.user, url=url, thumb_url=thumb_url) | 82 photo = Photo(user=self.user, url=url, thumb_url=thumb_url, |
83 signature=signature) | |
70 photo.save() | 84 photo.save() |
71 return photo | 85 return photo |
86 | |
87 def _signature(self): | |
88 """Calculates and returns a signature for the image file as a hex digest | |
89 string. | |
90 | |
91 This function should only be called if is_valid() is True. | |
92 | |
93 """ | |
94 fp = self.cleaned_data['image_file'] | |
95 md5 = hashlib.md5() | |
96 for chunk in fp.chunks(): | |
97 md5.update(chunk) | |
98 return md5.hexdigest() |