django-swingcms / swingcms / mailserver / forms.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.db.models import Q
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe

import settings
from mailserver.models import Email
from swingexceptions import SwingException
from cms.code import list_to_choices
from cms.models import Category, ds
from cms.forms import FormSorter, VisualEditor, HtmlField



FORM_FROM_MODE = {}


class EditSettingsForm(forms.Form):

    required_css_class = 'required'

    default_sender_email = forms.EmailField(label=_('default sender'), max_length=32, required=False)

    contact_email = forms.EmailField(label=_('contact email'), max_length=64, required=False,
                                     widget=forms.TextInput(attrs={'maxlength':'64','size':'64'}))
    default_from_email = forms.EmailField(label=_('default from'), max_length=64, required=False,
                                    widget=forms.TextInput(attrs={'maxlength':'64','size':'64'}))
    default_reply_to_email = forms.EmailField(label=_('default reply to'), max_length=64, required=False,
                                        widget=forms.TextInput(attrs={'maxlength':'64','size':'64'}))
    # TO-DO: replacing with ListField
    test_emails = forms.CharField(label=_('test emails'), max_length=256, required=False,
                                  widget=forms.Textarea(attrs={'rows':2,'cols':74}),
                                  help_text=_("Comma separed test emails"))
    text_plain_top = forms.CharField(label=_('text plain top'), max_length=2048, required=False,
                                     widget=forms.Textarea(attrs={'rows':10,'cols':74}))
    text_html_top = HtmlField(label=_('text html top'), max_length=2048, required=False,
                              widget=VisualEditor({'toolbar':'Full','rows':10,'cols':74}),
                              permitted_tags=settings.PERMITTED_TAGS5)
    text_plain_bottom = forms.CharField(label=_('text plain bottom'), max_length=2048, required=False,
                                        widget=forms.Textarea(attrs={'rows':10,'cols':74}))
    text_html_bottom = HtmlField(label=_('text html bottom'), max_length=2048, required=False,
                                 widget=VisualEditor({'toolbar':'Full','rows':10,'cols':74}),
                                 permitted_tags=settings.PERMITTED_TAGS5)

    def clean_test_emails(self):

        return self.cleaned_data['test_emails'].replace(' ','').split(',')


class ImportemailsForm(forms.Form):

    required_css_class = 'required'

    csv = forms.FileField()
    category = forms.ChoiceField(choices=(), widget=forms.RadioSelect)
    mode = forms.ChoiceField(choices=(('append','append'),('replace','replace')),
                             initial='append', widget=forms.RadioSelect)
    as_subscribers = forms.BooleanField(label=_('as subscribers'), initial=True, required=False)

    def __init__(self, *args, **kwargs):

        super(ImportemailsForm, self).__init__(*args, **kwargs)
        self.fields['category'].choices = Category.objects.filter(scope='email').values_list('name','name')


class ExportemailsForm(forms.Form):

    required_css_class = 'required'

    filename = forms.CharField(max_length=32)
    category = forms.ChoiceField(choices=(), widget=forms.RadioSelect)

    def __init__(self, *args, **kwargs):

        super(ExportemailsForm, self).__init__(*args, **kwargs)
        self.fields['category'].choices = tuple(Category.objects.filter(scope='email').values_list('name','name')) \
                                          + (('subscribers','subscribers'),('all','all'))

    #def clean_to(self):
    #
    #    to = self.cleaned_data['to']
    #    if 'all' in to:
    #        qs = Email.objects.all()
    #    else:
    #        if 'subscribers' in to:
    #            to.remove('subscribers')
    #            qs = Email.objects.filter(Q(categories__name__in=to) | Q(is_subscriber=True))
    #        else:
    #            qs = Email.objects.filter(categories__name__in=to)
    #    to = qs.filter(status__in=('CONFIRMED', 'NOT CHECKED')).values_list('email', flat=True)
    #    return to


class MinimalSendForm(forms.Form):

    required_css_class = 'required'

    subject = forms.CharField(label=_('subject'), max_length=64, required=False)
    text = forms.CharField(label=_('text'), max_length=2048, widget=forms.Textarea({'rows':50,'cols':80}))


class BaseSendForm(forms.Form):

    required_css_class = 'required'

    from_ = forms.CharField(label=_('from'), max_length=32, required=False,
                            help_text=_('default is %s') % (ds.DEFAULT_FROM_EMAIL or _('not defined')))
    sender = forms.CharField(label=_('sender'), max_length=32, required=False,
                            help_text=_('default is %s') % (ds.DEFAULT_SENDER_EMAIL or _('not defined')))
    subject = forms.CharField(label=_('subject'), max_length=64, required=False)
    prepend_top = forms.BooleanField(label=_('prepend top'), initial=True, required=False,
                                     help_text=mark_safe(ds.TEXT_HTML_TOP) or ds.TEXT_PLAIN_TOP)
    text = HtmlField(label=_('text'), max_length=16738, permitted_tags=settings.PERMITTED_TAGS5,
                     widget=VisualEditor({'toolbar':'Mini','rows':50,'cols':80}))
    append_bottom = forms.BooleanField(label=_('append bottom'), initial=True, required=False,
                                     help_text=mark_safe(ds.TEXT_PLAIN_BOTTOM) or ds.TEXT_PLAIN_BOTTOM)


class SendForm(BaseSendForm):

    to = forms.EmailField(label=_('to'), max_length=64,
                          widget=forms.TextInput(attrs={'maxlength':'64','size':'64'}))

    def __init__(self, *args, **kwargs):

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

        self.fields.keyOrder = ['from_','sender','to','subject','prepend_top','text','append_bottom']

    def clean_to(self):

        return (self.cleaned_data['to'],)

FORM_FROM_MODE['simple'] = SendForm


class SendToListForm(BaseSendForm):

    to = forms.MultipleChoiceField(label=_('to'), choices=())
    bcc = forms.BooleanField(label=_('send as bcc'), initial=True, required=False)
    add_test_emails = forms.BooleanField(label=_('add test emails'), initial=True, required=False)

    def __init__(self, email_list=None, *args, **kwargs):

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

        self.fields.keyOrder = ['from_','sender','to','bcc','add_test_emails','subject',
                                'prepend_top','text','append_bottom']

        if email_list:
            choices = list_to_choices(email_list)
        else:
            choices = tuple(Email.objects.filter(status__in=('CONFIRMED','NOT CHECKED')).values_list('email','email'))
        if not email_list:
            raise SwingException(_("No email list available."), level='WARNING', display=True)
        self.fields['to'].choices = choices

FORM_FROM_MODE['to_list'] = SendToListForm


class SendToCategoriesForm(BaseSendForm):

    to = forms.MultipleChoiceField(label=_('to'), choices=(), widget=forms.CheckboxSelectMultiple)
    bcc = forms.BooleanField(label=_('send as bcc'), initial=True, required=False)
    add_test_emails = forms.BooleanField(label=_('add test emails'), initial=True, required=False)

    def __init__(self, category_list=None, *args, **kwargs):

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

        self.fields.keyOrder = ['from_','sender','to','bcc','add_test_emails','subject',
                                'prepend_top','text','append_bottom']

        if category_list:
            choices = list_to_choices(category_list)
        else:
            choices = tuple(Category.objects.filter(scope='email').values_list('name','name'))
        self.fields['to'].choices = choices + (('subscribers','subscribers'), ('all','all'))

    def clean_to(self):

        to = self.cleaned_data['to']
        if 'all' in to:
            qs = Email.objects.all()
        else:
            if 'subscribers' in to:
                to.remove('subscribers')
                qs = Email.objects.filter(Q(categories__name__in=to) | Q(is_subscriber=True))
            else:
                qs = Email.objects.filter(categories__name__in=to)
        to = qs.filter(status__in=('CONFIRMED', 'NOT CHECKED')).values_list('email', flat=True)
        return to

    def clean_text(self):

        text = self.cleaned_data['text']
        if settings.ADD_UNSUBSCRIBE_STRING:
            text += _(settings.UNSUBSCRIBE) % {'domain':settings.DOMAIN}
        return text

FORM_FROM_MODE['to_categories'] = SendToCategoriesForm


class SendToQuerySetForm(BaseSendForm):
    """
    Used as base class for custom queryset form in apps.
    """
    bcc = forms.BooleanField(label=_('send as bcc'), initial=True, required=False)
    add_test_emails = forms.BooleanField(label=_('add test emails'), initial=True, required=False)

    def __init__(self, *args, **kwargs):

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

        query_fields = [lkp for lkp in self.fields.keyOrder if 'lkp' in lkp]
        self.fields.keyOrder = ['from_','sender'] + query_fields + ['bcc','add_test_emails',
                                                                    'subject', 'prepend_top',
                                                                    'text','append_bottom']

FORM_FROM_MODE['to_query_set'] = SendToQuerySetForm


class ContactForm(forms.Form):

    required_css_class = 'required'

    first_name = forms.CharField(label=_('first name'), max_length=32, required=False)
    last_name = forms.CharField(label=_('last name'), max_length=32, required=False)
    email = forms.EmailField(label=_('email'), max_length=64)
    text = forms.CharField(label=_('text'), max_length=10*50,
                           widget=forms.Textarea(attrs={'rows':10,'cols':50}))


class SubscribeBaseForm(forms.Form, FormSorter):

    required_css_class = 'required'

    mode = forms.ChoiceField(label='', initial='subscribe', required=False, widget=forms.RadioSelect,
                             choices=(('subscribe','subscribe'), ('unsubscribe','unsubscribe')))
    accept = forms.BooleanField(label=_('i accept privacy policy'), initial=False,
                                error_messages={'required': _("Please read privacy policy and check this box.")})

    def __init__(self, category_list=None, *args, **kwargs):

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

        # manage categories
        if settings.MANAGE_CATEGORIES:
            category_list = category_list and list_to_choices(category_list) or Category.objects.filter(scope='email').values_list('id','name')
            self.fields['categories'].choices = category_list or ()

        # sort and include/exclude fields according with Meta options
        self.sort_fields()

    def clean_mode(self):

        mode = self.cleaned_data['mode']
        if self.cleaned_data['mode'] == 'unsubscribe':
            self.fields['accept'].required = False
        return mode


class SubscribeAsObjForm(SubscribeBaseForm):

    email = forms.EmailField(label=_('email'), max_length=64,
                             widget=forms.TextInput(attrs={'maxlength':'64','size':'32'}))
    categories = forms.MultipleChoiceField(label=_('categories'), choices=(), required=False,
                                           help_text=_("Optionally select category of interest."),
                                           widget=forms.CheckboxSelectMultiple)

    class Meta:

        fields = ('email', 'categories', 'mode', 'accept')


class SubscribeAsPluginForm(SubscribeBaseForm):

    email = forms.EmailField(label='', max_length=64,
                             widget=forms.TextInput(attrs={'maxlength':'64','size':'22'}))
    categories = forms.MultipleChoiceField(label='', choices=(), required=False,
                                           help_text=_("select category of interest"),
                                           widget=forms.CheckboxSelectMultiple)

    class Meta:

        fields = ('email', 'categories', 'mode', 'accept')
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.