view email_list/forms.py @ 85:662707340bd2

Update to Django 1.4.5.
author Brian Neal <bgneal@gmail.com>
date Sat, 09 Mar 2013 17:20:31 -0600
parents e2868ad47a1e
children 0a8942306b04
line wrap: on
line source
"""
Forms for the email_list application.

"""
from django import forms
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.mail import send_mail, send_mass_mail
from django.template.loader import render_to_string

from email_list.models import Subscriber


SUBSCRIBE_OPTS = [('sub', 'Subscribe'), ('unsub', 'Unsubscribe')]

ALREADY_SUBSCRIBED = "This email address is already subscribed."
NOT_SUBSCRIBED = "This email address is not on our list."


class SubscriberForm(forms.Form):
    name = forms.CharField(max_length=64, required=False)
    email = forms.EmailField()
    location = forms.CharField(max_length=64, required=False)
    option = forms.ChoiceField(choices=SUBSCRIBE_OPTS)

    def clean(self):
        """
        This method ensures the appropriate action can be carried out and raises
        a validation error if not.

        """
        email = self.cleaned_data['email']

        if self.cleaned_data['option'] == 'sub':
            # is the user already subscribed (active)?
            try:
                subscriber = Subscriber.objects.get(email=email)
            except Subscriber.DoesNotExist:
                subscriber = Subscriber(email=email,
                        name=self.cleaned_data['name'],
                        location=self.cleaned_data['location'])
            else:
                if subscriber.is_active():
                    raise forms.ValidationError(ALREADY_SUBSCRIBED)
        else:
            # is the user already unsubscribed or not subscribed?
            try:
                subscriber = Subscriber.objects.get(email=email)
            except Subscriber.DoesNotExist:
                raise forms.ValidationError(NOT_SUBSCRIBED)

        # save the subscriber away for a future process() call
        self.subscriber = subscriber

        return self.cleaned_data

    def is_subscribe(self):
        """
        This function can be called after an is_valid() call to determine if the
        request was for a subscribe or unsubscribe.

        """
        return self.cleaned_data['option'] == 'sub'

    def process(self):
        """
        Call this function if is_valid() returns True. It carries out the user's
        subscription request. 

        """
        if self.is_subscribe():
            self.subscriber.set_pending()
        else:
            self.subscriber.set_leaving()

        self.subscriber.save()
        send_email(self.subscriber)


class AdminEmailForm(forms.Form):
    subject = forms.CharField(max_length=255, required=True, label='Subject:',
        widget=forms.TextInput(attrs={'class': 'vTextField required',
            'size': '120'}))
    message = forms.CharField(label='Message:',
        widget=forms.Textarea(attrs={'class': 'vLargeTextField required'}))

    def __init__(self, *args, **kwargs):
        initial = kwargs.pop('initial', {})
        if 'subject' not in initial:
            initial['subject'] = '[%s] ' % settings.BAND_CONFIG['BAND_NAME']
            kwargs['initial'] = initial

        super(AdminEmailForm, self).__init__(*args, **kwargs)

    def save(self):
        """
        Call this function if is_valid() to send the mass email.
        Returns the number of mails sent.

        """
        subject = self.cleaned_data['subject']
        message = self.cleaned_data['message']
        return send_mail_to_subscribers(subject, message)


def send_email(subscriber):
    """
    This function sends out the appropriate email for the given subscriber.

    """
    config = settings.BAND_CONFIG
    band = config['BAND_NAME']
    from_email = config['BAND_EMAIL']

    url = "http://%s%s" % (config['BAND_DOMAIN'],
            reverse('email_list-confirm', kwargs={'key': subscriber.key}))

    if subscriber.is_pending():
        email_template = 'email_list/email_subscribe.txt'
    else:
        email_template = 'email_list/email_unsubscribe.txt'

    msg = render_to_string(email_template, {
        'band': band, 
        'url': url, 
        'band_domain': config['BAND_DOMAIN'],
        })

    subject = "[%s] Mailing List Confirmation" % band

    send_mail(subject, msg, from_email, [subscriber.email])


def send_mail_to_subscribers(subject, message):
    """
    Send an email to each mailing list subscriber with the given subject and
    message.
    Returns the number of messages sent.

    """
    config = settings.BAND_CONFIG
    unsubscribe_url = "http://%s%s" % (config['BAND_DOMAIN'],
              reverse('email_list-main'))

    msg = render_to_string('email_list/mailing_list.txt', {
        'band': config['BAND_NAME'],
        'unsubscribe_url': unsubscribe_url,
        'message': message,
        })

    mail_data = [(subject, msg, config['BAND_EMAIL'], [subscriber]) for
            subscriber in Subscriber.objects.values_list('email', flat=True)]

    send_mass_mail(mail_data)
    return len(mail_data)