Mercurial > public > sg101
diff user_photos/forms.py @ 971:4f265f61874b
Hotlink image form is functioning.
The user can now submit a URL via a form and the URL will be downloaded
and uploaded to a S3 bucket if it is an image.
Tests to follow.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Tue, 22 Sep 2015 20:23:50 -0500 |
parents | 51a2051588f5 |
children | 7138883966b3 |
line wrap: on
line diff
--- a/user_photos/forms.py Sun Sep 13 14:51:33 2015 -0500 +++ b/user_photos/forms.py Tue Sep 22 20:23:50 2015 -0500 @@ -2,13 +2,15 @@ import datetime import hashlib import os.path +import urlparse from django import forms from django.conf import settings +from core.download import download_file +from core.functions import TemporaryFile +from core.images.upload import upload from core.s3 import S3Bucket -from core.image_uploader import upload -from core.functions import TemporaryFile from core.services import get_redis_connection from user_photos.models import Photo @@ -29,6 +31,15 @@ return val > limit +def rate_limit_user(user): + """Shared function to rate limit user uploads.""" + key = 'user_photos:counts:' + user.username + limit = settings.USER_PHOTOS_RATE_LIMIT + if rate_limit(key, *limit): + raise forms.ValidationError("You've exceeded your upload quota. " + "Please try again later.") + + class UploadForm(forms.Form): image_file = forms.ImageField() @@ -38,14 +49,7 @@ def clean(self): cleaned_data = super(UploadForm, self).clean() - - # rate limit uploads - key = 'user_photos:counts:' + self.user.username - limit = settings.USER_PHOTOS_RATE_LIMIT - if rate_limit(key, *limit): - raise forms.ValidationError("You've exceeded your upload quota. " - "Please try again later.") - + rate_limit_user(self.user) return cleaned_data def save(self): @@ -113,3 +117,55 @@ for chunk in fp.chunks(): md5.update(chunk) return md5.hexdigest() + + +class HotLinkImageForm(forms.Form): + """Form for hot-linking images. If the supplied URL's host is on + a white-list, return it as-is. Otherwise attempt to download the image at + the given URL and upload it into our S3 storage. The URL to the new location + is returned. + """ + url = forms.URLField() + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop('user') + super(HotLinkImageForm, self).__init__(*args, **kwargs) + + def clean_url(self): + the_url = self.cleaned_data['url'] + self.url_parts = urlparse.urlsplit(the_url) + if self.url_parts.scheme not in ['http', 'https']: + raise forms.ValidationError("Invalid URL scheme") + return the_url + + def clean(self): + cleaned_data = super(HotLinkImageForm, self).clean() + rate_limit_user(self.user) + return cleaned_data + + def save(self): + import pdb; pdb.set_trace() + + url = self.url_parts.geturl() + if (self.url_parts.scheme == 'https' and + self.url_parts.hostname in settings.USER_IMAGES_SOURCES): + return url + + # Try to download the file + path = download_file(url) + + # Upload it to our S3 bucket + bucket = S3Bucket(access_key=settings.USER_PHOTOS_ACCESS_KEY, + secret_key=settings.USER_PHOTOS_SECRET_KEY, + base_url=settings.HOT_LINK_PHOTOS_BASE_URL, + bucket_name=settings.HOT_LINK_PHOTOS_BUCKET) + + now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + metadata = {'user': self.user.username, 'date': now} + + url, _ = upload(filename=path, + bucket=bucket, + metadata=metadata, + new_size=settings.USER_PHOTOS_MAX_SIZE) + + return url