diff --git a/INSTALL b/INSTALL
index 07aa60c0c..ea33a69ce 100644
--- a/INSTALL
+++ b/INSTALL
@@ -121,6 +121,17 @@ usual, with re-pointing the symlink and restarting apache.
Additional Version-Specific Instructions
========================================
+Version 4.46
+------------
+
+Before you run step 3 (migration) of the general instructions, please run some specific
+initial migrations with the a --fake argument:
+
+ cd $releasenumber
+ PYTHONPATH=$PWD ietf/manage.py migrate group 0001 --fake
+ cd ..
+
+
Version 4.42
------------
diff --git a/changelog b/changelog
index e9d2c1de5..9c918fa17 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,14 @@
+ietfdb (4.46) ietf; urgency=medium
+
+ This is a major feature release, which introduces datatracker support
+ for milestone management. WG Chairs will, if they are logged in, see
+ an 'Add or edit milestones' button on the WG's Charter page in the
+ datatracker, just below the charter text, and Area Directors and
+ Secretariat staff will see a new link 'Milestones' in the left-hand
+ menu-bar, leading to a page which lists Milestones Needing Review.
+
+ -- Henrik Levkowetz 14 May 2013 21:50:09 +0200
+
ietfdb (4.45) ietf; urgency=medium
This release contains bugfixes and some minor features.
diff --git a/ietf/__init__.py b/ietf/__init__.py
index ef08ac675..22887db83 100644
--- a/ietf/__init__.py
+++ b/ietf/__init__.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8-no-bom -*-
# Copyright The IETF Trust 2007, All Rights Reserved
__version__ = "4.46-dev"
diff --git a/ietf/bin/send-milestone-reminders b/ietf/bin/send-milestone-reminders
new file mode 100755
index 000000000..a23a7bcb9
--- /dev/null
+++ b/ietf/bin/send-milestone-reminders
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+#
+# This script will send various milestone reminders. It's supposed to
+# be run daily, and will then send reminders weekly/monthly as
+# appropriate.
+
+import datetime, os
+import syslog
+
+from ietf import settings
+from django.core import management
+management.setup_environ(settings)
+
+syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_LOCAL0)
+
+from ietf.wginfo.mails import *
+
+today = datetime.date.today()
+
+MONDAY = 1
+FIRST_DAY_OF_MONTH = 1
+
+if today.isoweekday() == MONDAY:
+ # send milestone review reminders - ideally we'd keep track of
+ # exactly when we sent one last time for a group, but it's a bit
+ # complicated because people can change the milestones in the mean
+ # time, so dodge all of this by simply sending once a week only
+ for g in groups_with_milestones_needing_review():
+ mail_sent = email_milestone_review_reminder(g, grace_period=7)
+ if mail_sent:
+ syslog.syslog("Sent milestone review reminder for %s %s" % (g.acronym, g.type.name))
+
+
+early_warning_days = 30
+
+# send any milestones due reminders
+for g in groups_needing_milestones_due_reminder(early_warning_days):
+ email_milestones_due(g, early_warning_days)
+ syslog.syslog("Sent milestones due reminder for %s %s" % (g.acronym, g.type.name))
+
+if today.day == FIRST_DAY_OF_MONTH:
+ # send milestone overdue reminders - once a month
+ for g in groups_needing_milestones_overdue_reminder(grace_period=30):
+ email_milestones_overdue(g)
+ syslog.syslog("Sent milestones overdue reminder for %s %s" % (g.acronym, g.type.name))
diff --git a/ietf/doc/models.py b/ietf/doc/models.py
index a64753d0e..31d6a35f6 100644
--- a/ietf/doc/models.py
+++ b/ietf/doc/models.py
@@ -465,6 +465,7 @@ EVENT_TYPES = [
# WG events
("changed_group", "Changed group"),
("changed_protocol_writeup", "Changed protocol writeup"),
+ ("changed_charter_milestone", "Changed charter milestone"),
# charter events
("initial_review", "Set initial review time"),
diff --git a/ietf/group/admin.py b/ietf/group/admin.py
index 2af54013c..ff0040af0 100644
--- a/ietf/group/admin.py
+++ b/ietf/group/admin.py
@@ -116,9 +116,9 @@ class GroupHistoryAdmin(admin.ModelAdmin):
admin.site.register(GroupHistory, GroupHistoryAdmin)
class GroupMilestoneAdmin(admin.ModelAdmin):
- list_display = ["group", "desc", "expected_due_date", "time"]
- search_fields = ["group__name", "group__acronym", "desc"]
- raw_id_fields = ["group"]
+ list_display = ["group", "desc", "due", "resolved", "time"]
+ search_fields = ["group__name", "group__acronym", "desc", "resolved"]
+ raw_id_fields = ["group", "docs"]
admin.site.register(GroupMilestone, GroupMilestoneAdmin)
diff --git a/ietf/group/migrations/0001_initial.py b/ietf/group/migrations/0001_initial.py
new file mode 100644
index 000000000..6e9852f5d
--- /dev/null
+++ b/ietf/group/migrations/0001_initial.py
@@ -0,0 +1,481 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'Group'
+ db.create_table('group_group', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('time', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=80)),
+ ('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.GroupStateName'], null=True)),
+ ('type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.GroupTypeName'], null=True)),
+ ('parent', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'], null=True, blank=True)),
+ ('ad', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'], null=True, blank=True)),
+ ('list_email', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)),
+ ('list_subscribe', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
+ ('list_archive', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
+ ('comments', self.gf('django.db.models.fields.TextField')(blank=True)),
+ ('acronym', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=40, db_index=True)),
+ ('charter', self.gf('django.db.models.fields.related.OneToOneField')(blank=True, related_name='chartered_group', unique=True, null=True, to=orm['doc.Document'])),
+ ))
+ db.send_create_signal('group', ['Group'])
+
+ # Adding M2M table for field unused_states on 'Group'
+ db.create_table('group_group_unused_states', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('group', models.ForeignKey(orm['group.group'], null=False)),
+ ('state', models.ForeignKey(orm['doc.state'], null=False))
+ ))
+ db.create_unique('group_group_unused_states', ['group_id', 'state_id'])
+
+ # Adding M2M table for field unused_tags on 'Group'
+ db.create_table('group_group_unused_tags', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('group', models.ForeignKey(orm['group.group'], null=False)),
+ ('doctagname', models.ForeignKey(orm['name.doctagname'], null=False))
+ ))
+ db.create_unique('group_group_unused_tags', ['group_id', 'doctagname_id'])
+
+ # Adding model 'GroupHistory'
+ db.create_table('group_grouphistory', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('time', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=80)),
+ ('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.GroupStateName'], null=True)),
+ ('type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.GroupTypeName'], null=True)),
+ ('parent', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'], null=True, blank=True)),
+ ('ad', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'], null=True, blank=True)),
+ ('list_email', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)),
+ ('list_subscribe', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
+ ('list_archive', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
+ ('comments', self.gf('django.db.models.fields.TextField')(blank=True)),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(related_name='history_set', to=orm['group.Group'])),
+ ('acronym', self.gf('django.db.models.fields.CharField')(max_length=40)),
+ ))
+ db.send_create_signal('group', ['GroupHistory'])
+
+ # Adding M2M table for field unused_states on 'GroupHistory'
+ db.create_table('group_grouphistory_unused_states', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('grouphistory', models.ForeignKey(orm['group.grouphistory'], null=False)),
+ ('state', models.ForeignKey(orm['doc.state'], null=False))
+ ))
+ db.create_unique('group_grouphistory_unused_states', ['grouphistory_id', 'state_id'])
+
+ # Adding M2M table for field unused_tags on 'GroupHistory'
+ db.create_table('group_grouphistory_unused_tags', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('grouphistory', models.ForeignKey(orm['group.grouphistory'], null=False)),
+ ('doctagname', models.ForeignKey(orm['name.doctagname'], null=False))
+ ))
+ db.create_unique('group_grouphistory_unused_tags', ['grouphistory_id', 'doctagname_id'])
+
+ # Adding model 'GroupURL'
+ db.create_table('group_groupurl', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'])),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('url', self.gf('django.db.models.fields.URLField')(max_length=200)),
+ ))
+ db.send_create_signal('group', ['GroupURL'])
+
+ # Adding model 'GroupMilestone'
+ db.create_table('group_groupmilestone', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'])),
+ ('desc', self.gf('django.db.models.fields.TextField')()),
+ ('expected_due_date', self.gf('django.db.models.fields.DateField')()),
+ ('done', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('done_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+ ('time', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+ ))
+ db.send_create_signal('group', ['GroupMilestone'])
+
+ # Adding model 'GroupStateTransitions'
+ db.create_table('group_groupstatetransitions', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'])),
+ ('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['doc.State'])),
+ ))
+ db.send_create_signal('group', ['GroupStateTransitions'])
+
+ # Adding M2M table for field next_states on 'GroupStateTransitions'
+ db.create_table('group_groupstatetransitions_next_states', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('groupstatetransitions', models.ForeignKey(orm['group.groupstatetransitions'], null=False)),
+ ('state', models.ForeignKey(orm['doc.state'], null=False))
+ ))
+ db.create_unique('group_groupstatetransitions_next_states', ['groupstatetransitions_id', 'state_id'])
+
+ # Adding model 'GroupEvent'
+ db.create_table('group_groupevent', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'])),
+ ('time', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('type', self.gf('django.db.models.fields.CharField')(max_length=50)),
+ ('by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'])),
+ ('desc', self.gf('django.db.models.fields.TextField')()),
+ ))
+ db.send_create_signal('group', ['GroupEvent'])
+
+ # Adding model 'ChangeStateGroupEvent'
+ db.create_table('group_changestategroupevent', (
+ ('groupevent_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['group.GroupEvent'], unique=True, primary_key=True)),
+ ('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.GroupStateName'])),
+ ))
+ db.send_create_signal('group', ['ChangeStateGroupEvent'])
+
+ # Adding model 'Role'
+ db.create_table('group_role', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.RoleName'])),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'])),
+ ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'])),
+ ('email', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Email'])),
+ ))
+ db.send_create_signal('group', ['Role'])
+
+ # Adding model 'RoleHistory'
+ db.create_table('group_rolehistory', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.RoleName'])),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.GroupHistory'])),
+ ('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Person'])),
+ ('email', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Email'])),
+ ))
+ db.send_create_signal('group', ['RoleHistory'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'Group'
+ db.delete_table('group_group')
+
+ # Removing M2M table for field unused_states on 'Group'
+ db.delete_table('group_group_unused_states')
+
+ # Removing M2M table for field unused_tags on 'Group'
+ db.delete_table('group_group_unused_tags')
+
+ # Deleting model 'GroupHistory'
+ db.delete_table('group_grouphistory')
+
+ # Removing M2M table for field unused_states on 'GroupHistory'
+ db.delete_table('group_grouphistory_unused_states')
+
+ # Removing M2M table for field unused_tags on 'GroupHistory'
+ db.delete_table('group_grouphistory_unused_tags')
+
+ # Deleting model 'GroupURL'
+ db.delete_table('group_groupurl')
+
+ # Deleting model 'GroupMilestone'
+ db.delete_table('group_groupmilestone')
+
+ # Deleting model 'GroupStateTransitions'
+ db.delete_table('group_groupstatetransitions')
+
+ # Removing M2M table for field next_states on 'GroupStateTransitions'
+ db.delete_table('group_groupstatetransitions_next_states')
+
+ # Deleting model 'GroupEvent'
+ db.delete_table('group_groupevent')
+
+ # Deleting model 'ChangeStateGroupEvent'
+ db.delete_table('group_changestategroupevent')
+
+ # Deleting model 'Role'
+ db.delete_table('group_role')
+
+ # Deleting model 'RoleHistory'
+ db.delete_table('group_rolehistory')
+
+
+ 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.changestategroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'ChangeStateGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']"})
+ },
+ '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'})
+ },
+ 'group.groupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'GroupEvent'},
+ 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
+ 'desc': ('django.db.models.fields.TextField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'group.grouphistory': {
+ 'Meta': {'object_name': 'GroupHistory'},
+ 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
+ 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['group.Group']"}),
+ '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'})
+ },
+ 'group.groupmilestone': {
+ 'Meta': {'ordering': "['expected_due_date']", 'object_name': 'GroupMilestone'},
+ 'desc': ('django.db.models.fields.TextField', [], {}),
+ 'done': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'done_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'expected_due_date': ('django.db.models.fields.DateField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'group.groupstatetransitions': {
+ 'Meta': {'object_name': 'GroupStateTransitions'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'previous_groupstatetransitions_states'", 'symmetrical': 'False', 'to': "orm['doc.State']"}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.State']"})
+ },
+ 'group.groupurl': {
+ 'Meta': {'object_name': 'GroupURL'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'group.role': {
+ 'Meta': {'object_name': 'Role'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ 'group.rolehistory': {
+ 'Meta': {'object_name': 'RoleHistory'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupHistory']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ '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.rolename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
+ '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'})
+ },
+ '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 = ['group']
diff --git a/ietf/group/migrations/0002_auto__add_milestonegroupevent__del_field_groupmilestone_expected_due_d.py b/ietf/group/migrations/0002_auto__add_milestonegroupevent__del_field_groupmilestone_expected_due_d.py
new file mode 100644
index 000000000..b7b05efc2
--- /dev/null
+++ b/ietf/group/migrations/0002_auto__add_milestonegroupevent__del_field_groupmilestone_expected_due_d.py
@@ -0,0 +1,361 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ depends_on = (
+ ("name", "0009_add_groupmilestonestatenames"),
+ )
+
+ def forwards(self, orm):
+
+ # Adding model 'MilestoneGroupEvent'
+ db.create_table('group_milestonegroupevent', (
+ ('groupevent_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['group.GroupEvent'], unique=True, primary_key=True)),
+ ('milestone', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.GroupMilestone'])),
+ ))
+ db.send_create_signal('group', ['MilestoneGroupEvent'])
+
+ # rename expected_due_date
+ db.rename_column('group_groupmilestone', 'expected_due_date', "due")
+
+ # Adding field 'GroupMilestone.resolved'
+ db.add_column('group_groupmilestone', 'resolved', self.gf('django.db.models.fields.CharField')(default='', max_length=50, blank=True), keep_default=False)
+
+ # Adding field 'GroupMilestone.state'
+ db.add_column('group_groupmilestone', 'state', self.gf('django.db.models.fields.related.ForeignKey')(default='active', to=orm['name.GroupMilestoneStateName']), keep_default=False)
+
+ # Adding M2M table for field docs on 'GroupMilestone'
+ db.create_table('group_groupmilestone_docs', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('groupmilestone', models.ForeignKey(orm['group.groupmilestone'], null=False)),
+ ('document', models.ForeignKey(orm['doc.document'], null=False))
+ ))
+ db.create_unique('group_groupmilestone_docs', ['groupmilestone_id', 'document_id'])
+
+ # Changing field 'GroupMilestone.desc'
+ db.alter_column('group_groupmilestone', 'desc', self.gf('django.db.models.fields.CharField')(max_length=500))
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'MilestoneGroupEvent'
+ db.delete_table('group_milestonegroupevent')
+
+ # rename due
+ db.rename_column('group_groupmilestone', 'due', "expected_due_date")
+
+ # Deleting field 'GroupMilestone.resolved'
+ db.delete_column('group_groupmilestone', 'resolved')
+
+ # Deleting field 'GroupMilestone.state'
+ db.delete_column('group_groupmilestone', 'state_id')
+
+ # Removing M2M table for field docs on 'GroupMilestone'
+ db.delete_table('group_groupmilestone_docs')
+
+ # Changing field 'GroupMilestone.desc'
+ db.alter_column('group_groupmilestone', 'desc', self.gf('django.db.models.fields.TextField')())
+
+
+ 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.changestategroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'ChangeStateGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']"})
+ },
+ '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'})
+ },
+ 'group.groupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'GroupEvent'},
+ 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
+ 'desc': ('django.db.models.fields.TextField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'group.grouphistory': {
+ 'Meta': {'object_name': 'GroupHistory'},
+ 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
+ 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['group.Group']"}),
+ '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'})
+ },
+ 'group.groupmilestone': {
+ 'Meta': {'ordering': "['due', 'id']", 'object_name': 'GroupMilestone'},
+ 'desc': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'done': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'done_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'due': ('django.db.models.fields.DateField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'resolved': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupMilestoneStateName']"}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'group.groupstatetransitions': {
+ 'Meta': {'object_name': 'GroupStateTransitions'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'previous_groupstatetransitions_states'", 'symmetrical': 'False', 'to': "orm['doc.State']"}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.State']"})
+ },
+ 'group.groupurl': {
+ 'Meta': {'object_name': 'GroupURL'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'group.milestonegroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'MilestoneGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'milestone': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupMilestone']"})
+ },
+ 'group.role': {
+ 'Meta': {'object_name': 'Role'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ 'group.rolehistory': {
+ 'Meta': {'object_name': 'RoleHistory'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupHistory']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ '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.groupmilestonestatename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
+ '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.rolename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
+ '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'})
+ },
+ '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 = ['group']
diff --git a/ietf/group/migrations/0003_fixup_milestone.py b/ietf/group/migrations/0003_fixup_milestone.py
new file mode 100644
index 000000000..8abdc3d6f
--- /dev/null
+++ b/ietf/group/migrations/0003_fixup_milestone.py
@@ -0,0 +1,331 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+
+ system_person = orm["person.Person"].objects.get(name="(System)")
+
+ for m in orm.GroupMilestone.objects.all():
+ if m.done:
+ m.resolved = "Done"
+ m.save()
+
+ orm.MilestoneGroupEvent.objects.get_or_create(
+ group_id=m.group_id,
+ type="changed_milestone",
+ time=datetime.datetime.combine(m.done_date, datetime.time(0, 0, 0)),
+ by=system_person,
+ desc='Changed milestone "%s", resolved as "%s"' % (m.desc, m.resolved),
+ milestone=m,
+ )
+
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+
+ 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.changestategroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'ChangeStateGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']"})
+ },
+ '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'})
+ },
+ 'group.groupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'GroupEvent'},
+ 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
+ 'desc': ('django.db.models.fields.TextField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'group.grouphistory': {
+ 'Meta': {'object_name': 'GroupHistory'},
+ 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
+ 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['group.Group']"}),
+ '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'})
+ },
+ 'group.groupmilestone': {
+ 'Meta': {'ordering': "['due', 'id']", 'object_name': 'GroupMilestone'},
+ 'desc': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'done': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'done_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'due': ('django.db.models.fields.DateField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'resolved': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupMilestoneStateName']"}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'group.groupstatetransitions': {
+ 'Meta': {'object_name': 'GroupStateTransitions'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'previous_groupstatetransitions_states'", 'symmetrical': 'False', 'to': "orm['doc.State']"}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.State']"})
+ },
+ 'group.groupurl': {
+ 'Meta': {'object_name': 'GroupURL'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'group.milestonegroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'MilestoneGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'milestone': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupMilestone']"})
+ },
+ 'group.role': {
+ 'Meta': {'object_name': 'Role'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ 'group.rolehistory': {
+ 'Meta': {'object_name': 'RoleHistory'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupHistory']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ '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.groupmilestonestatename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
+ '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.rolename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
+ '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'})
+ },
+ '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 = ['group']
diff --git a/ietf/group/migrations/0004_auto__del_field_groupmilestone_done_date__del_field_groupmilestone_don.py b/ietf/group/migrations/0004_auto__del_field_groupmilestone_done_date__del_field_groupmilestone_don.py
new file mode 100644
index 000000000..e08a26e94
--- /dev/null
+++ b/ietf/group/migrations/0004_auto__del_field_groupmilestone_done_date__del_field_groupmilestone_don.py
@@ -0,0 +1,322 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Deleting field 'GroupMilestone.done_date'
+ db.delete_column('group_groupmilestone', 'done_date')
+
+ # Deleting field 'GroupMilestone.done'
+ db.delete_column('group_groupmilestone', 'done')
+
+
+ def backwards(self, orm):
+
+ # Adding field 'GroupMilestone.done_date'
+ db.add_column('group_groupmilestone', 'done_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True), keep_default=False)
+
+ # Adding field 'GroupMilestone.done'
+ db.add_column('group_groupmilestone', 'done', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
+
+
+ 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.changestategroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'ChangeStateGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']"})
+ },
+ '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'})
+ },
+ 'group.groupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'GroupEvent'},
+ 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
+ 'desc': ('django.db.models.fields.TextField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'group.grouphistory': {
+ 'Meta': {'object_name': 'GroupHistory'},
+ 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
+ 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['group.Group']"}),
+ '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'})
+ },
+ 'group.groupmilestone': {
+ 'Meta': {'ordering': "['due', 'id']", 'object_name': 'GroupMilestone'},
+ 'desc': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'due': ('django.db.models.fields.DateField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'resolved': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupMilestoneStateName']"}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'group.groupstatetransitions': {
+ 'Meta': {'object_name': 'GroupStateTransitions'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'previous_groupstatetransitions_states'", 'symmetrical': 'False', 'to': "orm['doc.State']"}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.State']"})
+ },
+ 'group.groupurl': {
+ 'Meta': {'object_name': 'GroupURL'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'group.milestonegroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'MilestoneGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'milestone': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupMilestone']"})
+ },
+ 'group.role': {
+ 'Meta': {'object_name': 'Role'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ 'group.rolehistory': {
+ 'Meta': {'object_name': 'RoleHistory'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupHistory']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ '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.groupmilestonestatename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
+ '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.rolename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
+ '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'})
+ },
+ '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 = ['group']
diff --git a/ietf/group/migrations/0005_auto__add_groupmilestonehistory.py b/ietf/group/migrations/0005_auto__add_groupmilestonehistory.py
new file mode 100644
index 000000000..394e83cd3
--- /dev/null
+++ b/ietf/group/migrations/0005_auto__add_groupmilestonehistory.py
@@ -0,0 +1,349 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'GroupMilestoneHistory'
+ db.create_table('group_groupmilestonehistory', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group.Group'])),
+ ('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.GroupMilestoneStateName'])),
+ ('desc', self.gf('django.db.models.fields.CharField')(max_length=500)),
+ ('due', self.gf('django.db.models.fields.DateField')()),
+ ('resolved', self.gf('django.db.models.fields.CharField')(max_length=50, blank=True)),
+ ('time', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+ ('milestone', self.gf('django.db.models.fields.related.ForeignKey')(related_name='history_set', to=orm['group.GroupMilestone'])),
+ ))
+ db.send_create_signal('group', ['GroupMilestoneHistory'])
+
+ # Adding M2M table for field docs on 'GroupMilestoneHistory'
+ db.create_table('group_groupmilestonehistory_docs', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('groupmilestonehistory', models.ForeignKey(orm['group.groupmilestonehistory'], null=False)),
+ ('document', models.ForeignKey(orm['doc.document'], null=False))
+ ))
+ db.create_unique('group_groupmilestonehistory_docs', ['groupmilestonehistory_id', 'document_id'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'GroupMilestoneHistory'
+ db.delete_table('group_groupmilestonehistory')
+
+ # Removing M2M table for field docs on 'GroupMilestoneHistory'
+ db.delete_table('group_groupmilestonehistory_docs')
+
+
+ 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.changestategroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'ChangeStateGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']"})
+ },
+ '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'})
+ },
+ 'group.groupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'GroupEvent'},
+ 'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
+ 'desc': ('django.db.models.fields.TextField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'group.grouphistory': {
+ 'Meta': {'object_name': 'GroupHistory'},
+ 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
+ 'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['group.Group']"}),
+ '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'})
+ },
+ 'group.groupmilestone': {
+ 'Meta': {'ordering': "['due', 'id']", 'object_name': 'GroupMilestone'},
+ 'desc': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'due': ('django.db.models.fields.DateField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'resolved': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupMilestoneStateName']"}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'group.groupmilestonehistory': {
+ 'Meta': {'ordering': "['due', 'id']", 'object_name': 'GroupMilestoneHistory'},
+ 'desc': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'docs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'due': ('django.db.models.fields.DateField', [], {}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'milestone': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['group.GroupMilestone']"}),
+ 'resolved': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupMilestoneStateName']"}),
+ 'time': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+ },
+ 'group.groupstatetransitions': {
+ 'Meta': {'object_name': 'GroupStateTransitions'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'previous_groupstatetransitions_states'", 'symmetrical': 'False', 'to': "orm['doc.State']"}),
+ 'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.State']"})
+ },
+ 'group.groupurl': {
+ 'Meta': {'object_name': 'GroupURL'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'group.milestonegroupevent': {
+ 'Meta': {'ordering': "['-time', 'id']", 'object_name': 'MilestoneGroupEvent', '_ormbases': ['group.GroupEvent']},
+ 'groupevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['group.GroupEvent']", 'unique': 'True', 'primary_key': 'True'}),
+ 'milestone': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupMilestone']"})
+ },
+ 'group.role': {
+ 'Meta': {'object_name': 'Role'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ 'group.rolehistory': {
+ 'Meta': {'object_name': 'RoleHistory'},
+ 'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.GroupHistory']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.RoleName']"}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"})
+ },
+ '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.groupmilestonestatename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
+ '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.rolename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
+ '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'})
+ },
+ '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 = ['group']
diff --git a/ietf/group/migrations/__init__.py b/ietf/group/migrations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/ietf/group/models.py b/ietf/group/models.py
index 7546fd37b..8559b9931 100644
--- a/ietf/group/models.py
+++ b/ietf/group/models.py
@@ -66,17 +66,31 @@ class GroupURL(models.Model):
def __unicode__(self):
return u"%s (%s)" % (self.url, self.name)
-class GroupMilestone(models.Model):
+class GroupMilestoneInfo(models.Model):
group = models.ForeignKey(Group)
- desc = models.TextField(verbose_name="Description")
- expected_due_date = models.DateField()
- done = models.BooleanField()
- done_date = models.DateField(null=True, blank=True)
- time = models.DateTimeField(auto_now=True)
+ # a group has two sets of milestones, current milestones
+ # (active/under review/deleted) and charter milestones (active
+ # during a charter/recharter event), events for charter milestones
+ # are stored on the charter document
+ state = models.ForeignKey(GroupMilestoneStateName)
+ desc = models.CharField(verbose_name="Description", max_length=500)
+ due = models.DateField()
+ resolved = models.CharField(max_length=50, blank=True, help_text="Explanation of why milestone is resolved (usually \"Done\"), or empty if still due")
+
+ docs = models.ManyToManyField('doc.Document', blank=True)
+
def __unicode__(self):
return self.desc[:20] + "..."
class Meta:
- ordering = ['expected_due_date']
+ abstract = True
+ ordering = ['due', 'id']
+
+class GroupMilestone(GroupMilestoneInfo):
+ time = models.DateTimeField(auto_now=True)
+
+class GroupMilestoneHistory(GroupMilestoneInfo):
+ time = models.DateTimeField()
+ milestone = models.ForeignKey(GroupMilestone, related_name="history_set")
class GroupStateTransitions(models.Model):
"""Captures that a group has overriden the default available
@@ -93,6 +107,7 @@ GROUP_EVENT_CHOICES = [
("added_comment", "Added comment"),
("info_changed", "Changed metadata"),
("requested_close", "Requested closing group"),
+ ("changed_milestone", "Changed milestone"),
]
class GroupEvent(models.Model):
@@ -112,6 +127,9 @@ class GroupEvent(models.Model):
class ChangeStateGroupEvent(GroupEvent):
state = models.ForeignKey(GroupStateName)
+class MilestoneGroupEvent(GroupEvent):
+ milestone = models.ForeignKey(GroupMilestone)
+
class Role(models.Model):
name = models.ForeignKey(RoleName)
group = models.ForeignKey(Group)
diff --git a/ietf/group/utils.py b/ietf/group/utils.py
index 47f56a581..6eb1f5a6f 100644
--- a/ietf/group/utils.py
+++ b/ietf/group/utils.py
@@ -3,6 +3,7 @@ import os
from django.conf import settings
from ietf.group.models import *
+from ietf.utils.history import get_history_object_for, copy_many_to_many_for_history
def save_group_in_history(group):
@@ -11,30 +12,17 @@ def save_group_in_history(group):
the Group entry contain the current state. XXX TODO: Call this
directly from Group.save()
"""
- def get_model_fields_as_dict(obj):
- return dict((field.name, getattr(obj, field.name))
- for field in obj._meta.fields
- if field is not obj._meta.pk)
-
- # copy fields
- fields = get_model_fields_as_dict(group)
- del fields["charter"] # Charter is saved canonically on Group
- fields["group"] = group
-
- grouphist = GroupHistory(**fields)
- grouphist.save()
+ h = get_history_object_for(group)
+ h.save()
# save RoleHistory
for role in group.role_set.all():
- rh = RoleHistory(name=role.name, group=grouphist, email=role.email, person=role.person)
+ rh = RoleHistory(name=role.name, group=h, email=role.email, person=role.person)
rh.save()
- # copy many to many
- for field in group._meta.many_to_many:
- if field.rel.through and field.rel.through._meta.auto_created:
- setattr(grouphist, field.name, getattr(group, field.name).all())
+ copy_many_to_many_for_history(h, group)
- return grouphist
+ return h
def get_charter_text(group):
# get file path from settings. Syntesize file name from path, acronym, and suffix
@@ -60,3 +48,12 @@ def get_charter_text(group):
except BaseException:
desc = 'Error Loading Work Group Description'
return desc
+
+def save_milestone_in_history(milestone):
+ h = get_history_object_for(milestone)
+ h.milestone = milestone
+ h.save()
+
+ copy_many_to_many_for_history(h, milestone)
+
+ return h
diff --git a/ietf/idrfc/views_doc.py b/ietf/idrfc/views_doc.py
index a56b06a4d..8b5509bf9 100644
--- a/ietf/idrfc/views_doc.py
+++ b/ietf/idrfc/views_doc.py
@@ -150,10 +150,17 @@ def document_main(request, name, rev=None):
else:
ballot_summary = "No active ballot found."
+ chartering = get_chartering_type(doc)
+
+ # inject milestones from group
+ milestones = None
+ if chartering and not snapshot:
+ milestones = doc.group.groupmilestone_set.filter(state="charter")
+
return render_to_response("idrfc/document_charter.html",
dict(doc=doc,
top=top,
- chartering=get_chartering_type(doc),
+ chartering=chartering,
content=content,
txt_url=settings.CHARTER_TXT_URL + filename,
revisions=revisions,
@@ -161,6 +168,7 @@ def document_main(request, name, rev=None):
telechat=telechat,
ballot_summary=ballot_summary,
group=group,
+ milestones=milestones,
),
context_instance=RequestContext(request))
@@ -237,35 +245,36 @@ def document_history(request, name):
doc = get_object_or_404(Document, docalias__name=name)
top = render_document_top(request, doc, "history", name)
- diff_documents = [ doc ]
- diff_documents.extend(Document.objects.filter(docalias__relateddocument__source=doc, docalias__relateddocument__relationship="replaces"))
-
# pick up revisions from events
diff_revisions = []
- seen = set()
diffable = name.startswith("draft") or name.startswith("charter") or name.startswith("conflict-review") or name.startswith("status-change")
-
if diffable:
+ diff_documents = [ doc ]
+ diff_documents.extend(Document.objects.filter(docalias__relateddocument__source=doc, docalias__relateddocument__relationship="replaces"))
+
+ seen = set()
for e in NewRevisionDocEvent.objects.filter(type="new_revision", doc__in=diff_documents).select_related('doc').order_by("-time", "-id"):
- if not (e.doc.name, e.rev) in seen:
- seen.add((e.doc.name, e.rev))
+ if (e.doc.name, e.rev) in seen:
+ continue
- url = ""
- if name.startswith("charter"):
- h = find_history_active_at(e.doc, e.time)
- url = settings.CHARTER_TXT_URL + ("%s-%s.txt" % ((h or doc).canonical_name(), e.rev))
- elif name.startswith("conflict-review"):
- h = find_history_active_at(e.doc, e.time)
- url = settings.CONFLICT_REVIEW_TXT_URL + ("%s-%s.txt" % ((h or doc).canonical_name(), e.rev))
- elif name.startswith("status-change"):
- h = find_history_active_at(e.doc, e.time)
- url = settings.STATUS_CHANGE_TXT_URL + ("%s-%s.txt" % ((h or doc).canonical_name(), e.rev))
- elif name.startswith("draft"):
- # rfcdiff tool has special support for IDs
- url = e.doc.name + "-" + e.rev
+ seen.add((e.doc.name, e.rev))
- diff_revisions.append((e.doc.name, e.rev, e.time, url))
+ url = ""
+ if name.startswith("charter"):
+ h = find_history_active_at(e.doc, e.time)
+ url = settings.CHARTER_TXT_URL + ("%s-%s.txt" % ((h or doc).canonical_name(), e.rev))
+ elif name.startswith("conflict-review"):
+ h = find_history_active_at(e.doc, e.time)
+ url = settings.CONFLICT_REVIEW_TXT_URL + ("%s-%s.txt" % ((h or doc).canonical_name(), e.rev))
+ elif name.startswith("status-change"):
+ h = find_history_active_at(e.doc, e.time)
+ url = settings.STATUS_CHANGE_TXT_URL + ("%s-%s.txt" % ((h or doc).canonical_name(), e.rev))
+ elif name.startswith("draft"):
+ # rfcdiff tool has special support for IDs
+ url = e.doc.name + "-" + e.rev
+
+ diff_revisions.append((e.doc.name, e.rev, e.time, url))
# grab event history
events = doc.docevent_set.all().order_by("-time", "-id").select_related("by")
@@ -533,6 +542,7 @@ def document_main_idrfc(request, name, tab):
'doc':doc, 'info':info, 'tab':tab,
'include_text':include_text(request),
'stream_info': get_full_info_for_draft(id),
+ 'milestones': id.groupmilestone_set.filter(state="active"),
'versions':versions, 'history':history},
context_instance=RequestContext(request));
diff --git a/ietf/iesg/urls.py b/ietf/iesg/urls.py
index 3ec407096..aa6532e13 100644
--- a/ietf/iesg/urls.py
+++ b/ietf/iesg/urls.py
@@ -60,7 +60,8 @@ urlpatterns += patterns('',
(r'^agenda/documents/$', views.agenda_documents),
(r'^agenda/telechat-(?P\d+)-(?P\d+)-(?P\d+)-docs.tgz', views.telechat_docs_tarfile),
(r'^discusses/$', views.discusses),
- (r'^telechatdates/$', views.telechat_dates),
+ (r'^milestones', views.milestones_needing_review),
+ (r'^telechatdates/$', 'django.views.generic.simple.redirect_to', { 'url': '/admin/iesg/telechatdate/' }),
url(r'^wgactions/$', views.working_group_actions, name="iesg_working_group_actions"),
url(r'^wgactions/add/$', views.edit_working_group_action, { 'wga_id': None }, name="iesg_add_working_group_action"),
url(r'^wgactions/(?P\d+)/$', views.edit_working_group_action, name="iesg_edit_working_group_action"),
diff --git a/ietf/iesg/views.py b/ietf/iesg/views.py
index 3bde47bb2..ba06e0f2e 100644
--- a/ietf/iesg/views.py
+++ b/ietf/iesg/views.py
@@ -51,11 +51,11 @@ from ietf.iesg.models import TelechatDates, TelechatAgendaItem, WGAction
from ietf.idrfc.idrfc_wrapper import IdWrapper, RfcWrapper
from ietf.idrfc.models import RfcIndex
from ietf.idrfc.utils import update_telechat
-from ietf.ietfauth.decorators import group_required
+from ietf.ietfauth.decorators import group_required, role_required
from ietf.idtracker.templatetags.ietf_filters import in_group
from ietf.ipr.models import IprDocAlias
from ietf.doc.models import Document, TelechatDocEvent, LastCallDocEvent, ConsensusDocEvent
-from ietf.group.models import Group
+from ietf.group.models import Group, GroupMilestone
def date_threshold():
"""Return the first day of the month that is 185 days ago."""
@@ -663,43 +663,25 @@ def discusses(request):
return direct_to_template(request, 'iesg/discusses.html', {'docs':res})
-if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
- class TelechatDatesForm(forms.ModelForm):
- class Meta:
- model = TelechatDates
- fields = ['date1', 'date2', 'date3', 'date4']
+@role_required('Area Director', 'Secretariat')
+def milestones_needing_review(request):
+ # collect milestones, grouped on AD and group
+ ads = {}
+ for m in GroupMilestone.objects.filter(state="review").exclude(group__state="concluded", group__ad=None).distinct().select_related("group", "group__ad"):
+ groups = ads.setdefault(m.group.ad, {})
+ milestones = groups.setdefault(m.group, [])
+ milestones.append(m)
-@group_required('Secretariat')
-def telechat_dates(request):
- if settings.USE_DB_REDESIGN_PROXY_CLASSES:
- return HttpResponseRedirect("/admin/iesg/telechatdate/")
+ ad_list = []
+ for ad, groups in ads.iteritems():
+ ad_list.append(ad)
+ ad.groups_needing_review = sorted(groups, key=lambda g: g.acronym)
+ for g, milestones in groups.iteritems():
+ g.milestones_needing_review = sorted(milestones, key=lambda m: m.due)
- dates = TelechatDates.objects.all()[0]
-
- if request.method == 'POST':
- if request.POST.get('rollup_dates'):
- TelechatDates.objects.all().update(
- date1=dates.date2, date2=dates.date3, date3=dates.date4,
- date4=dates.date4 + datetime.timedelta(days=14))
- form = TelechatDatesForm(instance=dates)
- else:
- form = TelechatDatesForm(request.POST, instance=dates)
- if form.is_valid():
- form.save(commit=False)
- TelechatDates.objects.all().update(date1 = dates.date1,
- date2 = dates.date2,
- date3 = dates.date3,
- date4 = dates.date4)
- else:
- form = TelechatDatesForm(instance=dates)
-
- from django.contrib.humanize.templatetags import humanize
- for f in form.fields:
- form.fields[f].label = "Date " + humanize.ordinal(form.fields[f].label[4])
- form.fields[f].thursday = getattr(dates, f).isoweekday() == 4
-
- return render_to_response("iesg/telechat_dates.html",
- dict(form=form),
+ return render_to_response('iesg/milestones_needing_review.html',
+ dict(ads=sorted(ad_list, key=lambda ad: ad.plain_name()),
+ ),
context_instance=RequestContext(request))
def parse_wg_action_file(path):
diff --git a/ietf/ietfworkflows/templatetags/ietf_streams.py b/ietf/ietfworkflows/templatetags/ietf_streams.py
index 58dd0d8c7..f9e69803f 100644
--- a/ietf/ietfworkflows/templatetags/ietf_streams.py
+++ b/ietf/ietfworkflows/templatetags/ietf_streams.py
@@ -40,7 +40,9 @@ def stream_state(context, doc):
data.update({'workflow': workflow,
'draft': draft,
- 'state': state})
+ 'state': state,
+ 'milestones': draft.groupmilestone_set.filter(state="active")
+ })
return data
diff --git a/ietf/ietfworkflows/views.py b/ietf/ietfworkflows/views.py
index 62bc5ecd3..26dc6f859 100644
--- a/ietf/ietfworkflows/views.py
+++ b/ietf/ietfworkflows/views.py
@@ -83,6 +83,7 @@ def _edit_draft_stream(request, draft, form_class=DraftTagsStateForm):
stream = get_stream_from_draft(draft)
history = get_workflow_history_for_draft(draft, 'objectworkflowhistoryentry')
tags = get_annotation_tags_for_draft(draft)
+ milestones = draft.groupmilestone_set.all()
return render_to_response('ietfworkflows/state_edit.html',
{'draft': draft,
'state': state,
@@ -91,6 +92,7 @@ def _edit_draft_stream(request, draft, form_class=DraftTagsStateForm):
'history': history,
'tags': tags,
'form': form,
+ 'milestones': milestones,
},
context_instance=RequestContext(request))
diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py
index ce56ee96c..ecf1080d7 100644
--- a/ietf/meeting/views.py
+++ b/ietf/meeting/views.py
@@ -135,7 +135,7 @@ def agenda_infoREDESIGN(num=None):
meeting_time = datetime.datetime.combine(meeting.date, datetime.time(0, 0, 0))
for g in Group.objects.filter(type="area").order_by("acronym"):
history = find_history_active_at(g, meeting_time)
- if history:
+ if history and history != g:
if history.state_id == "active":
ads.extend(IESGHistory().from_role(x, meeting_time) for x in history.rolehistory_set.filter(name="ad").select_related())
else:
diff --git a/ietf/name/fixtures/names.xml b/ietf/name/fixtures/names.xml
index ab9895adf..592204e07 100644
--- a/ietf/name/fixtures/names.xml
+++ b/ietf/name/fixtures/names.xml
@@ -411,35 +411,29 @@
True
0
-
- No
+
+ Active
True
- 0
+ 1
-
- Yes
+
+ Deleted
True
- 0
+ 2
-
- Abstain
+
+ For review
True
- 0
+ 3
-
- Block
+
+ Chartering/rechartering
True
- 0
-
-
- No record
-
- True
- 0
+ 4
BOF
diff --git a/ietf/name/migrations/0008_auto__del_groupballotpositionname__add_groupmilestonestatename.py b/ietf/name/migrations/0008_auto__del_groupballotpositionname__add_groupmilestonestatename.py
new file mode 100644
index 000000000..8304ebfaa
--- /dev/null
+++ b/ietf/name/migrations/0008_auto__del_groupballotpositionname__add_groupmilestonestatename.py
@@ -0,0 +1,183 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Deleting model 'GroupBallotPositionName'
+ try:
+ db.delete_table('name_groupballotpositionname')
+ except Exception:
+ pass
+
+ # Adding model 'GroupMilestoneStateName'
+ db.create_table('name_groupmilestonestatename', (
+ ('slug', self.gf('django.db.models.fields.CharField')(max_length=8, primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('desc', self.gf('django.db.models.fields.TextField')(blank=True)),
+ ('used', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ))
+ db.send_create_signal('name', ['GroupMilestoneStateName'])
+
+ def backwards(self, orm):
+
+ # Adding model 'GroupBallotPositionName'
+ db.create_table('name_groupballotpositionname', (
+ ('used', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('slug', self.gf('django.db.models.fields.CharField')(max_length=8, primary_key=True)),
+ ('order', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('desc', self.gf('django.db.models.fields.TextField')(blank=True)),
+ ))
+ db.send_create_signal('name', ['GroupBallotPositionName'])
+
+ # Deleting model 'GroupMilestoneStateName'
+ db.delete_table('name_groupmilestonestatename')
+
+
+ models = {
+ 'name.ballotpositionname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'BallotPositionName'},
+ 'blocking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ '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.constraintname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
+ '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.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.docremindertypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'DocReminderTypeName'},
+ '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.groupmilestonestatename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
+ '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.liaisonstatementpurposename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'LiaisonStatementPurposeName'},
+ '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.meetingtypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
+ '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.rolename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
+ '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.sessionstatusname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
+ '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'})
+ },
+ 'name.timeslottypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
+ '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'})
+ }
+ }
+
+ complete_apps = ['name']
diff --git a/ietf/name/migrations/0009_add_groupmilestonestatenames.py b/ietf/name/migrations/0009_add_groupmilestonestatenames.py
new file mode 100644
index 000000000..323f20f7a
--- /dev/null
+++ b/ietf/name/migrations/0009_add_groupmilestonestatenames.py
@@ -0,0 +1,170 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ # add names
+ orm.GroupMilestoneStateName.objects.get_or_create(slug="active",
+ name="Active",
+ order=1)
+ orm.GroupMilestoneStateName.objects.get_or_create(slug="deleted",
+ name="Deleted",
+ order=2)
+ orm.GroupMilestoneStateName.objects.get_or_create(slug="review",
+ name="For review",
+ order=3)
+ orm.GroupMilestoneStateName.objects.get_or_create(slug="charter",
+ name="Chartering/rechartering",
+ order=4)
+
+
+ def backwards(self, orm):
+ # remove names
+ orm.GroupMilestoneStateName.objects.filter(slug__in=("active", "deleted", "review", "charter")).delete()
+
+
+ models = {
+ 'name.ballotpositionname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'BallotPositionName'},
+ 'blocking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ '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.constraintname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
+ '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.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.docremindertypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'DocReminderTypeName'},
+ '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.groupmilestonestatename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
+ '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.liaisonstatementpurposename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'LiaisonStatementPurposeName'},
+ '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.meetingtypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
+ '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.rolename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
+ '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.sessionstatusname': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
+ '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'})
+ },
+ 'name.timeslottypename': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
+ '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'})
+ }
+ }
+
+ complete_apps = ['name']
diff --git a/ietf/name/models.py b/ietf/name/models.py
index e3d1e8fce..a9e8bce8b 100644
--- a/ietf/name/models.py
+++ b/ietf/name/models.py
@@ -20,6 +20,8 @@ class GroupStateName(NameModel):
"""BOF, Proposed, Active, Dormant, Concluded, Abandoned"""
class GroupTypeName(NameModel):
"""IETF, Area, WG, RG, Team, etc."""
+class GroupMilestoneStateName(NameModel):
+ """Active, Deleted, For Review, Chartering"""
class RoleName(NameModel):
"""AD, Chair"""
class StreamName(NameModel):
@@ -47,8 +49,6 @@ class DocReminderTypeName(NameModel):
class BallotPositionName(NameModel):
""" Yes, No Objection, Abstain, Discuss, Block, Recuse """
blocking = models.BooleanField(default=False)
-class GroupBallotPositionName(NameModel):
- """ Yes, No, Block, Abstain """
class MeetingTypeName(NameModel):
"""IETF, Interim"""
class SessionStatusName(NameModel):
diff --git a/ietf/person/forms.py b/ietf/person/forms.py
index 46c80314c..bf68544f0 100644
--- a/ietf/person/forms.py
+++ b/ietf/person/forms.py
@@ -14,22 +14,30 @@ def json_emails(emails):
return simplejson.dumps([{"id": e.address + "", "name": escape(u"%s <%s>" % (e.person.name, e.address))} for e in emails])
class EmailsField(forms.CharField):
+ """Multi-select field using jquery.tokeninput.js. Since the API of
+ tokeninput" is asymmetric, we have to pass it a JSON
+ representation on the way out and parse the ids coming back as a
+ comma-separated list on the way in."""
+
def __init__(self, *args, **kwargs):
kwargs["max_length"] = 1000
if not "help_text" in kwargs:
kwargs["help_text"] = "Type in name to search for person"
super(EmailsField, self).__init__(*args, **kwargs)
- self.widget.attrs["class"] = "emails-field"
+ self.widget.attrs["class"] = "tokenized-field"
self.widget.attrs["data-ajax-url"] = lazy(urlreverse, str)("ajax_search_emails") # make this lazy to prevent initialization problem
+ def parse_tokenized_value(self, value):
+ return Email.objects.filter(address__in=[x.strip() for x in value.split(",") if x.strip()]).select_related("person")
+
def prepare_value(self, value):
if not value:
return ""
- if isinstance(value, str):
- return value
+ if isinstance(value, str) or isinstance(value, unicode):
+ value = self.parse_tokenized_value(value)
return json_emails(value)
def clean(self, value):
value = super(EmailsField, self).clean(value)
- return Email.objects.filter(address__in=[x.strip() for x in value.split(",") if x.strip()]).select_related("person")
+ return self.parse_tokenized_value(value)
diff --git a/ietf/person/models.py b/ietf/person/models.py
index cababcda8..d292019e5 100644
--- a/ietf/person/models.py
+++ b/ietf/person/models.py
@@ -107,8 +107,8 @@ class Email(models.Model):
return self.person.plain_name() if self.person else self.address
def formatted_email(self):
- if self.person and self.person.name:
- return u'"%s" <%s>' % (self.person.plain_name(), self.address)
+ if self.person and self.person.ascii:
+ return u'"%s" <%s>' % (self.person.ascii, self.address)
else:
return self.address
diff --git a/ietf/templates/base_leftmenu.html b/ietf/templates/base_leftmenu.html
index a06495e69..d4b0462ce 100644
--- a/ietf/templates/base_leftmenu.html
+++ b/ietf/templates/base_leftmenu.html
@@ -44,12 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
My Documents (new)
Next Telechat
Discusses
+ Milestones
+ {# FIXME: this link should be removed when the old WG Actions are completely dead #}
Working Groups
{% endif %}
{% if user|in_group:"Secretariat" %}
Secretariat
- Telechat Dates
+ Telechat Dates
Management Items
+ Milestones
+ {# FIXME: this link should be removed when the old WG Actions are completely dead #}
Working Groups
Sync discrepancies
{% endif %}
diff --git a/ietf/templates/idrfc/doc_tab_document_id.html b/ietf/templates/idrfc/doc_tab_document_id.html
index cbffffb65..83858fa25 100644
--- a/ietf/templates/idrfc/doc_tab_document_id.html
+++ b/ietf/templates/idrfc/doc_tab_document_id.html
@@ -99,9 +99,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% ifequal stream_info.stream.name "IETF" %}
IETF State:
- {{ stream_info.state.name }} ({{ stream_info.streamed.get_group }})
- {% if stream_info.tags %}{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %}
-
+ {{ stream_info.state.name }} ({{ stream_info.streamed.get_group }})
+ {% if stream_info.tags %}{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %} {% endif %}
+ {% if milestones %}{% for m in milestones %}{{ m.due|date:"M Y" }} {% endfor %}{% endif %}
+
{% else %}
{% if stream_info.stream %}
@@ -109,7 +110,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{{ stream_info.stream.name }} status:
{{ stream_info.state.name }} {% if stream_info.streamed.get_group %}({{ stream_info.streamed.get_group }}) {% endif %}
- {% if stream_info.tags %}{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %}
+ {% if stream_info.tags %}{% for tag in stream_info.tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %} {% endif %}
{% endif %}
diff --git a/ietf/templates/idrfc/document_charter.html b/ietf/templates/idrfc/document_charter.html
index b63680aba..5070cc851 100644
--- a/ietf/templates/idrfc/document_charter.html
+++ b/ietf/templates/idrfc/document_charter.html
@@ -47,7 +47,6 @@
{% if chartering == "initial" %} - (Initial Chartering){% endif %}
{% if chartering == "rechartering" %} - (Rechartering){% endif %}
-
{% if not snapshot and chartering %}
@@ -134,11 +133,25 @@
{% endif %}
-{% if doc.rev %}
+{% if doc.rev != "" %}
{{ content|safe|keep_spacing|sanitize_html|wordwrap:80|safe }}
{% endif %}
+{% if not snapshot and chartering %}
+Proposed Milestones
+{% if user|has_role:"Area Director,Secretariat" %}
+Edit charter milestones
+{% endif %}
+
+
+{% if milestones %}
+{% include "wginfo/milestones.html" %}
+{% else %}
+No milestones for charter found.
+{% endif %}
+{% endif %}
+
{% endblock %}
diff --git a/ietf/templates/iesg/milestones_needing_review.html b/ietf/templates/iesg/milestones_needing_review.html
new file mode 100644
index 000000000..f4c0b47d0
--- /dev/null
+++ b/ietf/templates/iesg/milestones_needing_review.html
@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+
+{% block title %}Milestones Needing Review{% endblock %}
+
+{% block morecss %}
+h3.ad { margin-bottom: 0.5em; }
+div.milestones-for-group { margin: 0.5em 0; }
+{% endblock %}
+
+{% block content %}
+Milestones Needing Review
+
+{% for ad in ads %}
+{{ ad.plain_name }}
+
+{% for g in ad.groups_needing_review %}
+
+
+
+{% with g.milestones_needing_review as milestones %}
+{% include "wginfo/milestones.html" %}
+{% endwith %}
+
+{% endfor %}
+{% endfor %}
+
+{% endblock %}
diff --git a/ietf/templates/iesg/telechat_dates.html b/ietf/templates/iesg/telechat_dates.html
deleted file mode 100644
index b3dcb4a46..000000000
--- a/ietf/templates/iesg/telechat_dates.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Manage Telechat Dates{% endblock %}
-
-{% block content %}
-Manage Telechat Dates
-
-
-{% endblock %}
diff --git a/ietf/templates/ietfworkflows/state_edit.html b/ietf/templates/ietfworkflows/state_edit.html
index b2c281fa4..19f0265a4 100644
--- a/ietf/templates/ietfworkflows/state_edit.html
+++ b/ietf/templates/ietfworkflows/state_edit.html
@@ -29,6 +29,19 @@ table.edit-form-tags ul li { padding: 0px; }
Return to document view
+
+{% if state and state.slug == "wg-doc" and not milestones %}
+This document is not part of any milestone. You may wish to add it to one .
+{% endif %}
+
+{% if state and state.slug == "sub-pub" and milestones %}
+This document is part of {% if milestones|length > 1 %}{{ milestones|length }}
+milestones{% else %}a milestone{% endif %}. Now that the draft is
+submitted to IESG for publication, you may wish to
+update the
+milestone{{ milestones|pluralize }} .
+{% endif %}
+
Current stream
diff --git a/ietf/templates/ietfworkflows/stream_state.html b/ietf/templates/ietfworkflows/stream_state.html
index fa7d02234..d06c4ac1e 100644
--- a/ietf/templates/ietfworkflows/stream_state.html
+++ b/ietf/templates/ietfworkflows/stream_state.html
@@ -3,6 +3,7 @@
{% if stream %}
{% if state %}{{ state.name }}{% else %}{{ stream }}{% endif %}
+{% if milestones %}{% for m in milestones %}{{ m.due|date:"M Y" }} {% endfor %}{% endif %}
{% else %}
No stream assigned
{% endif %}
diff --git a/ietf/templates/wgcharter/action_text.txt b/ietf/templates/wgcharter/action_text.txt
index 30f7435de..bee83bc6c 100644
--- a/ietf/templates/wgcharter/action_text.txt
+++ b/ietf/templates/wgcharter/action_text.txt
@@ -1,8 +1,8 @@
{% load ietf_filters %}{% autoescape off %}From: The IESG
-To: IETF-Announce {% if wg.list_email %}
-Cc: {{ wg.acronym }} WG <{{ wg.list_email }}> {% endif %}
-Subject: WG Action: {{ action_type }} {{ wg.name }} ({{ wg.acronym }})
+To: IETF-Announce {% if group.list_email %}
+Cc: {{ group.acronym }} {{ group.type.name }} <{{ group.list_email }}> {% endif %}
+Subject: WG Action: {{ action_type }} {{ group.name }} ({{ group.acronym }})
-{% filter wordwrap:73 %}{% ifequal action_type "Formed" %}A new IETF working group has been formed in the {{ wg.parent.name }}.{% endifequal %}{% ifequal action_type "Rechartered" %}The {{ wg.name }} ({{ wg.acronym }}) working group in the {{ wg.parent.name }} of the IETF has been rechartered.{% endifequal %} For additional information please contact the Area Directors or the WG Chair{{ chairs|pluralize}}.
+{% filter wordwrap:73 %}{% ifequal action_type "Formed" %}A new IETF working group has been formed in the {{ group.parent.name }}.{% endifequal %}{% ifequal action_type "Rechartered" %}The {{ group.name }} ({{ group.acronym }}) working group in the {{ group.parent.name }} of the IETF has been rechartered.{% endifequal %} For additional information please contact the Area Directors or the {{ group.type.name }} Chair{{ chairs|pluralize}}.
-{% include "wgcharter/wg_info.txt" %}{% endfilter %}{% endautoescape %}
+{% include "wgcharter/group_info.txt" %}{% endfilter %}{% endautoescape %}
diff --git a/ietf/templates/wgcharter/charter_with_milestones.txt b/ietf/templates/wgcharter/charter_with_milestones.txt
new file mode 100644
index 000000000..cfa74b052
--- /dev/null
+++ b/ietf/templates/wgcharter/charter_with_milestones.txt
@@ -0,0 +1,8 @@
+{% load ietf_filters %}{% autoescape off %}{% filter wrap_long_lines %}{{ charter_text }}{% endfilter %}
+
+Milestones
+
+{% for milestone in milestones %}{% if milestone.resolved %}{{ milestone.resolved|ljust:8 }}{% else %}{{ milestone.due|date:"M Y" }}{% endif %} - {{ milestone.desc_filled }}{% for d in milestone.docs.all %}
+ o {{ d.name }}{% endfor %}
+
+{% endfor %}{% endautoescape %}
diff --git a/ietf/templates/wgcharter/email_secretariat.txt b/ietf/templates/wgcharter/email_secretariat.txt
index 140714df6..4b8480fe7 100644
--- a/ietf/templates/wgcharter/email_secretariat.txt
+++ b/ietf/templates/wgcharter/email_secretariat.txt
@@ -1,6 +1,6 @@
{% load ietf_filters %}{% autoescape off %}
{{ text|fill:70 }}
-WG: {{ wg_url }}
+{{ group.type.name}}: {{ group_url }}
Charter: {{ charter_url }}
{% endautoescape %}
diff --git a/ietf/templates/wgcharter/group_info.txt b/ietf/templates/wgcharter/group_info.txt
new file mode 100644
index 000000000..4d21461ec
--- /dev/null
+++ b/ietf/templates/wgcharter/group_info.txt
@@ -0,0 +1,28 @@
+{{ group.name }} ({{ group.acronym }})
+------------------------------------------------
+Current Status: {{ group.state.name }} {{ group.type.name }}
+
+{% if chairs %}Chairs:
+{% for r in chairs %} {{ r.person.plain_name }} <{{r.email.address}}>
+{% endfor %}
+{% endif %}{% if secr %}Secretaries:
+{% for r in secr %} {{ r.person.plain_name }} <{{r.email.address}}>
+{% endfor %}
+{% endif %}{% if techadv %}Technical advisors:
+{% for r in techadv %} {{ r.person.plain_name }} <{{r.email.address}}>
+{% endfor %}
+{% endif %}{% if group.ad %}Assigned Area Director:
+ {{ group.ad.plain_name }} <{{ ad_email }}>
+
+{% endif %}{% if group.list_email %}Mailing list
+ Address: {{ group.list_email }}
+ To Subscribe: {{ group.list_subscribe }}
+ Archive: {{ group.list_archive }}
+{% endif %}
+Charter:
+
+{{ charter_text }}
+
+Milestones:
+{% for milestone in milestones %} {% if milestone.resolved %}{{ milestone.resolved }} {% else %}{{ milestone.due|date:"M Y" }}{% endif %} - {{ milestone.desc|safe }}
+{% endfor %}
diff --git a/ietf/templates/wgcharter/review_text.txt b/ietf/templates/wgcharter/review_text.txt
index a683516e9..de8c83c28 100644
--- a/ietf/templates/wgcharter/review_text.txt
+++ b/ietf/templates/wgcharter/review_text.txt
@@ -1,8 +1,8 @@
{% load ietf_filters %}{% autoescape off %}From: The IESG
-To: IETF-Announce {% if wg.list_email %}
-Cc: {{ wg.acronym }} WG <{{ wg.list_email }}> {% endif %}
-Subject: WG Review: {{ wg.name }} ({{ wg.acronym }})
+To: IETF-Announce {% if group.list_email %}
+Cc: {{ group.acronym }} {{ group.type.name }} <{{ group.list_email }}> {% endif %}
+Subject: WG Review: {{ group.name }} ({{ group.acronym }})
-{% filter wordwrap:73 %}{% ifequal review_type "new" %}A new IETF working group has been proposed in the {{ wg.parent.name }}.{% endifequal %}{% ifequal review_type "recharter" %}The {{ wg.name }} ({{wg.acronym}}) working group in the {{ wg.parent.name }} of the IETF is undergoing rechartering.{% endifequal %} The IESG has not made any determination yet. The following draft charter was submitted, and is provided for informational purposes only. Please send your comments to the IESG mailing list (iesg at ietf.org) by {{ review_date }}.
+{% filter wordwrap:73 %}{% ifequal review_type "new" %}A new IETF working group has been proposed in the {{ group.parent.name }}.{% endifequal %}{% ifequal review_type "recharter" %}The {{ group.name }} ({{group.acronym}}) working group in the {{ group.parent.name }} of the IETF is undergoing rechartering.{% endifequal %} The IESG has not made any determination yet. The following draft charter was submitted, and is provided for informational purposes only. Please send your comments to the IESG mailing list (iesg at ietf.org) by {{ review_date }}.
-{% include "wgcharter/wg_info.txt" %}{% endfilter %}{% endautoescape %}
+{% include "wgcharter/group_info.txt" %}{% endfilter %}{% endautoescape %}
diff --git a/ietf/templates/wgcharter/search_result_row.html b/ietf/templates/wgcharter/search_result_row.html
deleted file mode 100644
index babfb2343..000000000
--- a/ietf/templates/wgcharter/search_result_row.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% comment %}
-Copyright The IETF Trust 2011, All Rights Reserved
-{% endcomment %}
-
-{% load ietf_filters %}
-
-
-{{ wg.acronym|safe }}
-
-{{ wg.name }}
-{% include "wgcharter/date_column.html" %}
-{% include "wgcharter/status_columns.html" %}
-
diff --git a/ietf/templates/wgcharter/submit.html b/ietf/templates/wgcharter/submit.html
index 9646d452a..8cae45f6b 100644
--- a/ietf/templates/wgcharter/submit.html
+++ b/ietf/templates/wgcharter/submit.html
@@ -8,13 +8,13 @@ form #id_content {
{% endblock %}
{% block title %}
-Charter submission for {{ wg.acronym }}
+Charter submission for {{ group.acronym }} {{ group.type.name }}
{% endblock %}
{% block content %}
-Charter submission for {{ wg.acronym }}
+Charter submission for {{ group.acronym }} {{ group.type.name }}
-The text will be submitted as charter-ietf-{{ wg.acronym }}-{{ next_rev }}
+The text will be submitted as charter-ietf-{{ group.acronym }}-{{ next_rev }}