* Added a document type for changing the publication status of other documents, and the UI for manipulating them.

* Added charters, conflict reviews, and status changes to the AD's "My Documents" page
* Improved the presentation of all document types on the Agenda, Future Telechats, Scribe and Moderator package pages
* Made the reverse name for document relationships explicit rather than deriving them from forward names
* Added a way to get to the underlying Document (when it exists) from an RfcWrapper
* Unified several common forms used by different document types
 - Legacy-Id: 5476
This commit is contained in:
Robert Sparks 2013-03-01 15:47:51 +00:00
commit 10b4f7a4dc
50 changed files with 3398 additions and 427 deletions

37
ietf/doc/forms.py Normal file
View file

@ -0,0 +1,37 @@
import datetime
from django import forms
from ietf.iesg.models import TelechatDate
class TelechatForm(forms.Form):
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False)
returning_item = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
dates = [d.date for d in TelechatDate.objects.active().order_by('date')]
init = kwargs['initial'].get("telechat_date")
if init and init not in dates:
dates.insert(0, init)
self.fields['telechat_date'].choices = [("", "(not on agenda)")] + [(d, d.strftime("%Y-%m-%d")) for d in dates]
from ietf.person.models import Person
class AdForm(forms.Form):
ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active").order_by('name'),
label="Shepherding AD", empty_label="(None)", required=True)
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
# if previous AD is now ex-AD, append that person to the list
ad_pk = self.initial.get('ad')
choices = self.fields['ad'].choices
if ad_pk and ad_pk not in [pk for pk, name in choices]:
self.fields['ad'].choices = list(choices) + [("", "-------"), (ad_pk, Person.objects.get(pk=ad_pk).plain_name())]
class NotifyForm(forms.Form):
notify = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)

View file

@ -0,0 +1,427 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
from ietf.doc.models import StateType, State, BallotType, DocTypeName
from ietf.name.models import BallotPositionName
class Migration(DataMigration):
def forwards(self, orm):
statchg = StateType(slug='statchg',label='RFC Status Change')
statchg.save()
needshep = State(
type=statchg,slug="needshep",
name="Needs Shepherd",used=True,order=1,
desc="An RFC status change has been requested, but a shepherding AD has not yet been assigned")
needshep.save()
adrev = State(
type=statchg,slug="adrev",
name="AD Review",used=True,order=2,
desc="The sponsoring AD is preparing an RFC status change document")
adrev.save()
iesgeval = State(
type=statchg,slug="iesgeval",
name="IESG Evaluation",used=True,order=3,
desc="The IESG is considering the proposed RFC status changes")
iesgeval.save()
defer = State(
type=statchg,slug="defer",
name="IESG Evaluation - Defer",used=True, order=4,
desc="The evaluation of the proposed RFC status changes have been deferred to the next telechat")
defer.save()
appr_pr = State(
type=statchg,slug="appr-pr",
name="Approved - point raised", used=True,order=5,
desc="The IESG has approved the RFC status changes, but a point has been raised that should be cleared before proceeding to announcement to be sent")
appr_pr.save()
appr_pend = State(
type=statchg,slug="appr-pend",
name="Approved - announcement to be sent", used=True,order=6,
desc="The IESG has approved the RFC status changes, but the secretariat has not yet sent the announcement")
appr_pend.save()
appr_sent = State(
type=statchg,slug="appr-sent",
name="Approved - announcement sent",used=True,order=7,
desc="The secretariat has announced the IESG's approved RFC status changes")
appr_sent.save()
withdraw = State(
type=statchg,slug="withdraw",
name="Withdrawn",used=True,order=8,
desc="The request for RFC status changes was withdrawn")
withdraw.save()
dead = State(
type=statchg,slug="dead",
name="Dead",used=True,order=9,
desc="The RFC status changes have been abandoned")
dead.save()
needshep.next_states.add(adrev,withdraw,dead)
needshep.save()
adrev.next_states.add(iesgeval,withdraw,dead)
adrev.save()
iesgeval.next_states.add(appr_pr,appr_pend,defer,withdraw,dead)
iesgeval.save()
defer.next_states.add(iesgeval,appr_pend,appr_pr,withdraw,dead)
defer.save()
appr_pend.next_states.add(appr_sent,withdraw)
appr_pend.save()
withdraw.next_states.add(needshep)
withdraw.save()
dead.next_states.add(needshep)
dead.save()
statchg_ballot = BallotType(doc_type=DocTypeName.objects.get(slug='statchg'),
slug='statchg',name="Approve",used=True,
question="Do we approve these RFC status changes?")
statchg_ballot.save()
statchg_ballot.positions.add('yes','noobj','discuss','abstain','recuse','norecord')
statchg_ballot.save()
def backwards(self, orm):
StateType.objects.filter(slug='statchg').delete()
StateType.objects.filter(slug='statchg').delete()
BallotType.objects.filter(slug='statchg').delete()
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.ballotdocevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'BallotDocEvent', '_ormbases': ['doc.DocEvent']},
'ballot_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.BallotType']"}),
'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'})
},
'doc.ballotpositiondocevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'BallotPositionDocEvent', '_ormbases': ['doc.DocEvent']},
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'ballot': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['doc.BallotDocEvent']", 'null': 'True'}),
'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'comment_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'discuss': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'discuss_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}),
'pos': ('django.db.models.fields.related.ForeignKey', [], {'default': "'norecord'", 'to': "orm['name.BallotPositionName']"})
},
'doc.ballottype': {
'Meta': {'ordering': "['order']", 'object_name': 'BallotType'},
'doc_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'positions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.BallotPositionName']", 'symmetrical': 'False', 'blank': 'True'}),
'question': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'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.docevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'DocEvent'},
'by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'desc': ('django.db.models.fields.TextField', [], {}),
'doc': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
'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'})
},
'doc.dochistory': {
'Meta': {'object_name': 'DocHistory'},
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_dochistory_set'", 'null': 'True', 'to': "orm['person.Person']"}),
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocHistoryAuthor']", 'blank': 'True'}),
'doc': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'history_set'", 'to': "orm['doc.Document']"}),
'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'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': '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'}),
'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', [], {'to': "orm['doc.DocAlias']", 'symmetrical': 'False', 'through': "orm['doc.RelatedDocHistory']", 'blank': 'True'}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_dochistory_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.dochistoryauthor': {
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocHistoryAuthor'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocHistory']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {})
},
'doc.docreminder': {
'Meta': {'object_name': 'DocReminder'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'due': ('django.db.models.fields.DateTimeField', [], {}),
'event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocEvent']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocReminderTypeName']"})
},
'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.initialreviewdocevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'InitialReviewDocEvent', '_ormbases': ['doc.DocEvent']},
'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
},
'doc.lastcalldocevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'LastCallDocEvent', '_ormbases': ['doc.DocEvent']},
'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
},
'doc.newrevisiondocevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'NewRevisionDocEvent', '_ormbases': ['doc.DocEvent']},
'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16'})
},
'doc.relateddochistory': {
'Meta': {'object_name': 'RelatedDocHistory'},
'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.DocHistory']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reversely_related_document_history_set'", 'to': "orm['doc.DocAlias']"})
},
'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'})
},
'doc.telechatdocevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'TelechatDocEvent', '_ormbases': ['doc.DocEvent']},
'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}),
'returning_item': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'telechat_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
},
'doc.writeupdocevent': {
'Meta': {'ordering': "['-time', '-id']", 'object_name': 'WriteupDocEvent', '_ormbases': ['doc.DocEvent']},
'docevent_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['doc.DocEvent']", 'unique': 'True', 'primary_key': 'True'}),
'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
},
'group.group': {
'Meta': {'object_name': 'Group'},
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': "orm['doc.Document']"}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}),
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
},
'name.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.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.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'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 = ['doc']

View file

@ -150,8 +150,7 @@ class RelatedDocument(models.Model):
def action(self):
return self.relationship.name
def inverse_action():
infinitive = self.relationship.name[:-1]
return u"%sd by" % infinitive
return self.relationship.revname
def __unicode__(self):
return u"%s %s %s" % (self.source.name, self.relationship.name.lower(), self.target.name)
@ -306,7 +305,8 @@ class Document(DocumentInfo):
iesg_state_summary = iesg_state_summary + "::"+"::".join(tag.name for tag in iesg_substate)
if self.get_state_slug() == "rfc":
return "<a href=\"%s\">RFC %d</a>" % (urlreverse('doc_view', args=['rfc%d' % self.rfc_number]), self.rfc_number)
#return "<a href=\"%s\">RFC %d</a>" % (urlreverse('doc_view', args=['rfc%d' % int(self.rfc_number())]), int(self.rfc_number()))
return "RFC %d (%s)" % (int(self.rfc_number()), self.std_level)
elif self.get_state_slug() == "repl":
rs = self.replaced_by()
if rs:

View file

@ -1,3 +1,4 @@
from ietf.doc.tests_conflict_review import *
from ietf.doc.tests_status_change import *

View file

@ -0,0 +1,392 @@
import os
import shutil
from pyquery import PyQuery
from StringIO import StringIO
from textwrap import wrap
import django.test
from django.conf import settings
from django.core.urlresolvers import reverse as urlreverse
from ietf.utils.test_utils import login_testing_unauthorized
from ietf.utils.test_data import make_test_data
from ietf.utils.mail import outbox
from ietf.doc.utils import create_ballot_if_not_open
from ietf.doc.views_status_change import default_approval_text
from ietf.doc.models import Document,DocEvent,NewRevisionDocEvent,BallotPositionDocEvent,TelechatDocEvent,DocAlias,State
from ietf.name.models import StreamName
from ietf.group.models import Person
from ietf.iesg.models import TelechatDate
class StatusChangeTestCase(django.test.TestCase):
fixtures = ['names']
def test_start_review(self):
url = urlreverse('start_rfc_status_change',kwargs=dict(name=""))
login_testing_unauthorized(self, "secretary", url)
# normal get should succeed and get a reasonable form
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('form select[name=create_in_state]')),1)
ad_strpk = str(Person.objects.get(name='Aread Irector').pk)
state_strpk = str(State.objects.get(slug='adrev',type__slug='statchg').pk)
# faulty posts
## Must set a responsible AD
r = self.client.post(url,dict(document_name="bogus",title="Bogus Title",ad="",create_in_state=state_strpk,notify='ipu@ietf.org'))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
## Must set a name
r = self.client.post(url,dict(document_name="",title="Bogus Title",ad=ad_strpk,create_in_state=state_strpk,notify='ipu@ietf.org'))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
## Must not choose a document name that already exists
r = self.client.post(url,dict(document_name="imaginary-mid-review",title="Bogus Title",ad=ad_strpk,create_in_state=state_strpk,notify='ipu@ietf.org'))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
## Must set a title
r = self.client.post(url,dict(document_name="bogus",title="",ad=ad_strpk,create_in_state=state_strpk,notify='ipu@ietf.org'))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
# successful status change start
r = self.client.post(url,dict(document_name="imaginary-new",title="A new imaginary status change",ad=ad_strpk,
create_in_state=state_strpk,notify='ipu@ietf.org',new_relation_row_blah="rfc9999",
statchg_relation_row_blah="tois"))
self.assertEquals(r.status_code, 302)
status_change = Document.objects.get(name='status-change-imaginary-new')
self.assertEquals(status_change.get_state('statchg').slug,'adrev')
self.assertEquals(status_change.rev,u'00')
self.assertEquals(status_change.ad.name,u'Aread Irector')
self.assertEquals(status_change.notify,u'ipu@ietf.org')
self.assertTrue(status_change.relateddocument_set.filter(relationship__slug='tois',target__document__name='draft-ietf-random-thing'))
def test_change_state(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_change_state',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('form select[name=new_state]')),1)
# faulty post
r = self.client.post(url,dict(new_state=""))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
# successful change to AD Review
adrev_pk = str(State.objects.get(slug='adrev',type__slug='statchg').pk)
r = self.client.post(url,dict(new_state=adrev_pk,comment='RDNK84ZD'))
self.assertEquals(r.status_code, 302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.get_state('statchg').slug,'adrev')
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('RDNK84ZD'))
self.assertFalse(doc.active_ballot())
# successful change to IESG Evaluation
iesgeval_pk = str(State.objects.get(slug='iesgeval',type__slug='statchg').pk)
r = self.client.post(url,dict(new_state=iesgeval_pk,comment='TGmZtEjt'))
self.assertEquals(r.status_code, 302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.get_state('statchg').slug,'iesgeval')
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('TGmZtEjt'))
self.assertTrue(doc.active_ballot())
self.assertEquals(doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position").pos_id,'yes')
def test_edit_notices(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_notices',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('form input[name=notify]')),1)
self.assertEquals(doc.notify,q('form input[name=notify]')[0].value)
# change notice list
newlist = '"Foo Bar" <foo@bar.baz.com>'
r = self.client.post(url,dict(notify=newlist))
self.assertEquals(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.notify,newlist)
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('Notification list changed'))
def test_edit_ad(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_ad',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('select[name=ad]')),1)
# change ads
ad2 = Person.objects.get(name='Ad No2')
r = self.client.post(url,dict(ad=str(ad2.pk)))
self.assertEquals(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.ad,ad2)
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('Shepherding AD changed'))
def test_edit_telechat_date(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_telechat_date',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('select[name=telechat_date]')),1)
# set a date
self.assertFalse(doc.latest_event(TelechatDocEvent, "scheduled_for_telechat"))
telechat_date = TelechatDate.objects.active().order_by('date')[0].date
r = self.client.post(url,dict(telechat_date=telechat_date.isoformat()))
self.assertEquals(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.latest_event(TelechatDocEvent, "scheduled_for_telechat").telechat_date,telechat_date)
# move it forward a telechat (this should set the returning item bit)
telechat_date = TelechatDate.objects.active().order_by('date')[1].date
r = self.client.post(url,dict(telechat_date=telechat_date.isoformat()))
self.assertEquals(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertTrue(doc.returning_item())
# clear the returning item bit
r = self.client.post(url,dict(telechat_date=telechat_date.isoformat()))
self.assertEquals(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertFalse(doc.returning_item())
# set the returning item bit without changing the date
r = self.client.post(url,dict(telechat_date=telechat_date.isoformat(),returning_item="on"))
self.assertEquals(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertTrue(doc.returning_item())
# Take the doc back off any telechat
r = self.client.post(url,dict(telechat_date=""))
self.assertEquals(r.status_code, 302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.latest_event(TelechatDocEvent, "scheduled_for_telechat").telechat_date,None)
def test_approve(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_approve',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "secretary", url)
# Some additional setup
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
create_ballot_if_not_open(doc,Person.objects.get(name="Sec Retary"),"statchg")
doc.set_state(State.objects.get(slug='appr-pend',type='statchg'))
doc.save()
# get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('form.approve')),1)
# There should be two messages to edit
self.assertEquals(q('input#id_form-TOTAL_FORMS').val(),'2')
self.assertTrue( '(rfc9999) to Internet Standard' in ''.join(wrap(r.content,2**16)))
self.assertTrue( '(rfc9998) to Historic' in ''.join(wrap(r.content,2**16)))
# submit
messages_before = len(outbox)
msg0=default_approval_text(doc,doc.relateddocument_set.all()[0])
msg1=default_approval_text(doc,doc.relateddocument_set.all()[1])
r = self.client.post(url,{'form-0-announcement_text':msg0,'form-1-announcement_text':msg1,'form-TOTAL_FORMS':'2','form-INITIAL_FORMS':'2','form-MAX_NUM_FORMS':''})
self.assertEquals(r.status_code, 302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.get_state_slug(),'appr-sent')
self.assertFalse(doc.ballot_open("statchg"))
self.assertEquals(len(outbox), messages_before + 2)
self.assertTrue('Action:' in outbox[-1]['Subject'])
self.assertTrue('(rfc9999) to Internet Standard' in ''.join(wrap(unicode(outbox[-1])+unicode(outbox[-2]),2**16)))
self.assertTrue('(rfc9998) to Historic' in ''.join(wrap(unicode(outbox[-1])+unicode(outbox[-2]),2**16)))
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('The following approval message was sent'))
def test_edit_relations(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_relations',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "secretary", url)
# Some additional setup
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
# get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('form.edit-status-change-rfcs')),1)
# There should be three rows on the form
self.assertEquals(len(q('tr[id^=relation_row]')),3)
# Try to add a relation to an RFC that doesn't exist
r = self.client.post(url,dict(new_relation_row_blah="rfc9997",
statchg_relation_row_blah="tois"))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
# Try to add a relation leaving the relation type blank
r = self.client.post(url,dict(new_relation_row_blah="rfc9999",
statchg_relation_row_blah=""))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
# Try to add a relation with an unknown relationship type
r = self.client.post(url,dict(new_relation_row_blah="rfc9999",
statchg_relation_row_blah="badslug"))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
# Successful change of relations
r = self.client.post(url,dict(new_relation_row_blah="rfc9999",
statchg_relation_row_blah="toexp",
new_relation_row_foo="rfc9998",
statchg_relation_row_foo="tobcp"))
self.assertEquals(r.status_code, 302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.relateddocument_set.count(),2)
verify9999 = doc.relateddocument_set.filter(target__name='rfc9999')
self.assertTrue(verify9999)
self.assertEquals(verify9999.count(),1)
self.assertEquals(verify9999[0].relationship.slug,'toexp')
verify9998 = doc.relateddocument_set.filter(target__name='rfc9998')
self.assertTrue(verify9998)
self.assertEquals(verify9998.count(),1)
self.assertEquals(verify9998[0].relationship.slug,'tobcp')
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('Affected RFC list changed.'))
def setUp(self):
make_test_data()
class StatusChangeSubmitTestCase(django.test.TestCase):
fixtures = ['names']
def test_initial_submission(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_submit',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code,200)
q = PyQuery(r.content)
self.assertTrue(q('textarea')[0].text.startswith("Provide a description"))
# Faulty posts using textbox
# Right now, nothing to test - we let people put whatever the web browser will let them put into that textbox
# sane post using textbox
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
self.assertEquals(doc.rev,u'00')
self.assertFalse(os.path.exists(path))
r = self.client.post(url,dict(content="Some initial review text\n",submit_response="1"))
self.assertEquals(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.rev,u'00')
with open(path) as f:
self.assertEquals(f.read(),"Some initial review text\n")
f.close()
self.assertTrue( "mid-review-00" in doc.latest_event(NewRevisionDocEvent).desc)
def test_subsequent_submission(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('status_change_submit',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# A little additional setup
# doc.rev is u'00' per the test setup - double-checking that here - if it fails, the breakage is in setUp
self.assertEquals(doc.rev,u'00')
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
with open(path,'w') as f:
f.write('This is the old proposal.')
f.close()
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code,200)
q = PyQuery(r.content)
self.assertTrue(q('textarea')[0].text.startswith("This is the old proposal."))
# faulty posts trying to use file upload
# Copied from wgtracker tests - is this really testing the server code, or is it testing
# how client.post populates Content-Type?
test_file = StringIO("\x10\x11\x12") # post binary file
test_file.name = "unnamed"
r = self.client.post(url, dict(txt=test_file,submit_response="1"))
self.assertEquals(r.status_code, 200)
self.assertTrue("does not appear to be a text file" in r.content)
# sane post uploading a file
test_file = StringIO("This is a new proposal.")
test_file.name = "unnamed"
r = self.client.post(url,dict(txt=test_file,submit_response="1"))
self.assertEquals(r.status_code, 302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEquals(doc.rev,u'01')
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
with open(path) as f:
self.assertEquals(f.read(),"This is a new proposal.")
f.close()
self.assertTrue( "mid-review-01" in doc.latest_event(NewRevisionDocEvent).desc)
# verify reset text button works
r = self.client.post(url,dict(reset_text="1"))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(q('textarea')[0].text.startswith("Provide a description"))
def setUp(self):
make_test_data()
self.test_dir = os.path.abspath("tmp-status-change-testdir")
os.mkdir(self.test_dir)
settings.STATUS_CHANGE_PATH = self.test_dir
def tearDown(self):
shutil.rmtree(self.test_dir)

View file

@ -0,0 +1,12 @@
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('ietf.doc.views_status_change',
url(r'^state/$', "change_state", name='status_change_change_state'),
url(r'^submit/$', "submit", name='status_change_submit'),
url(r'^notices/$', "edit_notices", name='status_change_notices'),
url(r'^ad/$', "edit_ad", name='status_change_ad'),
url(r'^approve/$', "approve", name='status_change_approve'),
url(r'^telechat/$', "telechat_date", name='status_change_telechat_date'),
url(r'^relations/$', "edit_relations", name='status_change_relations'),
)

View file

@ -25,20 +25,15 @@ from ietf.person.models import Person
from ietf.iesg.models import TelechatDate
from ietf.group.models import Role, Group
from ietf.doc.forms import TelechatForm, AdForm, NotifyForm
class ChangeStateForm(forms.Form):
review_state = forms.ModelChoiceField(State.objects.filter(type="conflrev", used=True), label="Conflict review state", empty_label=None, required=True)
comment = forms.CharField(widget=forms.Textarea, help_text="Optional comment for the review history", required=False)
def __init__(self, *args, **kwargs):
self.hide = kwargs.pop('hide', None)
super(ChangeStateForm, self).__init__(*args, **kwargs)
# hide requested fields
if self.hide:
for f in self.hide:
self.fields[f].widget = forms.HiddenInput
@role_required("Area Director", "Secretariat")
def change_state(request, name, option=None):
"""Change state of and IESG review for IETF conflicts in other stream's documents, notifying parties as necessary
"""Change state of an IESG review for IETF conflicts in other stream's documents, notifying parties as necessary
and logging the change as a comment."""
review = get_object_or_404(Document, type="conflrev", name=name)
@ -86,22 +81,22 @@ def change_state(request, name, option=None):
return redirect('doc_view', name=review.name)
else:
hide = []
s = review.get_state()
init = dict(review_state=s.pk if s else None)
form = ChangeStateForm(hide=hide, initial=init)
form = ChangeStateForm(initial=init)
return render_to_response('doc/conflict_review/change_state.html',
return render_to_response('doc/change_state.html',
dict(form=form,
doc=review,
login=login,
help_url=reverse('help_conflict_review_states'),
),
context_instance=RequestContext(request))
def send_conflict_eval_email(request,review):
msg = render_to_string("doc/conflict_review/eval_email.txt",
dict(review=review,
review_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(),
msg = render_to_string("doc/eval_email.txt",
dict(doc=review,
doc_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(),
)
)
send_mail_preformatted(request,msg)
@ -202,9 +197,6 @@ def submit(request, name):
},
context_instance=RequestContext(request))
class NotifyForm(forms.Form):
notify = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)
@role_required("Area Director", "Secretariat")
def edit_notices(request, name):
@ -231,28 +223,15 @@ def edit_notices(request, name):
init = { "notify" : review.notify }
form = NotifyForm(initial=init)
return render_to_response('doc/conflict_review/notify.html',
{'form': form,
'review': review,
'conflictdoc' : review.relateddocument_set.get(relationship__slug='conflrev').target.document,
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
titletext = 'the conflict review of %s-%s' % (conflictdoc.canonical_name(),conflictdoc.rev)
return render_to_response('doc/notify.html',
{'form': form,
'doc': review,
'titletext' : titletext
},
context_instance = RequestContext(request))
class AdForm(forms.Form):
ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active").order_by('name'),
label="Shepherding AD", empty_label="(None)", required=True)
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
# if previous AD is now ex-AD, append that person to the list
ad_pk = self.initial.get('ad')
choices = self.fields['ad'].choices
if ad_pk and ad_pk not in [pk for pk, name in choices]:
self.fields['ad'].choices = list(choices) + [("", "-------"), (ad_pk, Person.objects.get(pk=ad_pk).plain_name())]
@role_required("Area Director", "Secretariat")
def edit_ad(request, name):
"""Change the shepherding Area Director for this review."""
@ -277,10 +256,13 @@ def edit_ad(request, name):
init = { "ad" : review.ad_id }
form = AdForm(initial=init)
return render_to_response('doc/conflict_review/change_ad.html',
{'form': form,
'review': review,
'conflictdoc' : review.relateddocument_set.get(relationship__slug='conflrev').target.document,
conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document
titletext = 'the conflict review of %s-%s' % (conflictdoc.canonical_name(),conflictdoc.rev)
return render_to_response('doc/change_ad.html',
{'form': form,
'doc': review,
'titletext': titletext
},
context_instance = RequestContext(request))
@ -318,7 +300,7 @@ def approve(request, name):
review = get_object_or_404(Document, type="conflrev", name=name)
if review.get_state('conflrev').slug not in ('appr-reqnopub-pend','appr-noprob-pend'):
return Http404()
raise Http404
login = request.user.get_profile()
@ -465,22 +447,6 @@ def start_review(request, name):
context_instance = RequestContext(request))
# There should really only be one of these living in Doc instead of it being spread between idrfc,charter, and here
class TelechatForm(forms.Form):
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False)
returning_item = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
dates = [d.date for d in TelechatDate.objects.active().order_by('date')]
init = kwargs['initial'].get("telechat_date")
if init and init not in dates:
dates.insert(0, init)
self.fields['telechat_date'].choices = [("", "(not on agenda)")] + [(d, d.strftime("%Y-%m-%d")) for d in dates]
@role_required("Area Director", "Secretariat")
def telechat_date(request, name):
doc = get_object_or_404(Document, type="conflrev", name=name)
@ -501,7 +467,7 @@ def telechat_date(request, name):
else:
form = TelechatForm(initial=initial)
return render_to_response('doc/conflict_review/edit_telechat_date.html',
return render_to_response('doc/edit_telechat_date.html',
dict(doc=doc,
form=form,
user=request.user,

View file

@ -0,0 +1,629 @@
import datetime, os, re
from django import forms
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.http import HttpResponseRedirect, Http404
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.template.loader import render_to_string
from django.conf import settings
from ietf.idrfc.utils import update_telechat
from ietf.doc.utils import log_state_changed
from ietf.doc.models import save_document_in_history
from ietf.doc.utils import create_ballot_if_not_open, close_open_ballots, get_document_content
from ietf.ietfauth.decorators import has_role, role_required
from ietf.utils.textupload import get_cleaned_text_file_content
from ietf.utils.mail import send_mail_preformatted
from ietf.doc.models import State, Document, DocHistory, DocAlias
from ietf.doc.models import DocEvent, NewRevisionDocEvent, WriteupDocEvent, TelechatDocEvent, BallotDocEvent, BallotPositionDocEvent
from ietf.person.models import Person
from ietf.iesg.models import TelechatDate
from ietf.group.models import Group
from ietf.name.models import DocRelationshipName, StdLevelName
from ietf.doc.forms import TelechatForm, AdForm, NotifyForm
class ChangeStateForm(forms.Form):
new_state = forms.ModelChoiceField(State.objects.filter(type="statchg", used=True), label="Status Change Evaluation State", empty_label=None, required=True)
comment = forms.CharField(widget=forms.Textarea, help_text="Optional comment for the review history", required=False)
@role_required("Area Director", "Secretariat")
def change_state(request, name, option=None):
"""Change state of an status-change document, notifying parties as necessary
and logging the change as a comment."""
status_change = get_object_or_404(Document, type="statchg", name=name)
login = request.user.get_profile()
if request.method == 'POST':
form = ChangeStateForm(request.POST)
if form.is_valid():
clean = form.cleaned_data
new_state = clean['new_state']
comment = clean['comment'].rstrip()
if comment:
c = DocEvent(type="added_comment", doc=status_change, by=login)
c.desc = comment
c.save()
if new_state != status_change.get_state():
save_document_in_history(status_change)
old_description = status_change.friendly_state()
status_change.set_state(new_state)
new_description = status_change.friendly_state()
log_state_changed(request, status_change, login, new_description, old_description)
status_change.time = datetime.datetime.now()
status_change.save()
if new_state.slug == "iesgeval":
create_ballot_if_not_open(status_change, login, "statchg")
ballot = status_change.latest_event(BallotDocEvent, type="created_ballot")
if has_role(request.user, "Area Director") and not status_change.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot, type="changed_ballot_position"):
# The AD putting a status change into iesgeval who doesn't already have a position is saying "yes"
pos = BallotPositionDocEvent(doc=status_change, by=login)
pos.ballot = ballot
pos.type = "changed_ballot_position"
pos.ad = login
pos.pos_id = "yes"
pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.plain_name())
pos.save()
send_status_change_eval_email(request,status_change)
return redirect('doc_view', name=status_change.name)
else:
s = status_change.get_state()
init = dict(new_state=s.pk if s else None,
type='statchg',
label='Status Change Evaluation State',
)
form = ChangeStateForm(initial=init)
return render_to_response('doc/change_state.html',
dict(form=form,
doc=status_change,
login=login,
help_url=reverse('help_status_change_states')
),
context_instance=RequestContext(request))
def send_status_change_eval_email(request,doc):
msg = render_to_string("doc/eval_email.txt",
dict(doc=doc,
doc_url = settings.IDTRACKER_BASE_URL+doc.get_absolute_url(),
)
)
send_mail_preformatted(request,msg)
class UploadForm(forms.Form):
content = forms.CharField(widget=forms.Textarea, label="Status change text", help_text="Edit the status change text", required=False)
txt = forms.FileField(label=".txt format", help_text="Or upload a .txt file", required=False)
def clean_content(self):
return self.cleaned_data["content"].replace("\r", "")
def clean_txt(self):
return get_cleaned_text_file_content(self.cleaned_data["txt"])
def save(self, doc):
filename = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
with open(filename, 'wb') as destination:
if self.cleaned_data['txt']:
destination.write(self.cleaned_data['txt'])
else:
destination.write(self.cleaned_data['content'])
#This is very close to submit on charter - can we get better reuse?
@role_required('Area Director','Secretariat')
def submit(request, name):
doc = get_object_or_404(Document, type="statchg", name=name)
login = request.user.get_profile()
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
not_uploaded_yet = doc.rev == "00" and not os.path.exists(path)
if not_uploaded_yet:
# this case is special - the status change text document doesn't actually exist yet
next_rev = doc.rev
else:
next_rev = "%02d" % (int(doc.rev)+1)
if request.method == 'POST':
if "submit_response" in request.POST:
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
save_document_in_history(doc)
doc.rev = next_rev
e = NewRevisionDocEvent(doc=doc, by=login, type="new_revision")
e.desc = "New version available: <b>%s-%s.txt</b>" % (doc.canonical_name(), doc.rev)
e.rev = doc.rev
e.save()
# Save file on disk
form.save(doc)
doc.time = datetime.datetime.now()
doc.save()
return HttpResponseRedirect(reverse('doc_view', kwargs={'name': doc.name}))
elif "reset_text" in request.POST:
init = { "content": render_to_string("doc/status_change/initial_template.txt",dict())}
form = UploadForm(initial=init)
# Protect against handcrufted malicious posts
else:
form = None
else:
form = None
if not form:
init = { "content": ""}
if not_uploaded_yet:
init["content"] = render_to_string("doc/status_change/initial_template.txt",
dict(),
)
else:
filename = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
try:
with open(filename, 'r') as f:
init["content"] = f.read()
except IOError:
pass
form = UploadForm(initial=init)
return render_to_response('doc/status_change/submit.html',
{'form': form,
'next_rev': next_rev,
'doc' : doc,
},
context_instance=RequestContext(request))
@role_required("Area Director", "Secretariat")
def edit_notices(request, name):
"""Change the set of email addresses document change notificaitions go to."""
status_change = get_object_or_404(Document, type="statchg", name=name)
if request.method == 'POST':
form = NotifyForm(request.POST)
if form.is_valid():
status_change.notify = form.cleaned_data['notify']
status_change.save()
login = request.user.get_profile()
c = DocEvent(type="added_comment", doc=status_change, by=login)
c.desc = "Notification list changed to : "+status_change.notify
c.save()
return HttpResponseRedirect(reverse('doc_view', kwargs={'name': status_change.name}))
else:
init = { "notify" : status_change.notify }
form = NotifyForm(initial=init)
return render_to_response('doc/notify.html',
{'form': form,
'doc': status_change,
'titletext' : '%s-%s.txt' % (status_change.canonical_name(),status_change.rev)
},
context_instance = RequestContext(request))
@role_required("Area Director", "Secretariat")
def edit_ad(request, name):
"""Change the shepherding Area Director for this status_change."""
status_change = get_object_or_404(Document, type="statchg", name=name)
if request.method == 'POST':
form = AdForm(request.POST)
if form.is_valid():
status_change.ad = form.cleaned_data['ad']
status_change.save()
login = request.user.get_profile()
c = DocEvent(type="added_comment", doc=status_change, by=login)
c.desc = "Shepherding AD changed to "+status_change.ad.name
c.save()
return redirect("doc_view", name=status_change.name)
else:
init = { "ad" : status_change.ad_id }
form = AdForm(initial=init)
titletext = '%s-%s.txt' % (status_change.canonical_name(),status_change.rev)
return render_to_response('doc/change_ad.html',
{'form': form,
'doc': status_change,
'titletext' : titletext,
},
context_instance = RequestContext(request))
def newstatus(relateddoc):
level_map = {
'tops' : 'ps',
'tois' : 'std',
'tohist' : 'hist',
'toinf' : 'inf',
'tobcp' : 'bcp',
'toexp' : 'exp',
}
return StdLevelName.objects.get(slug=level_map[relateddoc.relationship.slug])
def default_approval_text(status_change,relateddoc):
filename = "%s-%s.txt" % (status_change.canonical_name(), status_change.rev)
current_text = get_document_content(filename, os.path.join(settings.STATUS_CHANGE_PATH, filename), split=False, markup=False)
if relateddoc.target.document.std_level.slug in ('std','ps','ds','bcp',):
action = "Protocol Action"
else:
action = "Document Action"
text = render_to_string("doc/status_change/approval_text.txt",
dict(status_change=status_change,
status_change_url = settings.IDTRACKER_BASE_URL+status_change.get_absolute_url(),
relateddoc= relateddoc,
relateddoc_url = settings.IDTRACKER_BASE_URL+relateddoc.target.document.get_absolute_url(),
approved_text = current_text,
action=action,
newstatus=newstatus(relateddoc),
)
)
return text
from django.forms.formsets import formset_factory
class AnnouncementForm(forms.Form):
announcement_text = forms.CharField(widget=forms.Textarea, label="Status Change Announcement", help_text="Edit the announcement message", required=True)
label = None
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self.label = self.initial.get('label')
@role_required("Secretariat")
def approve(request, name):
"""Approve this status change, setting the appropriate state and send the announcements to the right parties."""
status_change = get_object_or_404(Document, type="statchg", name=name)
if status_change.get_state('statchg').slug not in ('appr-pend'):
raise Http404
login = request.user.get_profile()
AnnouncementFormSet = formset_factory(AnnouncementForm,extra=0)
if request.method == 'POST':
formset = AnnouncementFormSet(request.POST)
if formset.is_valid():
save_document_in_history(status_change)
old_description = status_change.friendly_state()
status_change.set_state(State.objects.get(type='statchg', slug='appr-sent'))
new_description = status_change.friendly_state()
log_state_changed(request, status_change, login, new_description, old_description)
close_open_ballots(status_change, login)
e = DocEvent(doc=status_change, by=login)
e.type = "iesg_approved"
e.desc = "IESG has approved the status change"
e.save()
status_change.time = e.time
status_change.save()
for form in formset.forms:
send_mail_preformatted(request,form.cleaned_data['announcement_text'])
c = DocEvent(type="added_comment", doc=status_change, by=login)
c.desc = "The following approval message was sent\n"+form.cleaned_data['announcement_text']
c.save()
for rel in status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS):
# Add a document event to each target
c = DocEvent(type="added_comment", doc=rel.target.document, by=login)
c.desc = "New status of %s approved by the IESG\n%s%s" % (newstatus(rel), settings.IDTRACKER_BASE_URL,reverse('doc_view', kwargs={'name': status_change.name}))
c.save()
return HttpResponseRedirect(status_change.get_absolute_url())
else:
init = []
for rel in status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS):
init.append({"announcement_text" : default_approval_text(status_change,rel),
"label": "Announcement text for %s to %s"%(rel.target.document.canonical_name(),newstatus(rel)),
})
formset = AnnouncementFormSet(initial=init)
for form in formset.forms:
form.fields['announcement_text'].label=form.label
return render_to_response('doc/status_change/approve.html',
dict(
doc = status_change,
formset = formset,
),
context_instance=RequestContext(request))
RELATION_SLUGS = ('tops','tois','tohist','toinf','tobcp','toexp')
def clean_helper(form, formtype):
cleaned_data = super(formtype, form).clean()
new_relations = {}
rfc_fields = {}
status_fields={}
for k in sorted(form.data.iterkeys()):
v = form.data[k]
if k.startswith('new_relation_row'):
if re.match('\d{4}',v):
v = 'rfc'+v
rfc_fields[k[17:]]=v
elif k.startswith('statchg_relation_row'):
status_fields[k[21:]]=v
for key in rfc_fields:
if rfc_fields[key]!="":
new_relations[rfc_fields[key]]=status_fields[key]
form.relations = new_relations
errors=[]
for key in new_relations:
if not re.match('(?i)rfc\d{4}',key):
errors.append(key+" is not a valid RFC - please use the form RFCxxxx\n")
elif not DocAlias.objects.filter(name=key):
errors.append(key+" does not exist\n")
if new_relations[key] not in RELATION_SLUGS:
errors.append("Please choose a new status level for "+key+"\n")
if errors:
raise forms.ValidationError(errors)
cleaned_data['relations']=new_relations
return cleaned_data
class EditStatusChangeForm(forms.Form):
relations={}
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self.relations = self.initial.get('relations')
def clean(self):
return clean_helper(self,EditStatusChangeForm)
class StartStatusChangeForm(forms.Form):
document_name = forms.CharField(max_length=255, label="Document name", help_text="A descriptive name such as status-change-md2-to-historic is better than status-change-rfc1319", required=True)
title = forms.CharField(max_length=255, label="Title", required=True)
ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active").order_by('name'),
label="Shepherding AD", empty_label="(None)", required=True)
create_in_state = forms.ModelChoiceField(State.objects.filter(type="statchg", slug__in=("needshep", "adrev")), empty_label=None, required=False)
notify = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False, widget=forms.Select(attrs={'onchange':'make_bold()'}))
relations={}
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self.relations = self.initial.get('relations')
# telechat choices
dates = [d.date for d in TelechatDate.objects.active().order_by('date')]
self.fields['telechat_date'].choices = [("", "(not on agenda)")] + [(d, d.strftime("%Y-%m-%d")) for d in dates]
def clean_document_name(self):
name = self.cleaned_data['document_name']
errors=[]
if re.search("[^a-z0-9-]", name):
errors.append("The name of the document may only contain digits, lowercase letters and dashes")
if re.search("--", name):
errors.append("Please do not put more than one hyphen between any two words in the name")
if name.startswith('status-change'):
errors.append("status-change- will be added automatically as a prefix")
if name.startswith('-'):
errors.append("status-change- will be added automatically as a prefix, starting with a - will result in status-change-%s"%name)
if re.search("-[0-9]{2}$", name):
errors.append("This name looks like ends in a version number. -00 will be added automatically. Please adjust the end of the name.")
if Document.objects.filter(name='status-change-%s'%name):
errors.append("status-change-%s already exists"%name)
if name.endswith('CHANGETHIS'):
errors.append("Please change CHANGETHIS to reflect the intent of this status change")
if errors:
raise forms.ValidationError(errors)
return name
def clean_title(self):
title = self.cleaned_data['title']
errors=[]
if title.endswith('CHANGETHIS'):
errors.append("Please change CHANGETHIS to reflect the intent of this status change")
if errors:
raise forms.ValidationError(errors)
return title
def clean(self):
return clean_helper(self,StartStatusChangeForm)
def rfc_status_changes(request):
"""Show the rfc status changes that are under consideration, and those that are completed."""
docs=Document.objects.filter(type__slug='statchg')
doclist=[x for x in docs]
doclist.sort(key=lambda obj: obj.get_state().order)
return render_to_response('doc/status_change/status_changes.html',
{'docs' : doclist,
},
context_instance = RequestContext(request))
@role_required("Area Director","Secretariat")
def start_rfc_status_change(request,name):
"""Start the RFC status change review process, setting the initial shepherding AD, and possibly putting the review on a telechat."""
if name:
if not re.match("(?i)rfc[0-9]{4}",name):
raise Http404
seed_rfc = get_object_or_404(Document, type="draft", docalias__name=name)
login = request.user.get_profile()
relation_slugs = DocRelationshipName.objects.filter(slug__in=RELATION_SLUGS)
if request.method == 'POST':
form = StartStatusChangeForm(request.POST)
if form.is_valid():
iesg_group = Group.objects.get(acronym='iesg')
status_change=Document( type_id = "statchg",
name = 'status-change-'+form.cleaned_data['document_name'],
title = form.cleaned_data['title'],
rev = "00",
ad = form.cleaned_data['ad'],
notify = form.cleaned_data['notify'],
stream_id = 'ietf',
group = iesg_group,
)
status_change.set_state(form.cleaned_data['create_in_state'])
status_change.save()
DocAlias.objects.create( name= 'status-change-'+form.cleaned_data['document_name'], document=status_change )
for key in form.cleaned_data['relations']:
status_change.relateddocument_set.create(target=DocAlias.objects.get(name=key),
relationship_id=form.cleaned_data['relations'][key])
tc_date = form.cleaned_data['telechat_date']
if tc_date:
update_telechat(request, status_change, login, tc_date)
return HttpResponseRedirect(status_change.get_absolute_url())
else:
init = {}
if name:
init['title'] = "%s to CHANGETHIS" % seed_rfc.title
init['document_name'] = "%s-to-CHANGETHIS" % seed_rfc.canonical_name()
relations={}
relations[seed_rfc.canonical_name()]=None
init['relations'] = relations
form = StartStatusChangeForm(initial=init)
return render_to_response('doc/status_change/start.html',
{'form': form,
'relation_slugs': relation_slugs,
},
context_instance = RequestContext(request))
@role_required("Area Director", "Secretariat")
def telechat_date(request, name):
doc = get_object_or_404(Document, type="statchg", name=name)
login = request.user.get_profile()
e = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
initial_returning_item = bool(e and e.returning_item)
initial = dict(telechat_date=e.telechat_date if e else None,
returning_item = initial_returning_item,
)
if request.method == "POST":
form = TelechatForm(request.POST, initial=initial)
if form.is_valid():
update_telechat(request, doc, login, form.cleaned_data['telechat_date'], form.cleaned_data['returning_item'])
return redirect("doc_view", name=doc.name)
else:
form = TelechatForm(initial=initial)
return render_to_response('doc/edit_telechat_date.html',
dict(doc=doc,
form=form,
user=request.user,
login=login),
context_instance=RequestContext(request))
@role_required("Area Director", "Secretariat")
def edit_relations(request, name):
"""Change the affected set of RFCs"""
status_change = get_object_or_404(Document, type="statchg", name=name)
login = request.user.get_profile()
relation_slugs = DocRelationshipName.objects.filter(slug__in=RELATION_SLUGS)
if request.method == 'POST':
form = EditStatusChangeForm(request.POST)
if form.is_valid():
old_relations={}
for rel in status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS):
old_relations[rel.target.document.canonical_name()]=rel.relationship.slug
new_relations=form.cleaned_data['relations']
status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS).delete()
for key in new_relations:
status_change.relateddocument_set.create(target=DocAlias.objects.get(name=key),
relationship_id=new_relations[key])
c = DocEvent(type="added_comment", doc=status_change, by=login)
c.desc = "Affected RFC list changed.\nOLD:"
for relname,relslug in (set(old_relations.items())-set(new_relations.items())):
c.desc += "\n "+relname+": "+DocRelationshipName.objects.get(slug=relslug).name
c.desc += "\nNEW:"
for relname,relslug in (set(new_relations.items())-set(old_relations.items())):
c.desc += "\n "+relname+": "+DocRelationshipName.objects.get(slug=relslug).name
#for rel in status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS):
# c.desc +="\n"+rel.relationship.name+": "+rel.target.document.canonical_name()
c.desc += "\n"
c.save()
return HttpResponseRedirect(status_change.get_absolute_url())
else:
relations={}
for rel in status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS):
relations[rel.target.document.canonical_name()]=rel.relationship.slug
init = { "relations":relations,
}
form = EditStatusChangeForm(initial=init)
return render_to_response('doc/status_change/edit_relations.html',
{
'doc': status_change,
'form': form,
'relation_slugs': relation_slugs,
},
context_instance = RequestContext(request))

View file

@ -405,6 +405,16 @@ class RfcWrapper:
result['ietf_process'] = self.ietf_process.dict()
return json.dumps(result, indent=2)
def underlying_document(self):
""" Expose the Document object underneath the proxy """
# Things like RFC500 are special - there may not _be_ a docalias for them
from ietf.doc.models import Document
q = Document.objects.filter(docalias__name='rfc%04d'%self.rfc_number)
if q:
return q[0]
else:
return None
# ---------------------------------------------------------------------------
class IetfProcessData:

View file

@ -33,6 +33,7 @@
from django.conf.urls.defaults import patterns, url, include
from ietf.idrfc import views_doc, views_search, views_edit, views_ballot, views
from ietf.doc.models import State
from ietf.doc import views_status_change
urlpatterns = patterns('',
(r'^/?$', views_search.search_main),
@ -40,7 +41,10 @@ urlpatterns = patterns('',
(r'^all/$', views_search.all),
(r'^active/$', views_search.active),
(r'^in-last-call/$', views_search.in_last_call),
url(r'^rfc-status-changes/$', views_status_change.rfc_status_changes, name='rfc_status_changes'),
url(r'^start-rfc-status-change/(?P<name>[A-Za-z0-9._+-]*)$', views_status_change.start_rfc_status_change, name='start_rfc_status_change'),
url(r'^ad/(?P<name>[A-Za-z0-9.-]+)/$', views_search.by_ad, name="doc_search_by_ad"),
url(r'^ad2/(?P<name>[A-Za-z0-9.-]+)/$', views_search.by_ad2, name="doc_search_by_ad2"),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/((?P<rev>[0-9-]+)/)?$', views_doc.document_main, name="doc_view"),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/history/$', views_doc.document_history, name="doc_history"),
@ -81,11 +85,13 @@ urlpatterns = patterns('',
(r'^(?P<name>charter-[A-Za-z0-9._+-]+)/', include('ietf.wgcharter.urls')),
(r'^(?P<name>[A-Za-z0-9._+-]+)/conflict-review/', include('ietf.doc.urls_conflict_review')),
(r'^(?P<name>[A-Za-z0-9._+-]+)/status-change/', include('ietf.doc.urls_status_change')),
)
urlpatterns += patterns('django.views.generic.simple',
url(r'^help/state/charter/$', 'direct_to_template', { 'template': 'doc/states.html', 'extra_context': { 'states': State.objects.filter(type="charter"),'title':"Charter" } }, name='help_charter_states'),
url(r'^help/state/conflict-review/$', 'direct_to_template', { 'template': 'doc/states.html', 'extra_context': { 'states': State.objects.filter(type="conflrev").order_by("order"),'title':"Conflict Review" } }, name='help_conflict_review_states'),
url(r'^help/state/status-change/$', 'direct_to_template', { 'template': 'doc/states.html', 'extra_context': { 'states': State.objects.filter(type="statchg").order_by("order"),'title':"RFC Status Change" } }, name='help_status_change_states'),
)

View file

@ -54,20 +54,21 @@ from ietf.doc.models import *
from ietf.doc.utils import *
from ietf.utils.history import find_history_active_at
from ietf.ietfauth.decorators import has_role
from ietf.doc.views_status_change import RELATION_SLUGS as status_change_relationships
def render_document_top(request, doc, tab, name):
tabs = []
tabs.append(("Document", "document", urlreverse("ietf.idrfc.views_doc.document_main", kwargs=dict(name=name)), True))
ballot = doc.latest_event(BallotDocEvent, type="created_ballot")
if doc.type_id in ("draft","conflrev"):
if doc.type_id in ("draft","conflrev","statchg"):
# if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot:
tabs.append(("IESG Evaluation Record", "ballot", urlreverse("ietf.idrfc.views_doc.document_ballot", kwargs=dict(name=name)), ballot))
elif doc.type_id == "charter":
tabs.append(("IESG Review", "ballot", urlreverse("ietf.idrfc.views_doc.document_ballot", kwargs=dict(name=name)), ballot))
# FIXME: if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot:
if doc.type_id != "conflrev":
if doc.type_id not in ("conflrev","statchg"):
tabs.append(("IESG Writeups", "writeup", urlreverse("ietf.idrfc.views_doc.document_writeup", kwargs=dict(name=doc.name)), True))
tabs.append(("History", "history", urlreverse("ietf.idrfc.views_doc.document_history", kwargs=dict(name=doc.name)), True))
@ -190,6 +191,40 @@ def document_main(request, name, rev=None):
),
context_instance=RequestContext(request))
if doc.type_id == "statchg":
filename = "%s-%s.txt" % (doc.canonical_name(), doc.rev)
pathname = os.path.join(settings.STATUS_CHANGE_PATH,filename)
if doc.rev == "00" and not os.path.isfile(pathname):
# This could move to a template
content = "Status change text has not yet been proposed."
else:
content = _get_html(filename, pathname, split=False)
ballot_summary = None
if doc.get_state_slug() in ("iesgeval"):
ballot_summary = needed_ballot_positions(doc, doc.active_ballot().active_ad_positions().values())
if isinstance(doc,Document):
sorted_relations=doc.relateddocument_set.all().order_by('relationship__name')
elif isinstance(doc,DocHistory):
sorted_relations=doc.relateddochistory_set.all().order_by('relationship__name')
else:
sorted_relations=None
return render_to_response("idrfc/document_status_change.html",
dict(doc=doc,
top=top,
content=content,
revisions=revisions,
snapshot=snapshot,
telechat=telechat,
ballot_summary=ballot_summary,
approved_states=('appr-pend','appr-sent'),
sorted_relations=sorted_relations,
),
context_instance=RequestContext(request))
raise Http404()
@ -209,7 +244,7 @@ def document_history(request, name):
diff_revisions = []
seen = set()
diffable = name.startswith("draft") or name.startswith("charter") or name.startswith("conflict-review")
diffable = name.startswith("draft") or name.startswith("charter") or name.startswith("conflict-review") or name.startswith("status-change")
if diffable:
for e in NewRevisionDocEvent.objects.filter(type="new_revision", doc__in=diff_documents).select_related('doc').order_by("-time", "-id"):
@ -223,6 +258,9 @@ def document_history(request, name):
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
@ -423,6 +461,11 @@ def document_main_rfc(request, rfc_number, tab):
content1 = ""
content2 = ""
underlying_document = doc.underlying_document()
if underlying_document:
info['status_changes'] = ', '.join([ rel.source.canonical_name() for rel in RelatedDocument.objects.filter(relationship__in=status_change_relationships,target__document=underlying_document) if rel.source.get_state_slug() in ('appr-sent','appr-pend')])
info['proposed_status_changes'] = ', '.join([ rel.source.canonical_name() for rel in RelatedDocument.objects.filter(relationship__in=status_change_relationships,target__document=underlying_document) if rel.source.get_state_slug() in ('needshep','adrev','iesgeval','defer','appr-pr')])
history = _get_history(doc, None)
template = "idrfc/doc_tab_%s" % tab

View file

@ -38,6 +38,7 @@ from django.template import RequestContext
from django.views.decorators.cache import cache_page
from ietf.idtracker.models import IDState, IESGLogin, IDSubState, Area, InternetDraft, Rfc, IDInternal, IETFWG
from ietf.idrfc.models import RfcIndex
from ietf.ipr.models import IprDraft
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponsePermanentRedirect
from ietf.idrfc.idrfc_wrapper import IdWrapper,RfcWrapper,IdRfcWrapper
from ietf.utils import normalize_draftname
@ -579,6 +580,129 @@ def by_ad(request, name):
results.sort(key=lambda obj: obj.view_sort_key_byad())
return render_to_response('idrfc/by_ad.html', {'form':form, 'docs':results,'meta':meta, 'ad_name':ad_name}, context_instance=RequestContext(request))
def ad_dashboard_group(doc):
if doc.type.slug=='draft':
if doc.get_state_slug('draft') == 'rfc':
return 'RFC'
elif doc.get_state_slug('draft') == 'active' and doc.get_state_slug('draft-iesg'):
return '%s Internet-Draft' % doc.get_state('draft-iesg').name
else:
return '%s Internet-Draft' % doc.get_state('draft').name
elif doc.type.slug=='conflrev':
if doc.get_state_slug('conflrev') in ('appr-reqnopub-sent','appr-noprob-sent'):
return 'Approved Conflict Review'
elif doc.get_state_slug('conflrev') in ('appr-reqnopub-pend','appr-noprob-pend','appr-reqnopub-pr','appr-noprob-pr'):
return "%s Conflict Review" % State.objects.get(type__slug='draft-iesg',slug='approved')
else:
return '%s Conflict Review' % doc.get_state('conflrev')
elif doc.type.slug=='statchg':
if doc.get_state_slug('statchg') in ('appr-sent',):
return 'Approved Status Change'
if doc.get_state_slug('statchg') in ('appr-pend','appr-pr'):
return '%s Status Change' % State.objects.get(type__slug='draft-iesg',slug='approved')
else:
return '%s Status Change' % doc.get_state('statchg')
elif doc.type.slug=='charter':
if doc.get_state_slug('charter') == 'approved':
return "Approved Charter"
else:
return '%s Charter' % doc.get_state('charter')
else:
return "Document"
def ad_dashboard_sort_key(doc):
if doc.type.slug=='draft' and doc.get_state_slug('draft') == 'rfc':
return "21%04d" % int(doc.rfc_number())
if doc.type.slug=='statchg' and doc.get_state_slug('statchg') == 'appr-sent':
return "22%d" % 0 # TODO - get the date of the transition into this state here
if doc.type.slug=='conflrev' and doc.get_state_slug('conflrev') in ('appr-reqnopub-sent','appr-noprob-sent'):
return "23%d" % 0 # TODO - get the date of the transition into this state here
if doc.type.slug=='charter' and doc.get_state_slug('charter') == 'approved':
return "24%d" % 0 # TODO - get the date of the transition into this state here
seed = ad_dashboard_group(doc)
if doc.type.slug=='conflrev' and doc.get_state_slug('conflrev') == 'adrev':
state = State.objects.get(type__slug='draft-iesg',slug='ad-eval')
return "1%d%s" % (state.order,seed)
if doc.type.slug=='charter':
if doc.get_state_slug('charter') in ('notrev','infrev'):
return "100%s" % seed
elif doc.get_state_slug('charter') == 'intrev':
state = State.objects.get(type__slug='draft-iesg',slug='ad-eval')
return "1%d%s" % (state.order,seed)
elif doc.get_state_slug('charter') == 'extrev':
state = State.objects.get(type__slug='draft-iesg',slug='lc')
return "1%d%s" % (state.order,seed)
elif doc.get_state_slug('charter') == 'iesgrev':
state = State.objects.get(type__slug='draft-iesg',slug='iesg-eva')
return "1%d%s" % (state.order,seed)
if seed.startswith('Needs Shepherd'):
return "100%s" % seed
if seed.endswith(' Document'):
seed = seed[:-9]
elif seed.endswith(' Internet-Draft'):
seed = seed[:-15]
elif seed.endswith(' Conflict Review'):
seed = seed[:-16]
elif seed.endswith(' Status Change'):
seed = seed[:-14]
state = State.objects.filter(type__slug='draft-iesg',name=seed)
if state:
ageseconds = 0
changetime= doc.latest_event(type='changed_document')
if changetime:
ageseconds = (datetime.datetime.now()-doc.latest_event(type='changed_document').time).total_seconds()
return "1%d%s%010d" % (state[0].order,seed,ageseconds)
return "3%s" % seed
def by_ad2(request, name):
responsible = Document.objects.values_list('ad', flat=True).distinct()
for p in Person.objects.filter(Q(role__name__in=("pre-ad", "ad"),
role__group__type="area",
role__group__state="active")
| Q(pk__in=responsible)).distinct():
if name == p.full_name_as_key():
ad_id = p.id
ad_name = p.plain_name()
break
docqueryset = Document.objects.filter(ad__id=ad_id)
docs=[]
for doc in docqueryset:
doc.ad_dashboard_sort_key = ad_dashboard_sort_key(doc)
doc.ad_dashboard_group = ad_dashboard_group(doc)
if doc.get_state_slug() == 'rfc':
doc.display_date = doc.latest_event(type='published_rfc').time
else:
revision = doc.latest_event(type='new_revision')
if revision:
doc.display_date = revision.time
# This might be better handled as something Documents know about themselves
now = datetime.datetime.now()
doc.can_expire = (doc.type.slug=='draft' and doc.get_state_slug('draft')=='active' and ( not doc.get_state('draft-iesg') or doc.get_state('draft-iesg').order >= 42) and doc.expires>now)
if doc.get_state_slug('draft') == 'rfc':
doc.obsoleted_by = ", ".join([ 'RFC %04d' % int(rel.source.rfc_number()) for alias in doc.docalias_set.all() for rel in alias.relateddocument_set.filter(relationship='obsoletes') ] )
doc.updated_by = ", ".join([ 'RFC %04d' % int(rel.source.rfc_number()) for alias in doc.docalias_set.all() for rel in alias.relateddocument_set.filter(relationship='updates') ] )
doc.has_errata = bool(doc.tags.filter(slug="errata"))
else:
s = doc.get_state("draft-rfceditor")
if s:
# extract possible extra annotations
tags = doc.tags.filter(slug__in=("iana", "ref"))
doc.rfc_editor_state = "*".join([s.name] + [t.slug.upper() for t in tags])
if doc.type.slug == 'draft':
doc.iprCount = IprDraft.objects.filter(document=doc, ipr__status__in=[1,3]).count()
doc.iprUrl = "/ipr/search?option=document_search&id_document_tag=%s" % doc.name
docs.append(doc)
docs.sort(key=ad_dashboard_sort_key)
return render_to_response('idrfc/by_ad2.html',{'docs':docs,'ad_name':ad_name}, context_instance=RequestContext(request))
@cache_page(15*60) # 15 minutes
def all(request):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:

View file

@ -226,6 +226,7 @@ def urlize_ietf_docs(string, autoescape=None):
string = re.sub("(?<!>)(FYI ?)0{0,3}(\d+)", "<a href=\"http://tools.ietf.org/html/fyi\\2/\">\\1\\2</a>", string)
string = re.sub("(?<!>)(draft-[-0-9a-zA-Z._+]+)", "<a href=\"/doc/\\1/\">\\1</a>", string)
string = re.sub("(?<!>)(conflict-review-[-0-9a-zA-Z._+]+)", "<a href=\"/doc/\\1/\">\\1</a>", string)
string = re.sub("(?<!>)(status-change-[-0-9a-zA-Z._+]+)", "<a href=\"/doc/\\1/\">\\1</a>", string)
return mark_safe(string)
urlize_ietf_docs.is_safe = True
urlize_ietf_docs.needs_autoescape = True

View file

@ -159,13 +159,28 @@ def get_doc_sectionREDESIGN(doc):
s = s + "1"
elif doc.type_id == 'charter':
s = get_wg_section(doc.group)
elif doc.type_id == 'statchg':
protocol_action = False
for relation in doc.relateddocument_set.filter(relationship__slug__in=('tops','tois','tohist','toinf','tobcp','toexp')):
if relation.relationship.slug in ('tops','tois') or relation.target.document.std_level.slug in ('std','ds','ps'):
protocol_action = True
if protocol_action:
s="23"
else:
s="33"
if doc.get_state_slug() not in ("iesgeval", "defer", "appr-pr", "appr-pend", "appr-sent"):
s = s + "3"
elif doc.returning_item():
s = s + "2"
else:
s = s + "1"
elif doc.type_id == 'conflrev':
if doc.get_state('conflrev').slug not in ('adrev','iesgeval','appr-reqnopub-pend','appr-reqnopub-sent','appr-noprob-pend','appr-noprob-sent','defer'):
s = "333"
s = "343"
elif doc.returning_item():
s = "332"
s = "342"
else:
s = "331"
s = "341"
return s
@ -225,6 +240,8 @@ def agenda_docs(date, next_agenda):
docmatches.sort(key=lambda d: d.balloting_started)
res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4))
for k in range(1,4):
res['s34%d'%k]=[]
for id in docmatches:
section_key = "s"+get_doc_section(id)
if section_key not in res:
@ -279,6 +296,9 @@ def _agenda_json(request, date=None):
data['sections']['2.2'] = {'title':"Individual Submissions"}
data['sections']['2.2.1'] = {'title':"New Items", 'docs':[]}
data['sections']['2.2.2'] = {'title':"Returning Items", 'docs':[]}
data['sections']['2.3'] = {'title':"Individual Submissions"}
data['sections']['2.3.1'] = {'title':"New Items", 'docs':[]}
data['sections']['2.3.2'] = {'title':"Returning Items", 'docs':[]}
data['sections']['3'] = {'title':"Document Actions"}
data['sections']['3.1'] = {'title':"WG Submissions"}
data['sections']['3.1.1'] = {'title':"New Items", 'docs':[]}
@ -286,9 +306,12 @@ def _agenda_json(request, date=None):
data['sections']['3.2'] = {'title':"Individual Submissions Via AD"}
data['sections']['3.2.1'] = {'title':"New Items", 'docs':[]}
data['sections']['3.2.2'] = {'title':"Returning Items", 'docs':[]}
data['sections']['3.3'] = {'title':"IRTF and Independent Submission Stream Documents"}
data['sections']['3.3'] = {'title':"Status Changes"}
data['sections']['3.3.1'] = {'title':"New Items", 'docs':[]}
data['sections']['3.3.2'] = {'title':"Returning Items", 'docs':[]}
data['sections']['3.4'] = {'title':"IRTF and Independent Submission Stream Documents"}
data['sections']['3.4.1'] = {'title':"New Items", 'docs':[]}
data['sections']['3.4.2'] = {'title':"Returning Items", 'docs':[]}
data['sections']['4'] = {'title':"Working Group Actions"}
data['sections']['4.1'] = {'title':"WG Creation"}
data['sections']['4.1.1'] = {'title':"Proposed for IETF Review", 'wgs':[]}

View file

@ -4,12 +4,15 @@ from models import *
class NameAdmin(admin.ModelAdmin):
list_display = ["slug", "name", "desc", "used"]
prepopulate_from = { "slug": ("name",) }
class DocRelationshipNameAdmin(NameAdmin):
list_display = ["slug", "name", "revname", "desc", "used"]
admin.site.register(GroupTypeName, NameAdmin)
admin.site.register(GroupStateName, NameAdmin)
admin.site.register(RoleName, NameAdmin)
admin.site.register(StreamName, NameAdmin)
admin.site.register(DocRelationshipName, NameAdmin)
admin.site.register(DocRelationshipName, DocRelationshipNameAdmin)
admin.site.register(DocTypeName, NameAdmin)
admin.site.register(DocTagName, NameAdmin)
admin.site.register(StdLevelName, NameAdmin)

View file

@ -72,24 +72,70 @@
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Obsoleted by</field>
</object>
<object pk="updates" model="name.docrelationshipname">
<field type="CharField" name="name">Updates</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Updated by</field>
</object>
<object pk="replaces" model="name.docrelationshipname">
<field type="CharField" name="name">Replaces</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Replaced by</field>
</object>
<object pk="conflrev" model="name.docrelationshipname">
<field type="CharField" name="name">conflict reviews</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Conflict reviewed by</field>
</object>
<object pk="tops" model="name.docrelationshipname">
<field type="CharField" name="name">Moves to Proposed Standard</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Moved to Proposed Standard by</field>
</object>
<object pk="tois" model="name.docrelationshipname">
<field type="CharField" name="name">Moves to Internet Standard</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Moved to Internet Standard by</field>
</object>
<object pk="tohist" model="name.docrelationshipname">
<field type="CharField" name="name">Moves to Historic</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Moved to Historic by</field>
</object>
<object pk="toinf" model="name.docrelationshipname">
<field type="CharField" name="name">Moves to Informational</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Moved to Informational by</field>
</object>
<object pk="tobcp" model="name.docrelationshipname">
<field type="CharField" name="name">Moves to BCP</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Moved to BCP by</field>
</object>
<object pk="toexp" model="name.docrelationshipname">
<field type="CharField" name="name">Moves to Experimental</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field type="CharField" name="revname">Moved to Experimental by</field>
</object>
<object pk="stream-s" model="name.docremindertypename">
<field type="CharField" name="name">Stream state should change</field>
@ -97,7 +143,7 @@
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="iana" model="name.doctagname">
<object pk="iana-crd" model="name.doctagname">
<field type="CharField" name="name">IANA coordination</field>
<field type="TextField" name="desc">RFC-Editor/IANA Registration Coordination</field>
<field type="BooleanField" name="used">True</field>
@ -134,7 +180,7 @@
<field type="IntegerField" name="order">0</field>
</object>
<object pk="app-min" model="name.doctagname">
<field type="CharField" name="name">Approved in minute</field>
<field type="CharField" name="name">Approved in minutes</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
@ -157,6 +203,12 @@
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="iana" model="name.doctagname">
<field type="CharField" name="name">IANA</field>
<field type="TextField" name="desc">The document has IANA actions that are not yet completed.</field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="point" model="name.doctagname">
<field type="CharField" name="name">Point Raised - writeup needed</field>
<field type="TextField" name="desc">IESG discussions on the document have raised some issues that need to be brought to the attention of the authors/WG, but those issues have not been written down yet. (It is common for discussions during a telechat to result in such situations. An AD may raise a possible issue during a telechat and only decide as a result of that discussion whether the issue is worth formally writing up and bringing to the attention of the authors/WG). A document stays in the "Point Raised - Writeup Needed" state until *ALL* IESG comments that have been raised have been documented.</field>
@ -313,14 +365,44 @@
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="maturity" model="name.doctypename">
<field type="CharField" name="name">Maturity Change</field>
<object pk="conflrev" model="name.doctypename">
<field type="CharField" name="name">Conflict Review</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="conflrev" model="name.doctypename">
<field type="CharField" name="name">Conflict Review</field>
<object pk="statchg" model="name.doctypename">
<field type="CharField" name="name">Status Change</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="no" model="name.groupballotpositionname">
<field type="CharField" name="name">No</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="yes" model="name.groupballotpositionname">
<field type="CharField" name="name">Yes</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="abstain" model="name.groupballotpositionname">
<field type="CharField" name="name">Abstain</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="block" model="name.groupballotpositionname">
<field type="CharField" name="name">Block</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="norecord" model="name.groupballotpositionname">
<field type="CharField" name="name">No record</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
@ -361,6 +443,18 @@
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="abandon" model="name.groupstatename">
<field type="CharField" name="name">Abandonded</field>
<field type="TextField" name="desc">Formation of the group (most likely a BoF or Proposed WG) was abandoned</field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="bof-conc" model="name.groupstatename">
<field type="CharField" name="name">BOF Concluded</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="ietf" model="name.grouptypename">
<field type="CharField" name="name">IETF</field>
<field type="TextField" name="desc"></field>
@ -415,6 +509,12 @@
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="rfcedtyp" model="name.grouptypename">
<field type="CharField" name="name">RFC Editor</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="ps" model="name.intendedstdlevelname">
<field type="CharField" name="name">Proposed Standard</field>
<field type="TextField" name="desc"></field>
@ -559,6 +659,12 @@
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="atlarge" model="name.rolename">
<field type="CharField" name="name">At Large Member</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="schedw" model="name.sessionstatusname">
<field type="CharField" name="name">Waiting for Scheduling</field>
<field type="TextField" name="desc"></field>
@ -721,11 +827,8 @@
<object pk="draft-iesg" model="doc.statetype">
<field type="CharField" name="label">IESG state</field>
</object>
<object pk="draft-iana-action" model="doc.statetype">
<field type="CharField" name="label">IANA Action state</field>
</object>
<object pk="draft-iana-review" model="doc.statetype">
<field type="CharField" name="label">IANA Review state</field>
<object pk="draft-iana" model="doc.statetype">
<field type="CharField" name="label">IANA state</field>
</object>
<object pk="draft-rfceditor" model="doc.statetype">
<field type="CharField" name="label">RFC Editor state</field>
@ -760,6 +863,15 @@
<object pk="conflrev" model="doc.statetype">
<field type="CharField" name="label">Conflict Review State</field>
</object>
<object pk="draft-iana-action" model="doc.statetype">
<field type="CharField" name="label">IANA Action state</field>
</object>
<object pk="draft-iana-review" model="doc.statetype">
<field type="CharField" name="label">IANA Review state</field>
</object>
<object pk="statchg" model="doc.statetype">
<field type="CharField" name="label">RFC Status Change</field>
</object>
<object pk="81" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">agenda</field>
<field type="SlugField" name="slug">active</field>
@ -832,95 +944,113 @@
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="89" model="doc.state">
<object pk="90" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">needshep</field>
<field type="CharField" name="name">Needs Shepherd</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">A conflict review has been requested, but a shepherding AD has not yet been assigned</field>
<field type="IntegerField" name="order">1</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="90"></object><object pk="97"></object><object pk="98"></object></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="91"></object><object pk="98"></object><object pk="99"></object></field>
</object>
<object pk="90" model="doc.state">
<object pk="91" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">adrev</field>
<field type="CharField" name="name">AD Review</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The sponsoring AD is reviewing the document and preparing a proposed response</field>
<field type="IntegerField" name="order">2</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="91"></object><object pk="97"></object><object pk="98"></object></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="92"></object><object pk="98"></object><object pk="99"></object></field>
</object>
<object pk="91" model="doc.state">
<object pk="92" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">iesgeval</field>
<field type="CharField" name="name">IESG Evaluation</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG is considering the proposed conflict review response</field>
<field type="IntegerField" name="order">3</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="92"></object><object pk="93"></object><object pk="94"></object><object pk="97"></object><object pk="98"></object></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="93"></object><object pk="94"></object><object pk="95"></object><object pk="98"></object><object pk="99"></object></field>
</object>
<object pk="92" model="doc.state">
<object pk="93" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">defer</field>
<field type="CharField" name="name">IESG Evaluation - Defer</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The evaluation of the proposed conflict review response has been deferred to the next telechat</field>
<field type="IntegerField" name="order">4</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="91"></object><object pk="93"></object><object pk="94"></object><object pk="97"></object><object pk="98"></object></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="92"></object><object pk="94"></object><object pk="95"></object><object pk="98"></object><object pk="99"></object></field>
</object>
<object pk="93" model="doc.state">
<object pk="100" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">appr-reqnopub-pr</field>
<field type="CharField" name="name">Approved Request to Not Publish - point raised</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG has approved the conflict review response (a request to not publish), but a point has been raised that should be cleared before moving to announcement to be sent</field>
<field type="IntegerField" name="order">5</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="94"></object></field>
</object>
<object pk="101" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">appr-noprob-pr</field>
<field type="CharField" name="name">Approved No Problem - point raised</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG has approved the conflict review response, but a point has been raised that should be cleared before proceeding to announcement to be sent</field>
<field type="IntegerField" name="order">6</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="95"></object></field>
</object>
<object pk="94" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">appr-reqnopub-pend</field>
<field type="CharField" name="name">Approved Request to Not Publish - announcement to be sent</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG has approved the conflict review response (a request to not publish), but the secretariat has not yet sent the response</field>
<field type="IntegerField" name="order">5</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="95"></object><object pk="97"></object></field>
<field type="IntegerField" name="order">7</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="96"></object><object pk="98"></object></field>
</object>
<object pk="94" model="doc.state">
<object pk="95" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">appr-noprob-pend</field>
<field type="CharField" name="name">Approved No Problem - announcement to be sent</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG has approved the conflict review response, but the secretariat has not yet sent the response</field>
<field type="IntegerField" name="order">6</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="96"></object><object pk="97"></object></field>
<field type="IntegerField" name="order">8</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="97"></object><object pk="98"></object></field>
</object>
<object pk="95" model="doc.state">
<object pk="96" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">appr-reqnopub-sent</field>
<field type="CharField" name="name">Approved Request to Not Publish - announcement sent</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The secretariat has delivered the IESG's approved conflict review response (a request to not publish) to the requester</field>
<field type="IntegerField" name="order">7</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field type="IntegerField" name="order">9</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="96"></object></field>
</object>
<object pk="96" model="doc.state">
<object pk="97" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">appr-noprob-sent</field>
<field type="CharField" name="name">Approved No Problem - announcement sent</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The secretariat has delivered the IESG's approved conflict review response to the requester</field>
<field type="IntegerField" name="order">8</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field type="IntegerField" name="order">10</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="97"></object></field>
</object>
<object pk="97" model="doc.state">
<object pk="98" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">withdraw</field>
<field type="CharField" name="name">Withdrawn</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The request for conflict review was withdrawn</field>
<field type="IntegerField" name="order">9</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="89"></object></field>
<field type="IntegerField" name="order">11</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="90"></object></field>
</object>
<object pk="98" model="doc.state">
<object pk="99" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">dead</field>
<field type="CharField" name="name">Dead</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The conflict review has been abandoned</field>
<field type="IntegerField" name="order">10</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="89"></object></field>
<field type="IntegerField" name="order">12</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="90"></object></field>
</object>
<object pk="1" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
@ -976,97 +1106,97 @@
<field type="IntegerField" name="order">6</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="104" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">rfcedack</field>
<field type="CharField" name="name">RFC-Ed-Ack</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Request completed. The RFC Editor has acknowledged receipt of IANA's message that the actions have been completed</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="103" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitrfc</field>
<field type="CharField" name="name">Waiting on RFC Editor</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA has notified the RFC Editor that the actions have been completed</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="102" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitwgc</field>
<field type="CharField" name="name">Waiting on WGC</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is waiting on the IETF Working Group Chairs to respond</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="101" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitad</field>
<field type="CharField" name="name">Waiting on ADs</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is waiting on the IETF Area Directors to respond</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="100" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitauth</field>
<field type="CharField" name="name">Waiting on Authors</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is waiting on the document's authors to respond</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="99" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">inprog</field>
<field type="CharField" name="name">In Progress</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is currently processing the actions for this document</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="98" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">newdoc</field>
<field type="CharField" name="name">New Document</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">A new document has been received by IANA, but no actions have been taken</field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">1</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="103" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">inprog</field>
<field type="CharField" name="name">In Progress</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is currently processing the actions for this document</field>
<field type="IntegerField" name="order">2</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="104" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitauth</field>
<field type="CharField" name="name">Waiting on Authors</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is waiting on the document's authors to respond</field>
<field type="IntegerField" name="order">3</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="105" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitad</field>
<field type="CharField" name="name">Waiting on ADs</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is waiting on the IETF Area Directors to respond</field>
<field type="IntegerField" name="order">4</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="106" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitwgc</field>
<field type="CharField" name="name">Waiting on WGC</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA is waiting on the IETF Working Group Chairs to respond</field>
<field type="IntegerField" name="order">5</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="107" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">waitrfc</field>
<field type="CharField" name="name">Waiting on RFC Editor</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA has notified the RFC Editor that the actions have been completed</field>
<field type="IntegerField" name="order">6</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="108" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">rfcedack</field>
<field type="CharField" name="name">RFC-Ed-Ack</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Request completed. The RFC Editor has acknowledged receipt of IANA's message that the actions have been completed</field>
<field type="IntegerField" name="order">7</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="109" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">onhold</field>
<field type="CharField" name="name">On Hold</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">IANA has suspended work on the document</field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">8</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="106" model="doc.state">
<object pk="110" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-action</field>
<field type="SlugField" name="slug">noic</field>
<field type="CharField" name="name">No IC</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Request completed. There were no IANA actions for this document</field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">9</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="107" model="doc.state">
<object pk="111" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-review</field>
<field type="SlugField" name="slug">need-rev</field>
<field type="CharField" name="name">IANA Review Needed</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc"></field>
<field type="TextField" name="desc">Document has not yet been reviewed by IANA.</field>
<field type="IntegerField" name="order">1</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="108" model="doc.state">
<object pk="112" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-review</field>
<field type="SlugField" name="slug">ok-act</field>
<field type="CharField" name="name">IANA OK - Actions Needed</field>
@ -1075,7 +1205,7 @@
<field type="IntegerField" name="order">2</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="109" model="doc.state">
<object pk="113" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-review</field>
<field type="SlugField" name="slug">ok-noact</field>
<field type="CharField" name="name">IANA OK - No Actions Needed</field>
@ -1084,7 +1214,7 @@
<field type="IntegerField" name="order">3</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="110" model="doc.state">
<object pk="114" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-review</field>
<field type="SlugField" name="slug">not-ok</field>
<field type="CharField" name="name">IANA Not OK</field>
@ -1093,7 +1223,7 @@
<field type="IntegerField" name="order">4</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="111" model="doc.state">
<object pk="115" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iana-review</field>
<field type="SlugField" name="slug">changed</field>
<field type="CharField" name="name">Version Changed - Review Needed</field>
@ -1102,15 +1232,6 @@
<field type="IntegerField" name="order">5</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="112" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfceditor</field>
<field type="SlugField" name="slug">auth48-done</field>
<field type="CharField" name="name">AUTH48-DONE</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Final approvals are complete</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="16" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
<field type="SlugField" name="slug">pub-req</field>
@ -1287,7 +1408,7 @@
<field type="SlugField" name="slug">edit</field>
<field type="CharField" name="name">EDIT</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing</field>
<field type="TextField" name="desc">Awaiting editing or being edited</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
@ -1296,7 +1417,7 @@
<field type="SlugField" name="slug">iana</field>
<field type="CharField" name="name">IANA</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">RFC-Editor/IANA Registration Coordination</field>
<field type="TextField" name="desc">Document has been edited, but is holding for completion of IANA actions</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
@ -1305,7 +1426,7 @@
<field type="SlugField" name="slug">iesg</field>
<field type="CharField" name="name">IESG</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Holding for IESG action</field>
<field type="TextField" name="desc">Awaiting IESG action</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
@ -1323,7 +1444,7 @@
<field type="SlugField" name="slug">isr-auth</field>
<field type="CharField" name="name">ISR-AUTH</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Independent Submission awaiting author update, or in discussion between author and ISE</field>
<field type="TextField" name="desc">Independent submission awaiting author action, or in discussion between author and ISE</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
@ -1363,6 +1484,60 @@
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="89" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfceditor</field>
<field type="SlugField" name="slug">auth48done</field>
<field type="CharField" name="name">AUTH48-DONE</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Final approvals are complete</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="74"></object></field>
</object>
<object pk="116" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfceditor</field>
<field type="SlugField" name="slug">auth48-done</field>
<field type="CharField" name="name">AUTH48-DONE</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Final approvals are complete</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="117" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfceditor</field>
<field type="SlugField" name="slug">edit</field>
<field type="CharField" name="name">EDIT</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="118" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfceditor</field>
<field type="SlugField" name="slug">iana-crd</field>
<field type="CharField" name="name">IANA</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">RFC-Editor/IANA Registration Coordination</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="119" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfceditor</field>
<field type="SlugField" name="slug">iesg</field>
<field type="CharField" name="name">IESG</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Holding for IESG action</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="120" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfceditor</field>
<field type="SlugField" name="slug">isr-auth</field>
<field type="CharField" name="name">ISR-AUTH</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">Independent Submission awaiting author update, or in discussion between author and ISE</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="45" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-stream-iab</field>
<field type="SlugField" name="slug">candidat</field>
@ -1843,6 +2018,87 @@
<field type="IntegerField" name="order">2</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="121" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">needshep</field>
<field type="CharField" name="name">Needs Shepherd</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">An RFC status change has been requested, but a shepherding AD has not yet been assigned</field>
<field type="IntegerField" name="order">1</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="122"></object><object pk="128"></object><object pk="129"></object></field>
</object>
<object pk="122" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">adrev</field>
<field type="CharField" name="name">AD Review</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The sponsoring AD is preparing an RFC status change document</field>
<field type="IntegerField" name="order">2</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="123"></object><object pk="128"></object><object pk="129"></object></field>
</object>
<object pk="123" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">iesgeval</field>
<field type="CharField" name="name">IESG Evaluation</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG is considering the proposed RFC status changes</field>
<field type="IntegerField" name="order">3</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="124"></object><object pk="125"></object><object pk="126"></object><object pk="128"></object><object pk="129"></object></field>
</object>
<object pk="124" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">defer</field>
<field type="CharField" name="name">IESG Evaluation - Defer</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The evaluation of the proposed RFC status changes have been deferred to the next telechat</field>
<field type="IntegerField" name="order">4</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="123"></object><object pk="125"></object><object pk="126"></object><object pk="128"></object><object pk="129"></object></field>
</object>
<object pk="125" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">appr-pr</field>
<field type="CharField" name="name">Approved - point raised</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG has approved the RFC status changes, but a point has been raised that should be cleared before proceeding to announcement to be sent</field>
<field type="IntegerField" name="order">5</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="126" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">appr-pend</field>
<field type="CharField" name="name">Approved - announcement to be sent</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The IESG has approved the RFC status changes, but the secretariat has not yet sent the announcement</field>
<field type="IntegerField" name="order">6</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="127"></object><object pk="128"></object></field>
</object>
<object pk="127" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">appr-sent</field>
<field type="CharField" name="name">Approved - announcement sent</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The secretariat has announced the IESG's approved RFC status changes</field>
<field type="IntegerField" name="order">7</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="128" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">withdraw</field>
<field type="CharField" name="name">Withdrawn</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The request for RFC status changes was withdrawn</field>
<field type="IntegerField" name="order">8</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="121"></object></field>
</object>
<object pk="129" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">dead</field>
<field type="CharField" name="name">Dead</field>
<field type="BooleanField" name="used">True</field>
<field type="TextField" name="desc">The RFC status changes have been abandoned</field>
<field type="IntegerField" name="order">9</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="121"></object></field>
</object>
<object pk="5" model="doc.ballottype">
<field to="name.doctypename" name="doc_type" rel="ManyToOneRel">conflrev</field>
<field type="SlugField" name="slug">conflrev</field>
@ -1852,6 +2108,15 @@
<field type="IntegerField" name="order">0</field>
<field to="name.ballotpositionname" name="positions" rel="ManyToManyRel"><object pk="yes"></object><object pk="noobj"></object><object pk="discuss"></object><object pk="abstain"></object><object pk="recuse"></object><object pk="norecord"></object></field>
</object>
<object pk="6" model="doc.ballottype">
<field to="name.doctypename" name="doc_type" rel="ManyToOneRel">statchg</field>
<field type="SlugField" name="slug">statchg</field>
<field type="CharField" name="name">Approve</field>
<field type="TextField" name="question">Do we approve these RFC status changes?</field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
<field to="name.ballotpositionname" name="positions" rel="ManyToManyRel"><object pk="yes"></object><object pk="noobj"></object><object pk="discuss"></object><object pk="abstain"></object><object pk="recuse"></object><object pk="norecord"></object></field>
</object>
<object pk="1" model="doc.ballottype">
<field to="name.doctypename" name="doc_type" rel="ManyToOneRel">charter</field>
<field type="SlugField" name="slug">r-extrev</field>
@ -1888,4 +2153,4 @@
<field type="IntegerField" name="order">3</field>
<field to="name.ballotpositionname" name="positions" rel="ManyToManyRel"><object pk="yes"></object><object pk="noobj"></object><object pk="block"></object><object pk="abstain"></object><object pk="norecord"></object></field>
</object>
</django-objects>
</django-objects>

View file

@ -0,0 +1,157 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
from ietf.name.models import DocTypeName, DocRelationshipName
class Migration(DataMigration):
def forwards(self, orm):
DocTypeName(slug='statchg',name='Status Change',used=True).save()
def backwards(self, orm):
pass
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.groupballotpositionname': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupBallotPositionName'},
'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']

View file

@ -0,0 +1,161 @@
# 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 field 'DocRelationshipName.revname'
db.add_column('name_docrelationshipname', 'revname', self.gf('django.db.models.fields.CharField')(default='fixme', max_length=255), keep_default=False)
def backwards(self, orm):
# Deleting field 'DocRelationshipName.revname'
db.delete_column('name_docrelationshipname', 'revname')
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'}),
'revname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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.groupballotpositionname': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupBallotPositionName'},
'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']

View file

@ -0,0 +1,177 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
from ietf.name.models import DocRelationshipName
class Migration(DataMigration):
def update_reverse_name(self,slug,revname):
relation = DocRelationshipName.objects.get(slug=slug)
relation.revname = revname
relation.save()
def forwards(self, orm):
revnames = { 'obs' : 'Obsoleted by',
'updates' : 'Updated by',
'replaces': 'Replaced by',
'conflrev': 'Conflict reviewed by',
}
for key in revnames:
self.update_reverse_name(key,revnames[key])
DocRelationshipName(slug='tops', name='Moves to Proposed Standard', revname='Moved to Proposed Standard by', used=True).save()
DocRelationshipName(slug='tois', name='Moves to Internet Standard', revname='Moved to Internet Standard by', used=True).save()
DocRelationshipName(slug='tohist', name='Moves to Historic', revname='Moved to Historic by', used=True).save()
DocRelationshipName(slug='toinf', name='Moves to Informational', revname='Moved to Informational by', used=True).save()
DocRelationshipName(slug='tobcp', name='Moves to BCP', revname='Moved to BCP by', used=True).save()
DocRelationshipName(slug='toexp', name='Moves to Experimental', revname='Moved to Experimental by', used=True).save()
def backwards(self, orm):
pass
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'}),
'revname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'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.groupballotpositionname': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupBallotPositionName'},
'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']

View file

@ -24,9 +24,12 @@ class RoleName(NameModel):
"""AD, Chair"""
class StreamName(NameModel):
"""IETF, IAB, IRTF, ISE, Legacy"""
class DocRelationshipName(NameModel):
"""Updates, Replaces, Obsoletes, Reviews, ... The relationship is
always recorded in one direction."""
revname = models.CharField(max_length=255)
class DocTypeName(NameModel):
"""Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email,
Review, Issue, Wiki"""

View file

@ -207,6 +207,8 @@ CHARTER_PATH = '/a/www/ietf-ftp/charters/'
CHARTER_TXT_URL = 'http://www.ietf.org/charter/'
CONFLICT_REVIEW_PATH = '/a/www/ietf-ftp/conflict-reviews'
CONFLICT_REVIEW_TXT_URL = 'http://www.ietf.org/cr/'
STATUS_CHANGE_PATH = '/a/www/ietf-ftp/status-changes'
STATUS_CHANGE_TXT_URL = 'http://www.ietf.org/sc/'
AGENDA_PATH = '/a/www/www6s/proceedings/'
AGENDA_PATH_PATTERN = '/a/www/www6s/proceedings/%(meeting)s/agenda/%(wg)s.%(ext)s'
MINUTES_PATH_PATTERN = '/a/www/www6s/proceedings/%(meeting)s/minutes/%(wg)s.%(ext)s'

View file

@ -40,7 +40,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<li><a href="{% url account_index %}">{% if request.user.is_authenticated %}Manage Account{% else %}New Account{% endif %}</a></li>
{% if user|in_group:"Area_Director" %}
<li class="sect first">AD Dashboard</li>
<li><a href="{% url doc_search_by_ad name=user.get_profile.person.full_name_as_key %}">My Documents</a></li>
<li><a href="{% url doc_search_by_ad name=user.get_profile.person.full_name_as_key %}">My Documents (old)</a></li>
<li><a href="{% url doc_search_by_ad2 name=user.get_profile.person.full_name_as_key %}">My Documents (new)</a></li>
<li><a href="{% url ietf.iesg.views.agenda_documents %}">Next Telechat</a></li>
<li><a href="{% url ietf.iesg.views.discusses %}">Discusses</a></li>
<li><a href="{% url ietf.iesg.views.working_group_actions %}">Working Groups</a></li>
@ -102,6 +103,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% else %}
<li><a href="http://{{ request.get_host }}/accounts/login/?next={{request.get_full_path|urlencode}}" rel="nofollow">Sign in to track drafts</a></li>
{% endif %}
{% if user|in_group:"Area_Director,Secretariat" %}
<li><a href="{% url rfc_status_changes %}">RFC status changes</a></li>
{% endif %}
<li class="sect">Meetings</li>

View file

@ -8,11 +8,11 @@
{% endblock %}
{% block title %}
Change the shepherding AD for the conflict review of {{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }}
Change the shepherding AD for {{titletext}}
{% endblock %}
{% block content %}
<h1>Change the shepherding AD for the conflict review of {{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }}</h1>
<h1>Change the shepherding AD for {{titletext}}</h1>
<form class="edit-info" action="" enctype="multipart/form-data" method="POST">
<table>
@ -29,7 +29,7 @@ Change the shepherding AD for the conflict review of {{ conflictdoc.canonical_na
<tr>
<td></td>
<td class="actions">
<a href="{% url doc_view name=review.canonical_name %}">Back</a>
<a href="{% url doc_view name=doc.canonical_name %}">Back</a>
<input type="submit" value="Submit"/>
</td>
</tr>

View file

@ -20,7 +20,7 @@ form.change-state .actions {
{% block content %}
<h1>Change State: {{doc.title}}</h1>
<p class="helptext">For help on the states, see the <a href="{% url help_conflict_review_states %}">state table</a>.</p>
<p class="helptext">For help on the states, see the <a href="{{help_url}}">state table</a>.</p>
<form class="change-state" action="" method="post">
<table>

View file

@ -1,8 +1,8 @@
{% load mail_filters %}{% autoescape off %}To: Internet Engineering Steering Group <iesg@ietf.org>
From: IESG Secretary <iesg-secretary@ietf.org>
Reply-To: IESG Secretary <iesg-secretary@ietf.org>
Subject: Evaluation: {{review.title}}
Subject: Evaluation: {{doc.title}}
Evaluation for {{ review.title }} can be found at <{{ review_url }}>
Evaluation for {{ doc.title }} can be found at <{{ doc_url }}>
{% endautoescape%}

View file

@ -11,11 +11,11 @@ form.edit-info #id_notify {
{% endblock %}
{% block title %}
Edit notification addresses for the conflict review of {{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }}
Edit notification addresses for {{titletext}}
{% endblock %}
{% block content %}
<h1>Edit notification addresses for the conflict review of {{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }}</h1>
<h1>Edit notification addresses for {{titletext}}</h1>
<form class="edit-info" action="" enctype="multipart/form-data" method="POST">
<table>
@ -32,7 +32,7 @@ Edit notification addresses for the conflict review of {{ conflictdoc.canonical_
<tr>
<td></td>
<td class="actions">
<a href="{% url doc_view name=review.canonical_name %}">Back</a>
<a href="{% url doc_view name=doc.canonical_name %}">Back</a>
<input type="submit" value="Submit"/>
</td>
</tr>

View file

@ -0,0 +1,25 @@
{% load mail_filters %}{% autoescape off %}From: The IESG <iesg-secretary@ietf.org>
To: IETF-Announce <ietf-announce@ietf.org>
Cc: RFC Editor <rfc-editor@rfc-editor.org>, {{status_change.notify}}
Subject: {{action}}: {{relateddoc.target.document.title}} to {{newstatus}}
{% filter wordwrap:73 %}The IESG has approved changing the status of the following document:
- {{relateddoc.target.document.title }}
({{relateddoc.target.document.canonical_name }}) to {{ newstatus }}
This {{action|lower}} is documented at:
{{status_change_url}}
A URL of the affected document is:
{{relateddoc_url}}
Status Change Details:
{{ approved_text }}
Personnel
{{status_change.ad.plain_name}} is the responsible Area Director.
{% endfilter %}
{% endautoescape %}

View file

@ -0,0 +1,41 @@
{% extends "base.html" %}
{% block title %}Approve {{doc.canonical_name }}{% endblock %}
{% block morecss %}
textarea[id^="id_form-"][id$="-announcement_text"] {
overflow-x: auto;
overflow-y: scroll;
width: 800px;
height: 400px;
border: 1px solid #bbb;
}
{% endblock %}
{% block content %}
<h1>Approve {{ doc.canonical_name }}</h1>
<form class="approve" action="" method="POST">
{{formset.management_form}}
<table>
{% for form in formset.forms %}
{% for field in form.visible_fields %}
<tr>
<td>
<div>{{ field.label_tag }}:</div>
{{ field }}
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
{{ field.errors }}
</td>
</tr>
{% endfor %}
{% endfor %}
<tr>
<td class="actions">
<a href="{% url doc_view name=doc.name %}">Back</a>
<input type="submit" value="Send out the announcement and close the ballot"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -0,0 +1,73 @@
{% extends "base.html" %}
{% block title %}Edit List of RFCs Affected By Status Change{% endblock %}
{% block morecss %}
form.start-rfc-status-change-review #id_notify {
width: 600px;
}
form.start-rfc-status-change-review #id_document_name {
width: 510px;
}
form.start-rfc-status-change-review .actions {
padding-top: 20px;
}
.warning {
font-weight: bold;
color: #a00;
}
{% endblock %}
{% block pagehead %}
{% include "doc/status_change/status-change-edit-relations-js.html" %}
{% endblock %}
{% block content %}
<h1>Edit List of RFCs Affected By Status Change</h1>
<form class="edit-status-change-rfcs" action="" method="post">
<table>
<th>Affects RFCs:</th>
<td><table><tbody id="relations_table">
{% for rfc,choice_slug in form.relations.items %}
<tr id="relation_row_{{rfc}}">
<td>
<input id="new_relation_row_{{rfc}}" name="new_relation_row_{{rfc}}"
type="text" maxlength="7"
value="{{rfc}}"
onchange="update_relation_row('relation_row_{{rfc}}')"/>
</td>
<td>
<select id="statchg_relation_row_{{rfc}}" name="statchg_relation_row_{{rfc}}"
style="vertical-align: top;">
<option value="" {% if choice_slug == "" %}selected="selected"{% endif %}>(None)</option>
{% for rel in relation_slugs %}
<option value="{{rel.slug}}" {% if choice_slug == rel.slug %}selected="selected"{%endif%}>{{rel.name}}</option>
{% endfor %}
</select>
<img src="/images/close.png" onclick="delete_relation('relation_row_{{rfc}}');"
style="cursor: pointer; padding-left: 4px;"/>
</td>
{% endfor %}
<tr id="relation_row_0">
<td>
<input id="new_relation_row_0" name="new_relation_row_0"
type="text" maxlength="7"
onkeypress="buff_out_row('relation_row_0');"
onchange="update_relation_row('relation_row_0')"/>
</td>
</tr>
</tbody></table>
<div class="help">Enter one of the affected RFC as RFCXXXX</div>
{{ form.non_field_errors }}
</td>
</tr>
<tr>
<td colspan="2" class="actions">
<input type="submit" value="Submit"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -0,0 +1,17 @@
Provide a description of what RFCs status are changed and any necessary rational for the change.
This is a good place to document how the RFC6410 criteria for advancing to Internet Standard are met:
(1) There are at least two independent interoperating implementations
with widespread deployment and successful operational experience.
(2) There are no errata against the specification that would cause a
new implementation to fail to interoperate with deployed ones.
(3) There are no unused features in the specification that greatly
increase implementation complexity.
(4) If the technology required to implement the specification
requires patented or otherwise controlled technology, then the
set of implementations must demonstrate at least two independent,
separate and successful uses of the licensing process.

View file

@ -0,0 +1,90 @@
{% extends "base.html" %}
{% block title %}Begin RFC status change review {% endblock %}
{% block morecss %}
form.start-rfc-status-change-review #id_notify {
width: 600px;
}
form.start-rfc-status-change-review #id_title {
width: 600px;
}
form.start-rfc-status-change-review #id_document_name {
width: 510px;
}
form.start-rfc-status-change-review .actions {
padding-top: 20px;
}
.warning {
font-weight: bold;
color: #a00;
}
{% endblock %}
{% block pagehead %}
{% include "doc/status_change/status-change-edit-relations-js.html" %}
{% endblock %}
{% block content %}
<h1>Begin RFC status change review</h1>
<p class="helptext">For help on the initial state choice, see the <a href="{% url help_status_change_states %}">state table</a>.</p>
<form class="start-rfc-status-change-review" action="" method="post">
<table>
<tr>
<th>Affects RFCs:</th>
<td><table><tbody id="relations_table">
{% for rfc,choice_slug in form.relations.items %}
<tr id="relation_row_{{rfc}}">
<td>
<input id="new_relation_row_{{rfc}}" name="new_relation_row_{{rfc}}"
type="text" maxlength="7"
value="{{rfc}}"
onchange="update_relation_row('relation_row_{{rfc}}')"/>
</td>
<td>
<select id="statchg_relation_row_{{rfc}}" name="statchg_relation_row_{{rfc}}"
style="vertical-align: top;">
<option value="" {% if choice_slug == "" %}selected="selected"{% endif %}>(None)</option>
{% for rel in relation_slugs %}
<option value="{{rel.slug}}" {% if choice_slug == rel.slug %}selected="selected"{%endif%}>{{rel.name}}</option>
{% endfor %}
</select>
<img src="/images/close.png" onclick="delete_relation('relation_row_{{rfc}}');"
style="cursor: pointer; padding-left: 4px;"/>
</td>
{% endfor %}
<tr id="relation_row_0">
<td>
<input id="new_relation_row_0" name="new_relation_row_0"
type="text" maxlength="7"
onkeypress="buff_out_row('relation_row_0');"
onchange="update_relation_row('relation_row_0')"/>
</td>
</tr>
</tbody></table>
<div class="help">Enter one of the affected RFC as RFCXXXX</div>
{{ form.non_field_errors }}
</td>
</tr>
{% for field in form.visible_fields %}
<tr>
<th>{{ field.label_tag }}:</th>
<td>
{% if field.label == "Document name" %}status-change-{% endif %}
{{ field }}
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
{{ field.errors }}
</td>
</tr>
{% endfor %}
<tr>
<td colspan="2" class="actions">
<input type="submit" value="Submit"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -0,0 +1,78 @@
<script type="text/javascript">
function buff_out_row(id)
{
setTimeout(function() {
var input = document.getElementById("new_"+id);
if (input.value!="")
{
input.removeAttribute("onkeypress");
buff_out_row_guts(id);
}
}, 0);
}
function buff_out_row_guts(id)
{
var buff_row = document.getElementById(id);
var td = document.createElement("td");
statchg = document.createElement("select");
statchg.name = "statchg_"+id;
statchg.id = "statchg_"+id;
option_empty = document.createElement("option");
option_empty.setAttribute("value","");
option_empty.setAttribute("selected","selected");
option_empty.innerHTML="(None)";
statchg.appendChild(option_empty);
{% for rel in relation_slugs %}
option_{{rel.slug}} = document.createElement("option");
option_{{rel.slug}}.setAttribute("value","{{rel.slug}}");
option_{{rel.slug}}.innerHTML="{{rel.name}}";
statchg.appendChild(option_{{rel.slug}});
{% endfor %}
statchg.style.verticalAlign="top";
td.appendChild(statchg);
xbutton = document.createElement("img");
xbutton.src="/images/close.png";
xbutton.setAttribute("onclick","delete_relation('"+id+"');");
xbutton.style.cursor="pointer";
xbutton.style.paddingLeft="4px";
td.appendChild(xbutton);
buff_row.appendChild(td);
var tr = document.createElement("tr");
var date = new Date;
var id = "relation_row_"+date.getTime();
tr.id = id;
var td2 = document.createElement("td");
var input= document.createElement("input");
input.type="text";
input.id="new_"+id;
input.name="new_"+id;
input.setAttribute("maxlength","7");
input.setAttribute("onchange","update_relation_row('"+id+"');");
input.setAttribute("onkeypress","buff_out_row('"+id+"');");
td2.appendChild(input);
tr.appendChild(td2);
buff_row.parentNode.appendChild(tr);
}
function update_relation_row(id)
{
/*
This hook exists to eventually do an asynch lookup to get the title of the RFC and display it
var update_row = document.getElementById(id);
var td = document.createElement("td");
td.innerHTML="TODO: fetch title of RFC and show it here";
update_row.appendChild(td);
*/
}
function delete_relation(id)
{
var leaving_row = document.getElementById(id);
leaving_row.parentNode.removeChild(leaving_row);
}
</script>

View file

@ -0,0 +1,23 @@
{% extends "base.html" %}
{% load ietf_filters %}
{% block title %}RFC Status Changes{% endblock %}
{% block content %}
<h1>RFC Status Changes</h1>
{% if user|in_group:"Area_Director,Secretariat" %}
<p><a href="{% url start_rfc_status_change name='' %}">Start new RFC status change document</a></p>
{% endif %}
{% regroup docs by get_state as state_groups %}
<table class="ietf-table ietf-doctable">
<tr><th class="doc">Document</th><th class="title">Title</th></tr>
{% for state in state_groups %}
<tr class="header"><td colspan="2">{{state.grouper}}</td></tr>
{% for doc in state.list %}
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
<td>{{ doc.displayname_with_link|safe }}</td>
<td>{{ doc.title }}</td>
</tr>
{% endfor %}
{% endfor %}
{% endblock content %}

View file

@ -0,0 +1,41 @@
{% extends "base.html" %}
{% block morecss %}
form #id_content {
width: 40em;
height: 450px;
}
{% endblock %}
{% block title %}
Edit status change text for {{doc.title}}
{% endblock %}
{% block content %}
<h1>Edit status change text for {{doc.title}}</h1>
<p>The text will be submitted as <strong>{{ doc.canonical_name }}-{{ next_rev }}</strong></p>
<form class="edit-info" action="" enctype="multipart/form-data" method="POST">
<table>
{% for field in form.visible_fields %}
<tr>
<th>{{ field.label_tag }}:</th>
<td>
{{ field }}
{% if field.help_text %}<div class="help">{{ field.help_text }}</div>{% endif %}
{{ field.errors }}
</td>
</tr>
{% endfor %}
<tr>
<td></td>
<td class="actions">
<a href="{% url doc_view name=doc.canonical_name %}">Back</a>
<input type="submit" name="reset_text" value="Reset to Template Text"/>
<input type="submit" name="submit_response" value="Submit"/>
</td>
</tr>
</table>
</form>
{% endblock %}

View file

@ -0,0 +1,88 @@
{% extends "base.html" %}
{% load ietf_filters %}
{% load ietf_streams_redesign %}
{% load ballot_icon_redesign %}
{% block title %}Documents for {{ ad_name }}{% endblock %}
{% block content %}
<h1>Documents for {{ ad_name }}</h1>
{% regroup docs by ad_dashboard_group as grouped_docs %}
<table class="ietf-table ietf-doctable">
<tr><th class="doc">Document</th><th class="title">Title</th><th class="date">Date</th><th class="status" colspan="2">Status</th><th class="ipr">ipr</th></tr>
{% for doc_group in grouped_docs %}
<tr class="header"><td colspan="7">{{doc_group.grouper}}s</td></tr>
{% for doc in doc_group.list %}
<tr class="{{ forloop.counter|divisibleby:2|yesno:"oddrow,evenrow" }}">
<td class="doc">
{#{{doc.ad_dashboard_sort_key}}<br/>#}
{% if doc.get_state_slug == 'rfc' %}
{{ doc.canonical_name|upper|rfcspace|urlize_ietf_docs }}<br/>{{ doc.name|urlize_ietf_docs }}
{% else %}
{{ doc.name|urlize_ietf_docs }}
{% endif %}
</td>
<td class="title">{{ doc.title }}</td>
<td class="date">
{% if doc.display_date %}
{% if doc.get_state_slug == 'rfc' %}
{{ doc.display_date|date:"Y-m"}}
{% else %}
{{ doc.display_date|date:"Y-m-d" }}
{% endif %}
{% if doc.display_date|timesince_days|new_enough:request %}
<br/><span class="ietf-small ietf-highlight-y">
{% if not doc.type.slug == 'draft' or doc.get_state_slug == 'rfc' %}
new
{% else %}
<a href="http:{{rfcdiff_prefix}}?url2={{doc.filename_with_rev}}">new</a>
{% endif %}
</span>
{% endif %}
{% if doc.can_expire and doc.expires and doc.expires|timesince_days|expires_soon:request %}
<br/><span class="ietf-small ietf-highlight-y">expires soon</span>
{%endif%}
{% endif %}
</td>
<td class="status">
{{ doc.friendly_state|safe }} {% if not doc.get_state_slug == 'rfc' %}{{ doc|state_age_colored|safe }}{% endif %}
{% if doc.on_upcoming_agenda %}<br/>IESG Telechat: {{ doc.telechat_date }}{% endif %}
{% if doc.get_state_slug == 'rfc' %}
{% if doc.obsoleted_by %}<br />Obsoleted by {{ doc.obsoleted_by|urlize_ietf_docs }}{%endif %}
{% if doc.updated_by %}<br />Updated by {{ doc.updated_by|urlize_ietf_docs }}{%endif %}
{% if doc.has_errata %}<br /><a href="http://www.rfc-editor.org/errata_search.php?rfc={{doc.rfc_number}}" rel="nofollow">Errata</a>{% endif %}
{% else %}{# not rfc #}
{% if doc.rfc_editor_state %}<br />RFC Editor State: <a href="http://www.rfc-editor.org/queue2.html#{{doc.name}}">{{ doc.rfc_editor_state|escape }}</a>{% endif %}
{% stream_state doc %}
{% endif %}
</td>
<td class="ballot">
{% ballot_icon doc %}
</td>
<td class="ipr">
{% if doc.iprCount %}<a href="{{ doc.iprUrl }}" rel="nofollow"> {{ doc.iprCount }} </a>{% endif %}
</td>
{% comment %}
{% include "idrfc/ipr_column.html" %}
{% endcomment %}
</tr>
{% endfor %}
{% endfor %}
</table>
{% endblock content %}

View file

@ -47,29 +47,32 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% block doc_metabuttons %}
{% if user|in_group:"Area_Director,Secretariat" %}
<div style="padding-bottom:2px;">
{% ifequal doc.draft_status "Expired" %}
{% if not doc.resurrect_requested_by %}
<span id="doc_request_resurrect_button" class="yui-button yui-link-button" style="margin-left:2px;"><span class="first-child"><a href="{% url doc_request_resurrect name=doc.draft_name %}">Request resurrect</a></span></span>
{% endif %}
{% if user|in_group:"Secretariat" %}
<span id="doc_resurrect_button" class="yui-button yui-link-button" style="margin-left:2px;"><span class="first-child"><a href="{% url doc_resurrect name=doc.draft_name %}">Resurrect</a></span></span>
{% endif %}
{% else %}
{% if stream_info.stream.name == 'ISE' or stream_info.stream.name == 'IRTF' %}
{% if user|in_group:"Secretariat" and not info.conflict_reviews %}
<span id="doc_conflict_review_button" class="yui-button yui-link-button" style="margin-left:2px;">{% url conflict_review_start name=doc.draft_name as start_review_url %}{% if start_review_url %}<span class="first-child"><a href="{{start_review_url}}">Begin IETF Conflict Review {% if not doc.underlying_document.intended_std_level %}(note that intended status is not set){% endif %}</a></span>{% endif %}</span>
{% endif %}
{% else %}
{% if stream_info.stream.name == 'IETF'%}{%if not doc.in_ietf_process %}
<span id="doc_add_button" class="yui-button yui-link-button" style="margin-left:2px;">{% url doc_edit_info name=doc.draft_name as doc_edit_url %}{% if doc_edit_url %}<span class="first-child"><a href="{{doc_edit_url}}">Begin IESG Processing</a></span>{% endif %}</span>
{% endif %}{% endif %}
{% endif %}
{% endifequal %}
</div>
<div style="padding-bottom:2px;">
{% ifequal doc.draft_status "Expired" %}
{% if not doc.resurrect_requested_by and user|in_group:"Area_Director" %}
<span id="doc_request_resurrect_button" class="yui-button yui-link-button" style="margin-left:2px;"><span class="first-child"><a href="{% url doc_request_resurrect name=doc.draft_name %}">Request resurrect</a></span></span>
{% endif %}
{% if user|in_group:"Secretariat" %}
<span id="doc_resurrect_button" class="yui-button yui-link-button" style="margin-left:2px;"><span class="first-child"><a href="{% url doc_resurrect name=doc.draft_name %}">Resurrect</a></span></span>
{% endif %}
{% else %} {# not expired #}
{% if stream_info.stream.name == 'ISE' or stream_info.stream.name == 'IRTF' %}
{% if user|in_group:"Secretariat" and not info.conflict_reviews %}
<span id="doc_conflict_review_button" class="yui-button yui-link-button" style="margin-left:2px;">{% url conflict_review_start name=doc.draft_name as start_review_url %}{% if start_review_url %}<span class="first-child"><a href="{{start_review_url}}">Begin IETF Conflict Review {% if not doc.underlying_document.intended_std_level %}(note that intended status is not set){% endif %}</a></span>{% endif %}</span>
{% endif %}
{% else %} {# Not a candidate for conflict review #}
{% if stream_info.stream.name == 'IETF' and not doc.in_ietf_process %}
<span id="doc_add_button" class="yui-button yui-link-button" style="margin-left:2px;">{% url doc_edit_info name=doc.draft_name as doc_edit_url %}{% if doc_edit_url %}<span class="first-child"><a href="{{doc_edit_url}}">Begin IESG Processing</a></span>{% endif %}</span>
{% else %}
{% if doc.underlying_document.get_state_slug == 'rfc' %}
<span id="doc_start_status_change" class="yui-button yui-link-button" style="margin-left:2px;">{% url start_rfc_status_change name=doc.underlying_document.canonical_name as start_url %}{% if start_url %}<span class="first-child"><a href="{{start_url}}">Start {% if info.proposed_status_changes %}An Additional {% endif %}Status Change</a></span>{% endif %}</span>
{% endif %}
{% endif %}
{% endif %}
{% endifequal %}
</div>
{% endif %}{# if user in group #}
{% endblock doc_metabuttons%}
{% endblock doc_metabuttons %}
</div> <!-- metabox -->
<div id="rfcText1">

View file

@ -41,6 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% if doc.updated_by %}<br />Updated by {{ doc.updated_by|urlize_ietf_docs }}{%endif %}
{% if doc.obsoletes %}<br />Obsoletes {{ doc.obsoletes|urlize_ietf_docs }}{%endif %}
{% if doc.updates %}<br />Updates {{ doc.updates|urlize_ietf_docs }}{%endif %}
{% if info.status_changes %}<br />Status changed by {{ info.status_changes|urlize_ietf_docs }}{% endif %}
{% if info.proposed_status_changes %}<br />Proposed status changes by {{ info.proposed_status_changes|urlize_ietf_docs }}{% endif %}
{% if doc.also %}<br />Also Known As {{ doc.also|urlize_ietf_docs }}{%endif %}
{% if doc.draft_name %}<br />Was <a href="/doc/{{ doc.draft_name}}/">{{doc.draft_name}}</a>{% endif %}
{% if doc.has_errata %}<br /><a href="http://www.rfc-editor.org/errata_search.php?rfc={{doc.rfc_number}}" rel="nofollow">Errata</a>{% endif %}

View file

@ -2,7 +2,7 @@
{% load ietf_filters %}
{% block title %}{{ doc.canonical_name }}-{{ doc.rev }}{% endblock %}
{% block title %}{{ doc.name }}-{{ doc.rev }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
@ -24,7 +24,7 @@
<div>
{% if snapshot %}Snapshot of{% endif %}
{% if doc.get_state_slug not in approved_states %}Proposed{% endif %}
IESG Conflict Review for the {{conflictdoc.stream}} document: <a href="{% url doc_view name=conflictdoc.canonical_name %}">{{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }}</a>
IESG Conflict Review for the {{conflictdoc.stream}} document: <a href="{% url doc_view name=conflictdoc.canonical_name %}">{{ conflictdoc.canonical_name }}{% if conflictdoc.get_state_slug != 'rfc' %}-{{ conflictdoc.rev }}{% endif %}</a>
</div>
<table id="metatable" width="100%">
@ -42,25 +42,26 @@
{% endif %}
</div>
{% if not snapshot %}
<div class="telechat">
</td>
</tr>
{% if not snapshot %}
<tr>
<td>Telechat Date:</td>
<td>
<a {% if not snapshot and user|has_role:"Area Director,Secretariat" and doc.get_state_slug not in approved_states %}
class="editlink" href="{% url conflict_review_telechat_date name=doc.name %}"
{%endif%} >
{% if not telechat %}Not on agenda of an IESG telechat{% else %}On agenda of {{ telechat.telechat_date|date:"Y-m-d" }} IESG telechat{% if doc.returning_item %} (returning item){% endif %}{% endif %}
</a>
</div>
{% if ballot_summary %}
<div class="ballot-summary">
({{ ballot_summary }})
</div>
{% endif %}
{% endif %}
</td>
</tr>
{% endif %}
<tr>
<td>Shepherding AD:</td>
@ -99,7 +100,7 @@
</div>
<h3>Conflict Review for {{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }}
<h3>Conflict Review for {{ conflictdoc.name }}-{{ conflictdoc.rev }}
{% if not snapshot and user|has_role:"Area Director,Secretariat" and doc.get_state_slug != 'apprsent' %}
<a class="edit" href="{% url conflict_review_submit name=doc.name %}">Change conflict review text</a>

View file

@ -0,0 +1,135 @@
{% extends "idrfc/doc_main.html" %}
{% load ietf_filters %}
{% block title %}{{ doc.canonical_name }}-{{ doc.rev }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
{% endblock %}
{% block content %}
{{ top|safe }}
<div class="snapshots">
Versions:
<span class="revisions">
{% for rev in revisions %}
<a {% if rev != doc.rev %}href="{% url doc_view name=doc.name %}{% if not forloop.last %}{{ rev }}/{% endif %}"{% endif %}>{{ rev }}</a>
{% endfor %}
</span>
</div>
<div class="ietf-box metabox">
<div>
{% if snapshot %}Snapshot of{% endif %}
{% if doc.get_state_slug not in approved_states %}Proposed{% endif %}
Status change : {{ doc.title }} </a>
</div>
<table id="metatable" width="100%">
{% regroup sorted_relations by relationship.name as relation_groups %}
{% for relation_group in relation_groups %}
<tr>
<td>{{relation_group.grouper}}:</td>
<td>{% for rel in relation_group.list %}{{rel.target.document.canonical_name|upper|urlize_ietf_docs}}{% if not forloop.last %}, {% endif %}{% endfor %}</td>
</tr>
{% endfor %}
<tr>
<td><a href="/doc/help/state/status-change/">Review State</a>:</td>
<td>
<div>
<a title="{{ doc.get_state.desc }}"{% if not snapshot and user|has_role:"Area Director,Secretariat" %} class="editlink" href="{% url status_change_change_state name=doc.name %}"{% endif %}>{{ doc.get_state.name }}</a>
{% if not snapshot and user|has_role:"Area Director,Secretariat" %}
{% if request.user|has_role:"Secretariat" %}{% if doc.get_state_slug = 'appr-pend' %}
- <a href="{% url status_change_approve name=doc.name %}">Approve RFC status changes</a>
{% endif %}{% endif %}
{% endif %}
</div>
</td>
</tr>
<tr>
<td>Telechat Date:</td>
<td>
{% if not snapshot %}
<a {% if not snapshot and user|has_role:"Area Director,Secretariat" and doc.get_state_slug not in approved_states %}
class="editlink" href="{% url status_change_telechat_date name=doc.name %}"
{%endif%} >
{% if not telechat %}Not on agenda of an IESG telechat{% else %}On agenda of {{ telechat.telechat_date|date:"Y-m-d" }} IESG telechat{% if doc.returning_item %} (returning item){% endif %}{% endif %}
</a>
{% if ballot_summary %}
<div class="ballot-summary">
({{ ballot_summary }})
</div>
{% endif %}
{% endif %}
</td>
</tr>
<tr>
<td>Shepherding AD:</td>
<td>
<a {% if not snapshot and user|has_role:"Area Director,Secretariat" and doc.get_state_slug not in approved_states %}
class="editlink" href="{% url status_change_ad name=doc.name %}"
{% endif %}
>
{{doc.ad}}
</a>
</td>
</tr>
<tr>
<td>Send notices to:</td>
<td>
<a {% if not snapshot and user|has_role:"Area Director,Secretariat" and doc.get_state_slug not in approved_states %}
class="editlink" href="{% url status_change_notices name=doc.name %}"
{% endif %}
>
{{doc.notify}}
</a>
</td>
</tr>
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
<tr><td>Last updated:</td><td> {{ doc.time|date:"Y-m-d" }}</td></tr>
{% if not snapshot and user|has_role:"Area Director,Secretariat" and doc.get_state_slug not in approved_states %}
<tr><td colspan="2">
<span id="doc_request_resurrect_button" class="yui-button yui-link-button" style="margin-left:2px;">
<span class="first-child">
<a href="{% url status_change_relations name=doc.name %}">Edit Affected RFC List</a>
</span>
</span>
</td><tr/>
{% endif %}
{% comment %}
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
{% endcomment %}
</table>
</div>
<h3>RFC Status Change : {{ doc.title }}
{% if not snapshot and user|has_role:"Area Director,Secretariat" and doc.get_state_slug != 'apprsent' %}
<a class="edit" href="{% url status_change_submit name=doc.name %}">Change status change text</a>
{% endif %}
</h3>
{% if doc.rev %}
<div class="markup_draft">
{{ content|fill:"80"|safe|linebreaksbr|keep_spacing|sanitize_html|safe }}
</div>
{% endif %}
{% endblock %}

View file

@ -39,7 +39,7 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% if title2_first %}{% if title1_first %}<h2>{{ title1 }}</h2>
{% endif %}
<h3>{{ title2 }}</h3>
{% if title2|startswith:"3.3" %}
{% if title2|startswith:"3.4" %}
<blockquote>
The IESG will use RFC 5742 responses: 1) The IESG has concluded
that there is no conflict between this document and IETF work; 2)

View file

@ -1,143 +0,0 @@
{% extends "base.html" %}
{% comment %}
Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the Nokia Corporation and/or its
subsidiary(-ies) nor the names of its contributors may be used
to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endcomment %}
{% load ballot_icon %}
{% load ietf_filters %}
{% block title %}Documents on Future IESG Telechat Agendas{% endblock %}
{% block morecss %}
.agenda_docs tr.oddrow {background-color: #EDF5FF; }
.agenda_docs tr.header.telechat_date { margin-top:10px; background:#2647A0; color: white;}
.agenda_docs tr.header.telechat_date td { font-size: 125%; }
.agenda_docs tr.header + tr.header { border-top: 2px solid white;}
.agenda_docs tr td {
vertical-align: top;
}
.agenda_docs tr .reschedule,
.agenda_docs tr .clear-returning-item {
font-size: 11px;
}
.agenda_docs tr .doc_pages {
font-size:80%; font-style:italic;
}
.secretariat-actions {
margin-bottom: 10px;
}
{% endblock %}
{% block pagehead %}
<link rel="alternate" type="application/atom+xml" href="/feed/iesg-agenda/" />
{% endblock %}
{% block content %}
<h1>Documents on Future IESG Telechat Agendas</h1>
<form action="" method="POST">
{% if user|in_group:"Secretariat" %}
<div class="secretariat-actions">
<button id="clear-all-on-schedule">Set all to not on agenda</button>
<input type="submit" value="Save"/>
</div>
{% endif %}
<table class="ietf-table ietf-doctable agenda_docs">
{% for t in telechats %}
{% if not forloop.first %}
<tr class="header"><td colspan="6">&nbsp;</td></tr>
{% endif %}
<tr class="header telechat_date"><td colspan="6">IESG telechat {{t.date}}</td></tr>
{% if forloop.first %}
<tr class="header"><td colspan="6"><a href="/iesg/agenda/">Full IESG Agenda</a></td></tr>
{% endif %}
<tr class="header"><td colspan="6"><a href="/iesg/agenda/telechat-{{t.date|date:"Y"}}-{{t.date|date:"m"}}-{{t.date|date:"d"}}-docs.tgz">Download Documents</a></td></tr>
<tr class="header"><td colspan="6">2. Protocol Actions</td></tr>
<tr class="header"><td colspan="6">2.1 WG Submissions</td></tr>
{% for doc in t.docs.s211 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s212 %}<tr class="header"><td colspan="6">2.1.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s212 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s213 %}<tr class="header"><td colspan="6">2.1.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s213 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="6">2.2 Individual Submissions</td></tr>
{% for doc in t.docs.s221 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s222 %}<tr class="header"><td colspan="6">2.2.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s222 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s223 %}<tr class="header"><td colspan="6">2.2.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s223 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="6">3. Document Actions</td></tr>
<tr class="header"><td colspan="6">3.1 WG Submissions</td></tr>
{% for doc in t.docs.s311 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s312 %}<tr class="header"><td colspan="6">3.1.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s312 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s313 %}<tr class="header"><td colspan="6">3.1.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s313 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="6">3.2 Individual Submissions Via AD</td></tr>
{% for doc in t.docs.s321 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s322 %}<tr class="header"><td colspan="6">3.2.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s322 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s323 %}<tr class="header"><td colspan="6">3.2.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s323 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="6">3.3 IRTF and Independent Submission Stream Documents</td></tr>
{% for doc in t.docs.s331 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s332 %}<tr class="header"><td colspan="6">3.3.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s332 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s333 %}<tr class="header"><td colspan="6">3.3.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s333 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% endfor %}
</table>
</form>
{% endblock content %}
{% block content_end %}
<script type="text/javascript" src="/js/agenda-documents.js"></script>
{% endblock %}

View file

@ -105,6 +105,14 @@ font-size:80%; font-style:italic;
{% if t.docs.s223 %}<tr class="header"><td colspan="6">2.2.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s223 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
<tr class="header"><td colspan="6">2.3 Status Changes</td></tr>
{% for doc in t.docs.s231 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
{% if t.docs.s222 %}<tr class="header"><td colspan="6">2.3.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s232 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
{% if t.docs.s223 %}<tr class="header"><td colspan="6">2.3.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s233 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
<tr class="header"><td colspan="6">3. Document Actions</td></tr>
<tr class="header"><td colspan="6">3.1 WG Submissions</td></tr>
@ -123,7 +131,7 @@ font-size:80%; font-style:italic;
{% if t.docs.s323 %}<tr class="header"><td colspan="6">3.2.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s323 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
<tr class="header"><td colspan="6">3.3 IRTF and Independent Submission Stream Documents</td></tr>
<tr class="header"><td colspan="6">3.3 Status Changes</td></tr>
{% for doc in t.docs.s331 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
{% if t.docs.s332 %}<tr class="header"><td colspan="6">3.3.2 Returning Item</td></tr>{% endif %}
@ -131,6 +139,14 @@ font-size:80%; font-style:italic;
{% if t.docs.s333 %}<tr class="header"><td colspan="6">3.3.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s333 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
<tr class="header"><td colspan="6">3.4 IRTF and Independent Submission Stream Documents</td></tr>
{% for doc in t.docs.s341 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
{% if t.docs.s342 %}<tr class="header"><td colspan="6">3.4.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s342 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
{% if t.docs.s343 %}<tr class="header"><td colspan="6">3.4.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s343 %}{% include "iesg/agenda_documents_row_redesign.html" %}{%endfor%}
<tr class="header"><td colspan="6">4. Working Group Actions</td></tr>
{% if t.docs.s411 or t.docs.s412%}<tr class="header"><td colspan="6">4.1 WG Creation</td></tr>{% endif %}

View file

@ -73,8 +73,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endwith %}{# title2 #}
{% with "2.3 Status Changes" as title2 %}
{% with 1 as title2_first %}
{% with "2.3.1 New Items" as title3 %}
{% with docs.s231 as section_docs %}{% include doc_template %}{% endwith %}
{% endwith %}
{% endwith %}{# title2_first #}
{% with "2.3.2 Returning Items" as title3 %}
{% with docs.s232 as section_docs %}{% include doc_template %}{% endwith %}
{% endwith %}
{% if docs.s233 %}
{% with "2.3.3 For Action" as title3 %}
{% with docs.s233 as section_docs %}{% include doc_template %}{% endwith %}
{% endwith %}
{% endif %}
{% endwith %}{# title2 #}
{% endwith %}{# title1 #}
{% with "3. Document Actions" as title1 %}{% with 1 as title1_first %}
{% with "3.1 WG Submissions" as title2 %}
@ -119,21 +140,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endwith %}{# title2 #}
{% with "3.3 IRTF and Independent Submission Stream Documents" as title2 %}
{% with "3.3 Status Changes" as title2 %}
{% with 1 as title2_first %}
{% with "3.3.1 New Items" as title3 %}
{% with docs.s331 as section_docs %}{% include doc_conflict_template %}{% endwith %}
{% with docs.s331 as section_docs %}{% include doc_template %}{% endwith %}
{% endwith %}
{% endwith %}{# title2_first #}
{% with "3.3.2 Returning Items" as title3 %}
{% with docs.s332 as section_docs %}{% include doc_conflict_template %}{% endwith %}
{% with docs.s332 as section_docs %}{% include doc_template %}{% endwith %}
{% endwith %}
{% if docs.s333 %}
{% with "3.3.3 For Action" as title3 %}
{% with docs.s333 as section_docs %}{% include doc_conflict_template %}{% endwith %}
{% with docs.s333 as section_docs %}{% include doc_template %}{% endwith %}
{% endwith %}
{% endif %}
{% endwith %} {# title2 #}
{% with "3.4 IRTF and Independent Submission Stream Documents" as title2 %}
{% with 1 as title2_first %}
{% with "3.4.1 New Items" as title3 %}
{% with docs.s341 as section_docs %}{% include doc_conflict_template %}{% endwith %}
{% endwith %}
{% endwith %}{# title2_first #}
{% with "3.4.2 Returning Items" as title3 %}
{% with docs.s342 as section_docs %}{% include doc_conflict_template %}{% endwith %}
{% endwith %}
{% if docs.s343 %}
{% with "3.4.3 For Action" as title3 %}
{% with docs.s343 as section_docs %}{% include doc_conflict_template %}{% endwith %}
{% endwith %}
{% endif %}

View file

@ -60,11 +60,6 @@ Last call ends: {{ doc.obj.most_recent_ietflc.expires.date|default:"(none)" }}
{% endfor %}
</pre></small>
{% if title1|startswith:"2." %}
<p>____ open positions<br>
[ &nbsp; ] would you like to record a position?</p>
{% endif %}
<p>____ active discusses<br>
[ &nbsp; ] there are [#] discusses in the tracker on this document. Do we need to talk about them now?</p>
@ -72,13 +67,10 @@ Last call ends: {{ doc.obj.most_recent_ietflc.expires.date|default:"(none)" }}
<p>(Ballot not issued)</p>
{% endif %}
{% if title2|startswith:"3.1" or title2|startswith:"3.2" %}
<p>Does anyone have an[y further] objection to this document being published as an {{ doc.obj.intended_std_level }} RFC?</p>
{% endif %}
{% if title3|startswith:"3.3.1" or title3|startswith:"3.3.2" %}
{% if title3|startswith:"3.4.1" or title3|startswith:"3.4.2" %}
<p>Does anyone have an objection to the RFC Editor publishing this document as an {{ doc.obj.intended_std_level }} RFC?</p>
{% endif %}
{% if title3|startswith:"3.3.3" %}
{% if title3|startswith:"3.4.3" %}
<p>Who will do the review of this document?</p>
{% endif %}
@ -86,45 +78,7 @@ Last call ends: {{ doc.obj.most_recent_ietflc.expires.date|default:"(none)" }}
Next State:<br>
Sub State: </p>
{% if title3|startswith:"2.1.1" or title3|startswith:"2.1.2" %}
<p>If APPROVED - The Secretariat will send a working group
submission, Protocol Action Announcement.</p>
<p>If APPROVED with caveats - The Secretariat will send a working
group submission, Protocol Action Announcement that includes the
[RFC Editor Note, IESG Note, etc.] to be drafted by [Name that
AD].</p>
{% endif %}
{% if title3|startswith:"2.2.1" or title3|startswith:"2.2.2" %}
<p>If APPROVED - The Secretariat will send an individual submission,
Protocol Action Announcement.</p>
<p>If APPROVED with caveats - The Secretariat will send an
individual submission, Protocol Action Announcement that includes
the [RFC Editor Note, IESG Note, etc.] to be drafted by [Name that
AD].</p>
{% endif %}
{% if title3|startswith:"3.1.1" or title3|startswith:"3.1.2" %}
<p>If APPROVED - The Secretariat will send a working group submission
Document Action Announcement.</p>
<p>If APPROVED with caveats - The Secretariat will send a working
group submission Document Action announcement that includes the [RFC
Ed. Note, IESG, note, etc.] from [Name that AD].</p>
{% endif %}
{% if title3|startswith:"3.2.1" or title3|startswith:"3.2.2" %}
<p>If APPROVED - The Secretariat will send an individual submission
Document Action Announcement.</p>
<p>If APPROVED with caveats - The Secretariat will send an
individual submission Document Action announcement that includes the
[RFC Ed. Note, IESG, note, etc.] from [Name that AD].</p>
{% endif %}
{% if title3|startswith:"3.3.1" or title3|startswith:"3.3.2" %}
{% if title3|startswith:"3.4.1" or title3|startswith:"3.4.2" %}
<p>If APPROVED - The Secretariat will send a standard no problem
message to the RFC Editor. [Name of AD] will you supply the text for
the IESG Note?</p>

View file

@ -102,6 +102,16 @@ Sub State: </p>
AD].</p>
{% endif %}
{% if title3|startswith:"2.3.1" or title3|startswith:"2.3.2" %}
<p>If APPROVED - The Secretariat will send the associated status change
Protocol Action Announcements.</p>
<p>If APPROVED with caveats - The Secretariat will send the
associated status change Protocol Action Announcements that includes the
[RFC Editor Note, IESG Note, etc.] to be drafted by [Name that
AD].</p>
{% endif %}
{% if title3|startswith:"3.1.1" or title3|startswith:"3.1.2" %}
<p>If APPROVED - The Secretariat will send a working group submission
Document Action Announcement.</p>
@ -121,6 +131,15 @@ Sub State: </p>
{% endif %}
{% if title3|startswith:"3.3.1" or title3|startswith:"3.3.2" %}
<p>If APPROVED - The Secretariat will send the associated status change
Document Action Announcements.</p>
<p>If APPROVED with caveats - The Secretariat will send the associated
status change Document Action announcements that includes the [RFC
Ed. Note, IESG, note, etc.] from [Name that AD].</p>
{% endif %}
{% if title3|startswith:"3.4.1" or title3|startswith:"3.4.2" %}
<p>If APPROVED - The Secretariat will send a standard no problem
message to the RFC Editor. [Name of AD] will you supply the text for
the IESG Note?</p>

View file

@ -60,6 +60,9 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% for doc in docs.s221 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s222 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s223 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s231 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s232 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s233 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s311 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s312 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s313 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
@ -69,6 +72,9 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% for doc in docs.s331 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s332 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s333 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s341 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s342 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% for doc in docs.s343 %}{% include "iesg/scribe_doc2.html" %}{%endfor%}
{% endfilter %}
</body>

View file

@ -126,7 +126,7 @@ th {
<tr>
<th>{{person_form.ascii_short.label}}:</th>
<td></td>
<td colspan='2'>{{person_form.ascii_short}} - Short form, if any, of your name as renedered in ASCII (blank is okay)</td>
<td colspan='2'>{{person_form.ascii_short}} - Short form, if any, of your name as rendered in ASCII (blank is okay)</td>
</tr>
<tr>
<th>{{person_form.affiliation.label}}:</th>

View file

@ -400,4 +400,22 @@ def make_test_data():
crdoc.save()
crdoc.relateddocument_set.create(target=docalias,relationship_id='conflrev')
# A status change mid review
doc = Document.objects.create(name='status-change-imaginary-mid-review',type_id='statchg', rev='00', notify="fsm@ietf.org")
doc.set_state(State.objects.get(slug='needshep',type__slug='statchg'))
doc.save()
docalias = DocAlias.objects.create(name='status-change-imaginary-mid-review',document=doc)
# Some things for a status change to affect
target_rfc = Document.objects.create(name='draft-ietf-random-thing', type_id='draft', std_level_id='ps')
target_rfc.set_state(State.objects.get(slug='rfc',type__slug='draft'))
target_rfc.save()
docalias = DocAlias.objects.create(name='draft-ietf-random-thing',document=target_rfc)
docalias = DocAlias.objects.create(name='rfc9999',document=target_rfc)
target_rfc = Document.objects.create(name='draft-ietf-random-otherthing', type_id='draft', std_level_id='inf')
target_rfc.set_state(State.objects.get(slug='rfc',type__slug='draft'))
target_rfc.save()
docalias = DocAlias.objects.create(name='draft-ietf-random-otherthing',document=target_rfc)
docalias = DocAlias.objects.create(name='rfc9998',document=target_rfc)
return draft

View file

@ -204,7 +204,7 @@ class ManageWorkflowTestCase(django.test.TestCase):
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q("form.set-state").find("input[name=state][value=%s]" % state.pk).parents("form").find("input[name=active][value=0]")), 1)
self.assertEquals(len(q("form.set-state").find("input[name=state][value=\"%s\"]" % state.pk).parents("form").find("input[name=active][value=\"0\"]")), 1)
# deactivate state
r = self.client.post(url,
@ -213,7 +213,7 @@ class ManageWorkflowTestCase(django.test.TestCase):
active="0"))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q("form.set-state").find("input[name=state][value=%s]" % state.pk).parents("form").find("input[name=active][value=1]")), 1)
self.assertEquals(len(q("form.set-state").find("input[name=state][value=\"%s\"]" % state.pk).parents("form").find("input[name=active][value=\"1\"]")), 1)
group = Group.objects.get(acronym=group.acronym)
self.assertTrue(state in group.unused_states.all())
@ -226,7 +226,7 @@ class ManageWorkflowTestCase(django.test.TestCase):
next_states=next_states))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q("form.set-next-states").find("input[name=state][value=%s]" % state.pk).parents('form').find("input[name=next_states][checked=checked]")), len(next_states))
self.assertEquals(len(q("form.set-next-states").find("input[name=state][value=\"%s\"]" % state.pk).parents('form').find("input[name=next_states][checked=checked]")), len(next_states))
transitions = GroupStateTransitions.objects.filter(group=group, state=state)
self.assertEquals(len(transitions), 1)
self.assertEquals(set(transitions[0].next_states.values_list("pk", flat=True)), set(next_states))