def subscribe(request, newsletter_slug):
    """
    Subscribe a user to the newsletter
    
    Requires a POST with an email
    """
    newsletter = get_object_or_404(Newsletter, slug=newsletter_slug)
    if request.method != 'POST':
        if is_json_request:
            return JSONResponse({
                'success': False, 
                'message': 'Only POST methods are allowed.'})
        return HttpResponseNotAllowed(['POST',])
    if 'email' not in request.POST:
        if is_json_request:
            return JSONResponse({
                'success': False, 
                'message': 'No email field was included.'})
        raise Http404("email not included in POST")
    try:
        sub = Subscription.objects.get(email=request.POST['email'],
                                       newsletter=newsletter)
    except Subscription.DoesNotExist:
        # The user wasn't subscribed, so we'll create it.
        sub = Subscription.objects.create(email=request.POST['email'],
                                    newsletter=newsletter)
        send_notification([], [newsletter], request.POST['email'])
        subscription.send(sender=newsletter, email=request.POST['email'],
                                        newsletter=newsletter)
    if is_json_request(request):
        return JSONResponse({'success': True, 'message': ''})
    return render_to_response('newsletters/subscribe.html', {
        'newsletter': newsletter
    }, RequestContext(request))
def sync_subscriptions(sub_form):
    """
    Do all the work of (un)subscribing newsletters for an account
    """
    old_subs = Subscription.objects.filter(email=sub_form.cleaned_data['email'])
    old_subs_nl = [item.newsletter for item in old_subs]
    new_subs = Newsletter.objects.filter(name__in=sub_form.get_subscriptions())
    
    unsubs = [sub for sub in old_subs if sub.newsletter not in new_subs]
    unsub_nl = [sub.newsletter for sub in unsubs]
    subs = [nl for nl in new_subs if nl not in old_subs_nl]
    
    for item in unsubs:
        unsubscription.send(
            sender=item.newsletter, 
            email=sub_form.cleaned_data['email'],
            newsletter=item.newsletter)
        item.delete()
    for item in subs:
        sub = Subscription.objects.create(
            email=sub_form.cleaned_data['email'],
            newsletter=item,
            confirmed=AUTO_CONFIRM,
        )
        subscription.send(
            sender=item,
            email=sub_form.cleaned_data['email'],
            newsletter=item,
        )
    send_notification(unsub_nl, subs, sub_form.cleaned_data['email'])
    return unsub_nl, subs
def bulk_subscribe(request):
    """
    Subscribe to many newsletters at once. Only for use with JSON and POST
    """
    from django.core.validators import validate_email
    from django.core.exceptions import ValidationError
    try:
        if request.method != 'POST':
            return JSONResponse({
                'success': False,
                'message': 'Form must be submitted using POST.'})
        
        values = dict(request.POST.items())
        
        if 'csrfmiddlewaretoken' in values:
            del values['csrfmiddlewaretoken']
        
        try:
            validate_email(values['email'])
            email = values['email']
            newsletters = [key for key in values.keys() if key != 'email']
            if not newsletters:
                return JSONResponse({
                    'success': False, 
                    'message': "Please select at least one newsletter."})
            nletters = Newsletter.objects.filter(slug__in=newsletters)
            for newsletter in nletters:
                try:
                    sub = Subscription.objects.get(email=email,
                                                   newsletter=newsletter)
                except Subscription.DoesNotExist:
                    # The user wasn't subscribed, so we'll create it.
                    sub = Subscription.objects.create(email=email,
                                                newsletter=newsletter)
                    subscription.send(
                        sender=newsletter,
                        email=email,
                        newsletter=newsletter,
                    )
            send_notification([], nletters, email)
            
            return JSONResponse({
                'success': True,
                'message': 'You signed up for ' + ", ".join([x.name for x in nletters])})
        except ValidationError, e:
            return JSONResponse({
                'success': False,
                'message': " ".join(e.messages)})
    except Exception, e:
        return JSONResponse({
            'success': False,
            'message': "We're sorry but a strange error occurred. (%s)" % str(e)})