# HG changeset patch # User Brian Neal # Date 1378605046 18000 # Node ID 2d35e5f97a992aa0462799421e06f8dcb00332d7 # Parent d84aaf2391825b2e653838f965db809e4e1eac05 In process work for #50. Started a user_photos application. Initial commit with model, form, and view. The view doesn't save the photo yet. diff -r d84aaf239182 -r 2d35e5f97a99 potd/models.py --- a/potd/models.py Fri Sep 06 21:50:53 2013 -0500 +++ b/potd/models.py Sat Sep 07 20:50:46 2013 -0500 @@ -32,7 +32,7 @@ thumb = models.ImageField(upload_to='potd/%Y/%m/%d/thumbs', blank=True, null=True) caption = models.CharField(max_length=128) description = models.TextField() - user = models.ForeignKey(User) + user = models.ForeignKey(User, related_name='potd_set') date_added = models.DateField() potd_count = models.IntegerField(default=0) diff -r d84aaf239182 -r 2d35e5f97a99 sg101/settings/base.py --- a/sg101/settings/base.py Fri Sep 06 21:50:53 2013 -0500 +++ b/sg101/settings/base.py Sat Sep 07 20:50:46 2013 -0500 @@ -141,6 +141,7 @@ 'potd', 'shoutbox', 'smiley', + 'user_photos', 'weblinks', 'wiki', 'ygroup', @@ -290,6 +291,11 @@ WIKI_COOKIE_AGE = SESSION_COOKIE_AGE WIKI_REDIS_SET = 'wiki_cookie_keys' +# User photo upload settings +USER_PHOTO_ENABLED = True +USER_PHOTO_ACCESS_KEY = SECRETS['AWS_ACCESS_KEY'] +USER_PHOTO_SECRET_KEY = SECRETS['AWS_SECRET_KEY'] + ####################################################################### # Asynchronous settings (queues, queued_search, redis, celery, etc) ####################################################################### diff -r d84aaf239182 -r 2d35e5f97a99 sg101/templates/user_photos/upload_form.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sg101/templates/user_photos/upload_form.html Sat Sep 07 20:50:46 2013 -0500 @@ -0,0 +1,24 @@ +{% extends 'base.html' %} +{% block title %}User Photo Upload{% endblock %} +{% block content %} +

User Photo Upload

+{% if enabled %} +

+ This form will allow you to upload a photo from your computer or device, + suitable for displaying in forum or comment posts. We will automatically + resize your photo for you. When the process is complete we will return an + image code you can paste into your post to display your photo. +

+
{% csrf_token %} +
+ Upload a photo: + {{ form.as_p }} +

+
+
+{% else %} +

+ We're sorry but uploading is currently disabled. Please try back later. +

+{% endif %} +{% endblock %} diff -r d84aaf239182 -r 2d35e5f97a99 sg101/urls.py --- a/sg101/urls.py Fri Sep 06 21:50:53 2013 -0500 +++ b/sg101/urls.py Sat Sep 07 20:50:46 2013 -0500 @@ -84,6 +84,7 @@ (r'^profile/', include('bio.urls')), (r'^shout/', include('shoutbox.urls')), (r'^smiley/', include('smiley.urls')), + (r'^user_photos/', include('user_photos.urls')), (r'^ygroup/', include('ygroup.urls')), ) diff -r d84aaf239182 -r 2d35e5f97a99 user_photos/admin.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_photos/admin.py Sat Sep 07 20:50:46 2013 -0500 @@ -0,0 +1,13 @@ +"""Admin definitions for the user_photos application.""" +from django.contrib import admin + +from user_photos.models import Photo + + +class PhotoAdmin(admin.ModelAdmin): + date_hierarchy = 'upload_date' + ordering = ['-upload_date'] + raw_id_fields = ['user'] + search_fields = ['user__username', 'user__email'] + +admin.site.register(Photo, PhotoAdmin) diff -r d84aaf239182 -r 2d35e5f97a99 user_photos/forms.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_photos/forms.py Sat Sep 07 20:50:46 2013 -0500 @@ -0,0 +1,6 @@ +"""Forms for the user_photos application.""" +from django import forms + + +class UploadForm(forms.Form): + image_file = forms.ImageField() diff -r d84aaf239182 -r 2d35e5f97a99 user_photos/models.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_photos/models.py Sat Sep 07 20:50:46 2013 -0500 @@ -0,0 +1,28 @@ +"""Models for the user_photos application.""" + +import datetime + +from django.db import models +from django.conf import settings + + +class Photo(models.Model): + """This model represents data about a user uploaded photo.""" + user = models.ForeignKey(settings.AUTH_USER_MODEL, + related_name='uploaded_photos') + upload_date = models.DateTimeField() + url = models.URLField(max_length=200) + thumb_url = models.URLField(max_length=200, blank=True) + + def __unicode__(self): + return u'Photo by {} on {}'.format(self.user.username, + self.upload_date.strftime('%Y-%m-%d %H:%M:%S')) + + def get_absolute_url(self): + return self.url + + def save(self, *args, **kwargs): + if not self.pk and not self.upload_date: + self.upload_date = datetime.datetime.now() + super(Photo, self).save(*args, **kwargs) + diff -r d84aaf239182 -r 2d35e5f97a99 user_photos/tests.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_photos/tests.py Sat Sep 07 20:50:46 2013 -0500 @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff -r d84aaf239182 -r 2d35e5f97a99 user_photos/urls.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_photos/urls.py Sat Sep 07 20:50:46 2013 -0500 @@ -0,0 +1,6 @@ +"""URLs for the user_photos application.""" +from django.conf.urls import patterns, url + +urlpatterns = patterns('user_photos.views', + url(r'^upload/$', 'upload', name='user_photos-upload'), +) diff -r d84aaf239182 -r 2d35e5f97a99 user_photos/views.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_photos/views.py Sat Sep 07 20:50:46 2013 -0500 @@ -0,0 +1,38 @@ +"""Views for the user_photos application.""" +from django.conf import settings +from django.contrib.auth.decorators import login_required +from django.shortcuts import render + +from user_photos.forms import UploadForm + + +@login_required +def upload(request): + """This view function receives an uploaded image file from a user. + The photo will be resized if necessary and a thumbnail image will be + created. The image and thumbnail will then be uploaded to the Amazon + S3 service for storage. + + TODO: rate limiting + pass off the processing to a celery task + ajax version of this view + + """ + form = None + uploads_enabled = settings.USER_PHOTO_ENABLED + + if uploads_enabled: + if request.method == 'POST': + form = UploadForm(request.POST, request.FILES) + if form.is_valid(): + #TODO + print "**************", request.FILES['image_file'] + pass + else: + form = UploadForm() + + return render(request, 'user_photos/upload_form.html', { + 'enabled': uploads_enabled, + 'form': form, + }, + status=200 if uploads_enabled else 503)