# HG changeset patch # User Brian Neal # Date 1424221146 21600 # Node ID 3aecf9058130496b62910181b03954f95d56a115 # Parent ae146e30d588a06301f9a2d5665797524daf28a3# Parent 79a71b9d0a2a60fa6c5dece620766a708cb9a526 Merge with upstream. diff -r ae146e30d588 -r 3aecf9058130 accounts/forms.py --- a/accounts/forms.py Tue Feb 10 20:36:34 2015 -0600 +++ b/accounts/forms.py Tue Feb 17 18:59:06 2015 -0600 @@ -183,7 +183,7 @@ # Send the confirmation email site = Site.objects.get_current() - admin_email = settings.ADMINS[0][1] + admin_email = settings.DEFAULT_FROM_EMAIL activation_link = 'http://%s%s' % (site.domain, reverse('accounts.views.register_confirm', kwargs = {'username' : pending_user.username, 'key' : pending_user.key})) @@ -199,8 +199,7 @@ }) subject = 'Registration Confirmation for ' + site.name - send_mail(subject, msg, admin_email, [self.cleaned_data['email']], - defer=False) + send_mail(subject, msg, admin_email, [self.cleaned_data['email']]) logger.info('Accounts/registration conf. email sent to %s for user %s; IP = %s', self.cleaned_data['email'], pending_user.username, self.ip) @@ -226,7 +225,7 @@ return site = Site.objects.get_current() - admin_email = settings.ADMINS[0][1] + admin_email = settings.DEFAULT_FROM_EMAIL subject = 'Forgotten username for %s' % site.name msg = render_to_string('accounts/forgot_user_email.txt', { @@ -234,7 +233,7 @@ 'site': site, 'admin_email': admin_email, }) - send_mail(subject, msg, admin_email, [email], defer=False) + send_mail(subject, msg, admin_email, [email]) logger.info('Forgotten username email sent to {} <{}>'.format( user.username, email)) diff -r ae146e30d588 -r 3aecf9058130 contact/forms.py --- a/contact/forms.py Tue Feb 10 20:36:34 2015 -0600 +++ b/contact/forms.py Tue Feb 17 18:59:06 2015 -0600 @@ -38,8 +38,11 @@ 'site_name': site.name, 'user_name': self.cleaned_data['name'], 'user_email': self.cleaned_data['email'], + 'subject': self.cleaned_data['subject'], 'message': self.cleaned_data['message'], }) subject = site.name + ' Feedback: ' + self.cleaned_data['subject'] - send_mail(subject, msg, self.cleaned_data['email'], self.recipient_list) + from_email = settings.GPP_NO_REPLY_EMAIL + '@' + site.domain + send_mail(subject, msg, from_email, self.recipient_list, + reply_to=self.cleaned_data['email']) diff -r ae146e30d588 -r 3aecf9058130 contact/tests/test_views.py --- a/contact/tests/test_views.py Tue Feb 10 20:36:34 2015 -0600 +++ b/contact/tests/test_views.py Tue Feb 17 18:59:06 2015 -0600 @@ -27,7 +27,8 @@ self.assertEqual(len(mail.outbox), 1) email = mail.outbox[0] self.assertEqual(len(email.recipients()), 1) - self.assertEqual(email.from_email, post_data['email']) + self.assertEqual(email.extra_headers['Reply-To'], post_data['email']) + self.assertEqual(email.from_email, 'no_reply@example.com') self.assertEqual(email.recipients()[0], 'admin@surfguitar101.com') self.assertTrue(post_data['subject'] in email.subject) msg = email.message().as_string() diff -r ae146e30d588 -r 3aecf9058130 core/functions.py --- a/core/functions.py Tue Feb 10 20:36:34 2015 -0600 +++ b/core/functions.py Tue Feb 17 18:59:06 2015 -0600 @@ -23,7 +23,7 @@ os.remove(path) -def send_mail(subject, message, from_email, recipient_list, defer=True, **kwargs): +def send_mail(subject, message, from_email, recipient_list, reply_to=None, defer=True): """ The main send email function. Use this function to send email from the site. All applications should use this function instead of calling @@ -39,15 +39,23 @@ logging.warning("Empty recipient_list in send_mail") return - logging.debug('EMAIL:\nFrom: %s\nTo: %s\nSubject: %s\nMessage:\n%s', - from_email, str(recipient_list), subject, message) + logging.debug('EMAIL:\nFrom: %s\nTo: %s\nReply-To: %s\nSubject: %s\nMessage:\n%s', + from_email, str(recipient_list), reply_to, subject, message) + + headers = {'Reply-To': reply_to} if reply_to else None + msg_kwargs = { + 'subject': subject, + 'body': message, + 'from_email': from_email, + 'to': recipient_list, + 'headers': headers, + } if defer: - core.tasks.send_mail.delay(subject, message, from_email, recipient_list, - **kwargs) + core.tasks.send_mail.delay(**msg_kwargs) else: - django.core.mail.send_mail(subject, message, from_email, recipient_list, - **kwargs) + msg = django.core.mail.EmailMessage(**msg_kwargs) + msg.send() def email_admins(subject, message): diff -r ae146e30d588 -r 3aecf9058130 core/image.py --- a/core/image.py Tue Feb 10 20:36:34 2015 -0600 +++ b/core/image.py Tue Feb 17 18:59:06 2015 -0600 @@ -102,7 +102,13 @@ """ if hasattr(im, '_getexif'): - exif = im._getexif() + try: + exif = im._getexif() + except IndexError: + # Work around issue seen in Pillow + # https://github.com/python-pillow/Pillow/issues/518 + exif = None + if exif and ORIENT_TAG in exif: orientation = exif[ORIENT_TAG] func = ORIENT_FUNCS.get(orientation) diff -r ae146e30d588 -r 3aecf9058130 core/tasks.py --- a/core/tasks.py Tue Feb 10 20:36:34 2015 -0600 +++ b/core/tasks.py Tue Feb 17 18:59:06 2015 -0600 @@ -4,20 +4,22 @@ """ from __future__ import absolute_import +import django.core.mail from celery import shared_task -import django.core.mail import core.whos_online @shared_task -def send_mail(subject, message, from_email, recipient_list, **kwargs): +def send_mail(**kwargs): """ A task to send mail via Django. + kwargs must be a dict of keyword arguments for an EmailMessage. + """ - django.core.mail.send_mail(subject, message, from_email, recipient_list, - **kwargs) + msg = django.core.mail.EmailMessage(**kwargs) + msg.send() @shared_task diff -r ae146e30d588 -r 3aecf9058130 messages/views.py --- a/messages/views.py Tue Feb 10 20:36:34 2015 -0600 +++ b/messages/views.py Tue Feb 17 18:59:06 2015 -0600 @@ -399,7 +399,7 @@ 'msgs': msgs, 'admin_email': admin_email, }) - send_mail(subject, msg_body, from_email, [email_addr], defer=False) + send_mail(subject, msg_body, from_email, [email_addr]) msg = '{} message{} sent to email.'.format(count, '' if count == 1 else 's') if count > 0: diff -r ae146e30d588 -r 3aecf9058130 news/views.py --- a/news/views.py Tue Feb 10 20:36:34 2015 -0600 +++ b/news/views.py Tue Feb 17 18:59:06 2015 -0600 @@ -3,6 +3,7 @@ """ import datetime +from django.conf import settings from django.shortcuts import render_to_response from django.template import RequestContext from django.template.loader import render_to_string @@ -201,11 +202,11 @@ if request.method == 'POST': send_form = SendStoryForm(request.POST) if send_form.is_valid(): + site = Site.objects.get_current() to_name = send_form.name() to_email = send_form.email() from_name = get_full_name(request.user) - from_email = request.user.email - site = Site.objects.get_current() + from_email = settings.GPP_NO_REPLY_EMAIL + '@' + site.domain msg = render_to_string('news/send_story_email.txt', { @@ -218,7 +219,7 @@ }) subject = 'Interesting Story at ' + site.name - send_mail(subject, msg, from_email, [to_email]) + send_mail(subject, msg, from_email, [to_email], reply_to=request.user.email) return HttpResponseRedirect(reverse('news.views.email_thanks')) else: send_form = SendStoryForm() diff -r ae146e30d588 -r 3aecf9058130 requirements.txt --- a/requirements.txt Tue Feb 10 20:36:34 2015 -0600 +++ b/requirements.txt Tue Feb 17 18:59:06 2015 -0600 @@ -1,32 +1,29 @@ Django==1.6.6 Markdown==2.5.1 MySQL-python==1.2.4 --e git+https://github.com/gremmie/django-elsewhere.git@1203bd331aba4c5d4e702cc4e64d807310f2b591#egg=django_elsewhere-dev +-e git+https://github.com/gremmie/django-elsewhere.git@1203bd331aba4c5d4e702cc4e64d807310f2b591#egg=django_elsewhere-master django-haystack==2.1.0 django-tagging==0.3.1 gdata==2.0.15 html5lib==1.0b3 bleach==1.4 -pytz==2013b +pytz==2013b0 queued-search==2.1.0 -hg+https://bgneal@bitbucket.org/bgneal/queues@862e884#egg=queues +-e hg+https://bgneal@bitbucket.org/bgneal/queues@862e8846f7e5f5a0df7f08bfe4b4e5283acb4614#egg=queues-dev redis==2.7.2 repoze.timeago==0.5 --e git+https://github.com/notanumber/xapian-haystack.git@37add92bc43fe50bf165e91f370269c26272f1eb#egg=xapian_haystack-dev +-e git+https://github.com/notanumber/xapian-haystack.git@37add92bc43fe50bf165e91f370269c26272f1eb#egg=xapian_haystack-master anyjson==0.3.3 celery==3.1.7 django-picklefield==0.3.1 kombu==3.0.8 python-dateutil==1.5 python-memcached==1.48 -wsgiref==0.1.2 -python-ts3==0.1 docutils==0.10 amqp==1.3.3 -argparse==1.2.1 six==1.8.0 ftfy==2.0.1 -Pillow==2.4.0 +Pillow==2.7.0 boto==2.13.0 billiard==3.3.0.13 google-api-python-client==1.3.1 diff -r ae146e30d588 -r 3aecf9058130 requirements_dev.txt --- a/requirements_dev.txt Tue Feb 10 20:36:34 2015 -0600 +++ b/requirements_dev.txt Tue Feb 17 18:59:06 2015 -0600 @@ -8,28 +8,26 @@ gdata==2.0.15 html5lib==0.999 bleach==1.4 -pytz==2013b +pytz==2013b0 queued-search==2.1.0 -hg+https://bgneal@bitbucket.org/bgneal/queues@862e884#egg=queues +-e hg+https://bgneal@bitbucket.org/bgneal/queues@862e8846f7e5f5a0df7f08bfe4b4e5283acb4614#egg=queues-dev redis==2.7.2 repoze.timeago==0.5 --e git+https://github.com/notanumber/xapian-haystack.git@37add92bc43fe50bf165e91f370269c26272f1eb#egg=xapian_haystack-master +-e git+https://github.com/notanumber/xapian-haystack.git@37add92bc43fe50bf165e91f370269c26272f1eb#egg=xapian_haystack-dev anyjson==0.3.3 celery==3.1.7 django-picklefield==0.3.1 kombu==3.0.8 python-dateutil==1.5 python-memcached==1.48 -wsgiref==0.1.2 docutils==0.10 amqp==1.3.3 Fabric==1.4.1 -argparse==1.2.1 six==1.8.0 pycrypto==2.5 ssh==1.7.13 ftfy==2.0.1 -Pillow==2.4.0 +Pillow==2.7.0 boto==2.13.0 sqlparse==0.1.10 billiard==3.3.0.13 @@ -41,6 +39,7 @@ rsa==3.1.4 simplejson==3.6.5 uritemplate==0.6 +mock==1.0.1 # # These packages I punted on and hacked into my virtualenv by # symlinking to the global site-packages: diff -r ae146e30d588 -r 3aecf9058130 sg101/templates/contact/contact_email.txt --- a/sg101/templates/contact/contact_email.txt Tue Feb 10 20:36:34 2015 -0600 +++ b/sg101/templates/contact/contact_email.txt Tue Feb 17 18:59:06 2015 -0600 @@ -2,6 +2,7 @@ Sender's Name: {{ user_name }} Sender's Email: {{ user_email }} +Subject: {{ subject }} Message: {{ message|safe }}