From 3e634ccadd9a1ab961ebaad53acd1e502b2f4cf8 Mon Sep 17 00:00:00 2001 From: Bill Fenner Date: Wed, 30 May 2007 11:20:46 +0000 Subject: [PATCH] Get close to the look of the existing form. MultiEmailField might belong in a project infrastructure file, not here. - Legacy-Id: 180 --- ietf/mailinglists/forms.py | 48 +++++++++++++++++++++++++++++++++++++ ietf/mailinglists/models.py | 31 ++++++++++++------------ ietf/mailinglists/views.py | 30 +++++++++++++++++++++-- 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/ietf/mailinglists/forms.py b/ietf/mailinglists/forms.py index 4af2fd882..89933561b 100644 --- a/ietf/mailinglists/forms.py +++ b/ietf/mailinglists/forms.py @@ -146,3 +146,51 @@ class ListReqAuthorized(forms.Form): # subclass pickapprover here too? class ListReqClose(forms.Form): pass + +class AdminRequestor(forms.MultiWidget): + def decompress(self, value): + # This implementation moves the requestor to the listbox + # if there are any validation errors. + # If we could find the requestor, we could instead + # check the checkbox, but for now let's try this. + return ['', '', value] + def __init__(self, attrs=None): + widgets = (forms.CheckboxInput(), forms.TextInput(attrs={'size': 55, 'disabled': True}), forms.Textarea(attrs=attrs)) + super(AdminRequestor, self).__init__(widgets, attrs) + def format_output(self, rendered_widgets): + return u'
\n'.join(["" % rendered_widgets[0]] + rendered_widgets[1:]) + def value_from_datadict(self, data, name): + try: + radio = data.get(name + '_0', "off") + rest = data[name + '_2'] + print "radio is %s, rest is %s" % (radio, rest) + if radio == 'on': + # This has some deep assumptions about how + # this is used. + key = name.replace('admins', 'requestor_email') + try: + return data[key] + "\n" + rest + except KeyError: + return rest + else: + return rest + except KeyError: + try: + return data[name] + except KeyError: + return '' + +class MultiEmailField(forms.CharField): + '''Ensure that each of a carraige-return-separated + list of e-mail addresses is valid.''' + def clean(self, value): + value = super(MultiEmailField, self).clean(value) + bad = list() + for addr in value.split("\n"): + addr = addr.strip() + if addr != '' and not(forms.fields.email_re.search(addr)): + bad.append(addr) + if len(bad) > 0: + raise forms.ValidationError, "The following email addresses seem to be invalid: %s" % ", ".join(["'" + addr + "'" for addr in bad]) + return value + diff --git a/ietf/mailinglists/models.py b/ietf/mailinglists/models.py index cf52a2666..f48054389 100644 --- a/ietf/mailinglists/models.py +++ b/ietf/mailinglists/models.py @@ -1,6 +1,7 @@ from django.db import models from ietf.idtracker.models import Acronym, Area, PersonOrOrgInfo import random +from datetime import datetime class ImportedMailingList(models.Model): group_acronym = models.ForeignKey(Acronym, null=True) @@ -45,26 +46,26 @@ class MailingList(models.Model): ('3', 'Close Non-WG Mailing List'), ) mailing_list_id = models.CharField('Unique ID', primary_key=True, maxlength=25, editable=False) - request_date = models.DateField() - mlist_name = models.CharField('Mailing list name', maxlength=250) - short_desc = models.CharField(maxlength=250) - long_desc = models.TextField(blank=True) - requestor = models.CharField(maxlength=250) - requestor_email = models.CharField(maxlength=250) - # admins is a VARCHAR but can have multiple lines - admins = models.TextField(blank=True, maxlength=250) - archive_remote = models.TextField(blank=True) - archive_private = models.BooleanField() - initial = models.TextField('Initial members',blank=True) - welcome_message = models.TextField(blank=True) - subscription = models.IntegerField(choices=SUBSCRIPTION_CHOICES) + request_date = models.DateField(default=datetime.now, editable=False) + requestor = models.CharField("Requestor's full name", maxlength=250) + requestor_email = models.EmailField("Requestor's email address", maxlength=250) + mlist_name = models.CharField('Email list name', maxlength=250) + short_desc = models.CharField('Short description of the email list', maxlength=250) + long_desc = models.TextField('Long description of the email list') + # admins is a VARCHAR but can have multiple lines. + admins = models.TextField('Mailing list administrators (one address per line)', maxlength=250) + initial = models.TextField('Enter email address(es) of initial subscriber(s) (one address per line) (optional)', blank=True) + welcome_message = models.TextField('Provide a welcome message for initial subscriber(s)(optional)', blank=True) + welcome_new = models.TextField('Provide a welcome message for new subscriber(s)(optional)', blank=True) + subscription = models.IntegerField('What steps are required for subscription?', choices=SUBSCRIPTION_CHOICES) post_who = models.BooleanField('Only members can post') - post_admin = models.BooleanField('Administrator approval required for posts') + post_admin = models.BooleanField('Do postings need to be approved by an administrator?') + archive_private = models.BooleanField('Are the archives private?') + archive_remote = models.TextField('Provide specific information about how to access and move the existing archive (optional)', blank=True) add_comment = models.TextField(blank=True) mail_type = models.IntegerField(choices=MAILTYPE_CHOICES) mail_cat = models.IntegerField(choices=MAILCAT_CHOICES) auth_person = models.ForeignKey(PersonOrOrgInfo, db_column='auth_person_or_org_tag', raw_id_admin=True) - welcome_new = models.TextField(blank=True) approved = models.BooleanField() approved_date = models.DateField(null=True, blank=True) reason_to_delete = models.TextField(blank=True) diff --git a/ietf/mailinglists/views.py b/ietf/mailinglists/views.py index 2abb53c6c..cda302520 100644 --- a/ietf/mailinglists/views.py +++ b/ietf/mailinglists/views.py @@ -1,4 +1,4 @@ -from forms import NonWgStep1, ListReqStep1, PickApprover, DeletionPickApprover, UrlMultiWidget, Preview, ListReqAuthorized, ListReqClose +from forms import NonWgStep1, ListReqStep1, PickApprover, DeletionPickApprover, UrlMultiWidget, Preview, ListReqAuthorized, ListReqClose, MultiEmailField, AdminRequestor from models import NonWgMailingList, MailingList from ietf.idtracker.models import Area, PersonOrOrgInfo from django import newforms as forms @@ -140,12 +140,38 @@ list_fields = { 'approved': None, 'approved_date': None, 'reason_to_delete': None, + 'add_comment': None, + 'mail_type': None, + 'mail_cat': None, + 'domain_name': None, + 'admins': MultiEmailField(label='List Administrator(s)', widget=AdminRequestor(attrs={'cols': 41, 'rows': 4})), + 'initial': MultiEmailField(label='Initial list member(s)', widget=forms.Textarea(attrs={'cols': 41, 'rows': 4}), required=False), } +list_labels = { + 'post_who': 'Who is allowed to post to this list?', +} + +# can I do a multiwidget for the mailing list admins? +# and something to display @domain after the email list name? list_widgets = { + 'subscription': forms.Select(choices=MailingList.SUBSCRIPTION_CHOICES), + 'post_who': forms.Select(choices=(('1', 'List members only'), ('0', 'Open'))), + 'post_admin': forms.Select(choices=(('0', 'No'), ('1', 'Yes'))), + 'archive_private': forms.Select(choices=(('0', 'No'), ('1', 'Yes'))), } list_attrs = { + 'requestor': { 'size': 55 }, + 'requestor_email': { 'size': 55 }, + 'mlist_name': { 'size': 10 }, + 'short_desc': { 'size': 55 }, + 'long_desc': { 'cols': 41, 'rows': 4, 'wrap': 'virtual' }, + 'admins': { 'cols': 41, 'rows': 4 }, + 'initial': { 'cols': 41, 'rows': 4 }, + 'welcome_message': { 'cols': 41, 'rows': 4 }, + 'welcome_new': { 'cols': 41, 'rows': 4 }, + 'archive_remote': { 'cols': 41, 'rows': 4 }, } list_callback = form_decorator(fields=list_fields, widgets=list_widgets, attrs=list_attrs) @@ -175,7 +201,7 @@ class ListReqWizard(wizard.Wizard): if form.clean_data['mail_type'].startswith('close'): self.form_list.append(ListReqClose) else: - self.form_list.append(forms.form_for_model(MailingList)) + self.form_list.append(forms.form_for_model(MailingList, formfield_callback=list_callback)) #XXX not quite super(ListReqWizard, self).process_step(request, form, step)