bgneal@695: """Forms for the user_photos application.""" bgneal@700: import datetime bgneal@700: bgneal@695: from django import forms bgneal@697: from django.conf import settings bgneal@695: bgneal@700: from core.s3 import S3Bucket bgneal@700: from core.image_uploader import upload bgneal@701: from core.services import get_redis_connection bgneal@696: from user_photos.models import Photo bgneal@696: bgneal@695: bgneal@701: def rate_limit(key, limit, seconds): bgneal@701: """Use Redis to do a rate limit check. Returns True if the limit is violated bgneal@701: and False otherwise. bgneal@701: bgneal@701: key - the key to check in Redis bgneal@701: limit - the rate limit maximum value bgneal@701: seconds - the rate limit period in seconds bgneal@701: bgneal@701: """ bgneal@701: conn = get_redis_connection() bgneal@701: val = conn.incr(key) bgneal@701: if val == 1: bgneal@701: conn.expire(key, seconds) bgneal@701: return val > limit bgneal@701: bgneal@701: bgneal@695: class UploadForm(forms.Form): bgneal@695: image_file = forms.ImageField() bgneal@696: bgneal@696: def __init__(self, *args, **kwargs): bgneal@696: self.user = kwargs.pop('user') bgneal@696: super(UploadForm, self).__init__(*args, **kwargs) bgneal@696: bgneal@701: def clean(self): bgneal@701: cleaned_data = super(UploadForm, self).clean() bgneal@701: bgneal@701: # rate limit uploads bgneal@701: key = 'user_photos:counts:' + self.user.username bgneal@701: limit = settings.USER_PHOTOS_RATE_LIMIT bgneal@701: if rate_limit(key, *limit): bgneal@701: raise forms.ValidationError("You've exceeded your upload quota. " bgneal@701: "Please try again later.") bgneal@701: bgneal@701: return cleaned_data bgneal@701: bgneal@696: def save(self): bgneal@696: """Processes the image and creates a new Photo object, which is saved to bgneal@696: the database. The new Photo instance is returned. bgneal@696: bgneal@696: This function should only be called if is_valid() returns True. bgneal@696: bgneal@696: """ bgneal@700: bucket = S3Bucket(access_key=settings.USER_PHOTOS_ACCESS_KEY, bgneal@700: secret_key=settings.USER_PHOTOS_SECRET_KEY, bgneal@700: base_url=settings.USER_PHOTOS_BASE_URL, bgneal@700: bucket_name=settings.USER_PHOTOS_BUCKET) bgneal@700: bgneal@700: now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') bgneal@700: metadata = {'user': self.user.username, 'date': now} bgneal@700: bgneal@700: url, thumb_url = upload(fp=self.cleaned_data['image_file'], bgneal@700: bucket=bucket, bgneal@700: metadata=metadata, bgneal@700: new_size=settings.USER_PHOTOS_MAX_SIZE, bgneal@700: thumb_size=settings.USER_PHOTOS_THUMB_SIZE) bgneal@700: bgneal@696: photo = Photo(user=self.user, url=url, thumb_url=thumb_url) bgneal@696: photo.save() bgneal@696: return photo