bgneal@51: """ bgneal@51: Forms for the email_list application. bgneal@51: bgneal@51: """ bgneal@51: from django import forms bgneal@51: from django.conf import settings bgneal@51: from django.core.urlresolvers import reverse bgneal@53: from django.core.mail import send_mail, send_mass_mail bgneal@51: from django.template.loader import render_to_string bgneal@51: bgneal@51: from email_list.models import Subscriber bgneal@51: bgneal@51: bgneal@51: SUBSCRIBE_OPTS = [('sub', 'Subscribe'), ('unsub', 'Unsubscribe')] bgneal@51: bgneal@51: ALREADY_SUBSCRIBED = "This email address is already subscribed." bgneal@51: NOT_SUBSCRIBED = "This email address is not on our list." bgneal@51: bgneal@51: bgneal@51: class SubscriberForm(forms.Form): bgneal@101: name = forms.CharField(required=False, bgneal@101: widget=forms.TextInput(attrs={ bgneal@101: 'class': 'form-control', bgneal@101: 'placeholder': 'Your name (optional)'})) bgneal@101: email = forms.EmailField(widget=forms.TextInput(attrs={ bgneal@101: 'class': 'form-control', bgneal@101: 'type': 'email', bgneal@101: 'placeholder': 'Your email address'})) bgneal@101: location = forms.CharField(required=False, bgneal@101: widget=forms.TextInput(attrs={ bgneal@101: 'class': 'form-control', bgneal@101: 'placeholder': 'City, State (optional)'})) bgneal@101: option = forms.ChoiceField(choices=SUBSCRIBE_OPTS, bgneal@101: widget=forms.Select(attrs={'class': 'form-control'})) bgneal@51: bgneal@51: def clean(self): bgneal@51: """ bgneal@51: This method ensures the appropriate action can be carried out and raises bgneal@51: a validation error if not. bgneal@51: bgneal@51: """ bgneal@101: cleaned_data = super(SubscriberForm, self).clean() bgneal@101: email = cleaned_data.get('email') bgneal@101: option = cleaned_data.get('option') bgneal@51: bgneal@101: if not email or not option: bgneal@101: return cleaned_data bgneal@101: bgneal@101: if option == 'sub': bgneal@51: # is the user already subscribed (active)? bgneal@51: try: bgneal@51: subscriber = Subscriber.objects.get(email=email) bgneal@51: except Subscriber.DoesNotExist: bgneal@51: subscriber = Subscriber(email=email, bgneal@101: name=cleaned_data['name'], bgneal@101: location=cleaned_data['location']) bgneal@51: else: bgneal@51: if subscriber.is_active(): bgneal@51: raise forms.ValidationError(ALREADY_SUBSCRIBED) bgneal@51: else: bgneal@51: # is the user already unsubscribed or not subscribed? bgneal@51: try: bgneal@51: subscriber = Subscriber.objects.get(email=email) bgneal@51: except Subscriber.DoesNotExist: bgneal@51: raise forms.ValidationError(NOT_SUBSCRIBED) bgneal@51: bgneal@51: # save the subscriber away for a future process() call bgneal@51: self.subscriber = subscriber bgneal@51: bgneal@101: return cleaned_data bgneal@51: bgneal@51: def is_subscribe(self): bgneal@51: """ bgneal@51: This function can be called after an is_valid() call to determine if the bgneal@51: request was for a subscribe or unsubscribe. bgneal@51: bgneal@51: """ bgneal@51: return self.cleaned_data['option'] == 'sub' bgneal@51: bgneal@51: def process(self): bgneal@51: """ bgneal@51: Call this function if is_valid() returns True. It carries out the user's bgneal@101: subscription request. bgneal@51: bgneal@51: """ bgneal@51: if self.is_subscribe(): bgneal@51: self.subscriber.set_pending() bgneal@51: else: bgneal@51: self.subscriber.set_leaving() bgneal@51: bgneal@51: self.subscriber.save() bgneal@51: send_email(self.subscriber) bgneal@51: bgneal@51: bgneal@53: class AdminEmailForm(forms.Form): bgneal@53: subject = forms.CharField(max_length=255, required=True, label='Subject:', bgneal@53: widget=forms.TextInput(attrs={'class': 'vTextField required', bgneal@53: 'size': '120'})) bgneal@53: message = forms.CharField(label='Message:', bgneal@53: widget=forms.Textarea(attrs={'class': 'vLargeTextField required'})) bgneal@53: bgneal@53: def __init__(self, *args, **kwargs): bgneal@53: initial = kwargs.pop('initial', {}) bgneal@53: if 'subject' not in initial: bgneal@53: initial['subject'] = '[%s] ' % settings.BAND_CONFIG['BAND_NAME'] bgneal@53: kwargs['initial'] = initial bgneal@53: bgneal@53: super(AdminEmailForm, self).__init__(*args, **kwargs) bgneal@53: bgneal@53: def save(self): bgneal@53: """ bgneal@53: Call this function if is_valid() to send the mass email. bgneal@53: Returns the number of mails sent. bgneal@53: bgneal@53: """ bgneal@53: subject = self.cleaned_data['subject'] bgneal@53: message = self.cleaned_data['message'] bgneal@53: return send_mail_to_subscribers(subject, message) bgneal@53: bgneal@53: bgneal@51: def send_email(subscriber): bgneal@51: """ bgneal@51: This function sends out the appropriate email for the given subscriber. bgneal@51: bgneal@51: """ bgneal@51: config = settings.BAND_CONFIG bgneal@51: band = config['BAND_NAME'] bgneal@51: from_email = config['BAND_EMAIL'] bgneal@51: bgneal@51: url = "http://%s%s" % (config['BAND_DOMAIN'], bgneal@51: reverse('email_list-confirm', kwargs={'key': subscriber.key})) bgneal@51: bgneal@51: if subscriber.is_pending(): bgneal@51: email_template = 'email_list/email_subscribe.txt' bgneal@51: else: bgneal@51: email_template = 'email_list/email_unsubscribe.txt' bgneal@51: bgneal@51: msg = render_to_string(email_template, { bgneal@101: 'band': band, bgneal@101: 'url': url, bgneal@51: 'band_domain': config['BAND_DOMAIN'], bgneal@51: }) bgneal@51: bgneal@51: subject = "[%s] Mailing List Confirmation" % band bgneal@51: bgneal@51: send_mail(subject, msg, from_email, [subscriber.email]) bgneal@53: bgneal@53: bgneal@53: def send_mail_to_subscribers(subject, message): bgneal@53: """ bgneal@53: Send an email to each mailing list subscriber with the given subject and bgneal@53: message. bgneal@53: Returns the number of messages sent. bgneal@53: bgneal@53: """ bgneal@53: config = settings.BAND_CONFIG bgneal@53: unsubscribe_url = "http://%s%s" % (config['BAND_DOMAIN'], bgneal@53: reverse('email_list-main')) bgneal@53: bgneal@53: msg = render_to_string('email_list/mailing_list.txt', { bgneal@53: 'band': config['BAND_NAME'], bgneal@53: 'unsubscribe_url': unsubscribe_url, bgneal@53: 'message': message, bgneal@53: }) bgneal@53: bgneal@53: mail_data = [(subject, msg, config['BAND_EMAIL'], [subscriber]) for bgneal@53: subscriber in Subscriber.objects.values_list('email', flat=True)] bgneal@53: bgneal@53: send_mass_mail(mail_data) bgneal@53: return len(mail_data)