comparison user_photos/forms.py @ 701:094492e66eb9

Implement rate limiting on user photo uploads.
author Brian Neal <bgneal@gmail.com>
date Sat, 14 Sep 2013 17:23:13 -0500
parents e888d627928f
children b6e98717690b
comparison
equal deleted inserted replaced
700:e888d627928f 701:094492e66eb9
4 from django import forms 4 from django import forms
5 from django.conf import settings 5 from django.conf import settings
6 6
7 from core.s3 import S3Bucket 7 from core.s3 import S3Bucket
8 from core.image_uploader import upload 8 from core.image_uploader import upload
9 from core.services import get_redis_connection
9 from user_photos.models import Photo 10 from user_photos.models import Photo
11
12
13 def rate_limit(key, limit, seconds):
14 """Use Redis to do a rate limit check. Returns True if the limit is violated
15 and False otherwise.
16
17 key - the key to check in Redis
18 limit - the rate limit maximum value
19 seconds - the rate limit period in seconds
20
21 """
22 conn = get_redis_connection()
23 val = conn.incr(key)
24 if val == 1:
25 conn.expire(key, seconds)
26 return val > limit
10 27
11 28
12 class UploadForm(forms.Form): 29 class UploadForm(forms.Form):
13 image_file = forms.ImageField() 30 image_file = forms.ImageField()
14 31
15 def __init__(self, *args, **kwargs): 32 def __init__(self, *args, **kwargs):
16 self.user = kwargs.pop('user') 33 self.user = kwargs.pop('user')
17 super(UploadForm, self).__init__(*args, **kwargs) 34 super(UploadForm, self).__init__(*args, **kwargs)
35
36 def clean(self):
37 cleaned_data = super(UploadForm, self).clean()
38
39 # rate limit uploads
40 key = 'user_photos:counts:' + self.user.username
41 limit = settings.USER_PHOTOS_RATE_LIMIT
42 if rate_limit(key, *limit):
43 raise forms.ValidationError("You've exceeded your upload quota. "
44 "Please try again later.")
45
46 return cleaned_data
18 47
19 def save(self): 48 def save(self):
20 """Processes the image and creates a new Photo object, which is saved to 49 """Processes the image and creates a new Photo object, which is saved to
21 the database. The new Photo instance is returned. 50 the database. The new Photo instance is returned.
22 51