diff --git a/ietf/nomcom/admin.py b/ietf/nomcom/admin.py
new file mode 100644
index 000000000..35db6010d
--- /dev/null
+++ b/ietf/nomcom/admin.py
@@ -0,0 +1,11 @@
+from django.contrib import admin
+
+from ietf.group.admin import GroupAdmin
+from ietf.nomcom.models import NomComGroup
+
+
+class NomComGroupAdmin(GroupAdmin):
+ exclude = ('type',)
+
+
+admin.site.register(NomComGroup, NomComGroupAdmin)
diff --git a/ietf/nomcom/forms.py b/ietf/nomcom/forms.py
index e219d8146..eabd121be 100644
--- a/ietf/nomcom/forms.py
+++ b/ietf/nomcom/forms.py
@@ -1,61 +1,58 @@
from django import forms
from django.contrib.formtools.preview import FormPreview
from django.http import HttpResponseRedirect, HttpResponseForbidden
+from django.shortcuts import get_object_or_404
from django.core.urlresolvers import reverse
+from django.conf import settings
from ietf.ietfauth.decorators import has_role
from ietf.utils import fields as custom_fields
-from ietf.group.models import Group, Role
+from ietf.group.models import Role
+from ietf.nomcom.models import NomComGroup
from ietf.name.models import RoleName
from ietf.person.models import Email
-class ManageGroupForm(forms.Form):
+ROLODEX_URL = getattr(settings, 'ROLODEX_URL', None)
+
+
+class EditMembersForm(forms.Form):
- chair = forms.EmailField(label="Chair email", required=False,
- widget=forms.TextInput(attrs={'size': '40'}))
members = custom_fields.MultiEmailField(label="Members email", required=False)
- def __init__(self, *args, **kwargs):
- super(ManageGroupForm, self).__init__(*args, **kwargs)
+class EditMembersFormPreview(FormPreview):
+ form_template = 'nomcom/edit_members.html'
+ preview_template = 'nomcom/edit_members_preview.html'
-class ManageGroupFormPreview(FormPreview):
- form_template = 'nomcom/manage_group.html'
- preview_template = 'nomcom/manage_group_review.html'
+ def __call__(self, request, *args, **kwargs):
+ year = kwargs['year']
+ group = get_object_or_404(NomComGroup,
+ acronym__icontains=year,
+ state__slug='active')
+ is_group_chair = bool(group.role_set.filter(person__user=request.user, name__slug='chair')[:1])
+ is_secretariat = has_role(request.user, "Secretariat")
+ if not is_secretariat and not is_group_chair:
+ return HttpResponseForbidden("Must be a secretariat or group chair")
- def preview_get(self, request):
- if not has_role(request.user, "Secretariat"):
- return HttpResponseForbidden("Must be a secretariat")
-
- return super(ManageGroupFormPreview, self).preview_get(request)
+ self.state['group'] = group
+ self.state['rolodex_url'] = ROLODEX_URL
+ self.group = group
+ self.year = year
+ return super(EditMembersFormPreview, self).__call__(request, *args, **kwargs)
def parse_params(self, *args, **kwargs):
- group_acronym = kwargs['acronym']
- group = Group.objects.get(acronym=group_acronym)
- chairs = group.role_set.filter(name__slug='chair')
- members = group.role_set.filter(name__slug='member')
- if chairs:
- self.form.base_fields['chair'].initial = chairs[0].email.address
+ members = self.group.role_set.filter(name__slug='member')
+
if members:
self.form.base_fields['members'].initial = ',\r\n'.join([role.email.address for role in members])
- self.state['group'] = group
def process_preview(self, request, form, context):
- chair_email = form.cleaned_data['chair']
members_email = form.cleaned_data['members'].replace('\r\n', '').replace(' ', '').split(',')
+
members_info = []
emails_not_found = []
- try:
- chair_email_obj = Email.objects.get(address=chair_email)
- chair_person = chair_email_obj.person
- except Email.DoesNotExist:
- chair_person = None
- chair_email_obj = None
- chair_info = {'email': chair_email,
- 'email_obj': chair_email_obj,
- 'person': chair_person}
for email in members_email:
try:
@@ -69,29 +66,76 @@ class ManageGroupFormPreview(FormPreview):
'person': person})
else:
emails_not_found.append(email)
- self.state.update({'chair_info': chair_info,
- 'members_info': members_info,
+ self.state.update({'members_info': members_info,
'emails_not_found': emails_not_found})
def done(self, request, cleaned_data):
- group = self.state['group']
- chair_info = self.state['chair_info']
members_info = self.state['members_info']
members_email = [member['email'] for member in self.state['members_info']]
- members_excluded = group.role_set.filter(name__slug='member').exclude(email__address__in=members_email)
+ members_excluded = self.group.role_set.filter(name__slug='member').exclude(email__address__in=members_email)
members_excluded.delete()
for member in members_info:
Role.objects.get_or_create(name=RoleName.objects.get(slug="member"),
- group=group,
+ group=self.group,
person=member['person'],
email=member['email_obj'])
- chair_exclude = group.role_set.filter(name__slug='chair').exclude(email__address=chair_info['email'])
+ return HttpResponseRedirect(reverse('edit_members', kwargs={'year': self.year}))
+
+
+class EditChairForm(forms.Form):
+
+ chair = forms.EmailField(label="Chair email", required=False,
+ widget=forms.TextInput(attrs={'size': '40'}))
+
+
+class EditChairFormPreview(FormPreview):
+ form_template = 'nomcom/edit_chair.html'
+ preview_template = 'nomcom/edit_chair_preview.html'
+
+ def __call__(self, request, *args, **kwargs):
+ year = kwargs['year']
+ group = get_object_or_404(NomComGroup,
+ acronym__icontains=year,
+ state__slug='active')
+ is_secretariat = has_role(request.user, "Secretariat")
+ if not is_secretariat:
+ return HttpResponseForbidden("Must be a secretariat")
+
+ self.state['group'] = group
+ self.state['rolodex_url'] = ROLODEX_URL
+ self.group = group
+ self.year = year
+
+ return super(EditChairFormPreview, self).__call__(request, *args, **kwargs)
+
+ def parse_params(self, *args, **kwargs):
+ chairs = self.group.role_set.filter(name__slug='chair')
+ if chairs:
+ self.form.base_fields['chair'].initial = chairs[0].email.address
+
+ def process_preview(self, request, form, context):
+ chair_email = form.cleaned_data['chair']
+ try:
+ chair_email_obj = Email.objects.get(address=chair_email)
+ chair_person = chair_email_obj.person
+ except Email.DoesNotExist:
+ chair_person = None
+ chair_email_obj = None
+ chair_info = {'email': chair_email,
+ 'email_obj': chair_email_obj,
+ 'person': chair_person}
+
+ self.state.update({'chair_info': chair_info})
+
+ def done(self, request, cleaned_data):
+ chair_info = self.state['chair_info']
+ chair_exclude = self.group.role_set.filter(name__slug='chair').exclude(email__address=chair_info['email'])
chair_exclude.delete()
if chair_info['email_obj'] and chair_info['person']:
Role.objects.get_or_create(name=RoleName.objects.get(slug="chair"),
- group=group,
+ group=self.group,
person=chair_info['person'],
email=chair_info['email_obj'])
- return HttpResponseRedirect(reverse('manage_group', kwargs={'acronym': group.acronym}))
+ return HttpResponseRedirect(reverse('edit_chair', kwargs={'year': self.year}))
diff --git a/ietf/nomcom/migrations/0001_initial.py b/ietf/nomcom/migrations/0001_initial.py
new file mode 100644
index 000000000..3b7e978a0
--- /dev/null
+++ b/ietf/nomcom/migrations/0001_initial.py
@@ -0,0 +1,228 @@
+# encoding: utf-8
+from south.db import db
+from south.v2 import SchemaMigration
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'NomComGroup'
+ db.create_table('nomcom_nomcomgroup', (
+ ('group_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['group.Group'], unique=True, primary_key=True)),
+ ('public_key', self.gf('django.db.models.fields.TextField')(blank=True)),
+ ))
+ db.send_create_signal('nomcom', ['NomComGroup'])
+
+ def backwards(self, orm):
+
+ # Deleting model 'NomComGroup'
+ db.delete_table('nomcom_nomcomgroup')
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'doc.docalias': {
+ 'Meta': {'object_name': 'DocAlias'},
+ 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
+ },
+ 'doc.document': {
+ 'Meta': {'object_name': 'Document'},
+ 'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
+ 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocumentAuthor']", 'blank': 'True'}),
+ 'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
+ 'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
+ 'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
+ 'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
+ 'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'related': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'reversely_related_document_set'", 'blank': 'True', 'through': "orm['doc.RelatedDocument']", 'to': "orm['doc.DocAlias']"}),
+ 'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
+ 'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
+ 'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
+ 'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
+ },
+ 'doc.documentauthor': {
+ 'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
+ },
+ 'doc.relateddocument': {
+ 'Meta': {'object_name': 'RelatedDocument'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocRelationshipName']"}),
+ 'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
+ 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocAlias']"})
+ },
+ 'doc.state': {
+ 'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'previous_states'", 'symmetrical': 'False', 'to': "orm['doc.State']"}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+ 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'doc.statetype': {
+ 'Meta': {'object_name': 'StateType'},
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
+ },
+ 'group.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
+ 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
+ 'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': "orm['doc.Document']"}),
+ 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
+ 'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}),
+ 'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'name.docrelationshipname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'DocRelationshipName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'name.doctagname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'name.doctypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'name.groupstatename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'name.grouptypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'name.intendedstdlevelname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'name.stdlevelname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'name.streamname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
+ 'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
+ 'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'nomcom.nomcomgroup': {
+ 'Meta': {'object_name': 'NomComGroup', '_ormbases': ['group.Group']},
+ 'group_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.Group']", 'unique': 'True', 'primary_key': 'True'}),
+ 'public_key': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+ },
+ 'person.email': {
+ 'Meta': {'object_name': 'Email'},
+ 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
+ },
+ 'person.person': {
+ 'Meta': {'object_name': 'Person'},
+ 'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
+ 'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['nomcom']
diff --git a/ietf/nomcom/migrations/__init__.py b/ietf/nomcom/migrations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/ietf/nomcom/models.py b/ietf/nomcom/models.py
index 71a836239..d97716e41 100644
--- a/ietf/nomcom/models.py
+++ b/ietf/nomcom/models.py
@@ -1,3 +1,21 @@
from django.db import models
-# Create your models here.
+from ietf.group.models import Group
+from ietf.name.models import GroupTypeName
+
+
+class NomComGroup(Group):
+ public_key = models.TextField(verbose_name="Public Key", blank=True)
+
+ class Meta:
+ verbose_name_plural = "NomCom groups"
+ verbose_name = "NomCom group"
+
+ def save(self, *args, **kwargs):
+ if not self.id:
+ try:
+ self.type = GroupTypeName.objects.get(slug='nomcom')
+ except GroupTypeName.DoesNotExist:
+ pass
+
+ super(NomComGroup, self).save(*args, **kwargs)
diff --git a/ietf/nomcom/urls.py b/ietf/nomcom/urls.py
index 1de15f3ae..c138219ad 100644
--- a/ietf/nomcom/urls.py
+++ b/ietf/nomcom/urls.py
@@ -1,7 +1,8 @@
from django.conf.urls.defaults import patterns, url
-from ietf.nomcom.forms import ManageGroupForm, ManageGroupFormPreview
+from ietf.nomcom.forms import EditChairForm, EditChairFormPreview, \
+ EditMembersForm, EditMembersFormPreview
urlpatterns = patterns('ietf.nomcom.views',
-
- url(r'^group/(?P[\w.@+-]+)/$', ManageGroupFormPreview(ManageGroupForm), name='manage_group'),
+ url(r'^(?P
+{% if state.chair_info.person %}
+ Person with {{ state.chair_info.email }} not exists. {% if state.rolodex_url %} Please go to {{ state.rolodex_url }} to add this person.{% endif %}Edit {{ state.group.acronym }} chair
+
+{% if form.errors %}Please correct the following errors
{% endif %}
+
+
+
+{% endblock %}
diff --git a/ietf/templates/nomcom/edit_chair_preview.html b/ietf/templates/nomcom/edit_chair_preview.html
new file mode 100644
index 000000000..04bb844e8
--- /dev/null
+++ b/ietf/templates/nomcom/edit_chair_preview.html
@@ -0,0 +1,44 @@
+{% extends "base.html" %}
+
+{% block title %}Edit {{ state.group.acronym }} chair{% endblock %}
+
+{% block content %}
+Edit {{ state.group.acronym }} chair
+
+Chair info
+
+
+{% else %}
+