Merge forward complete
- Legacy-Id: 5328
This commit is contained in:
parent
31a02c097e
commit
589ff698ee
37
ietf/doc/forms.py
Normal file
37
ietf/doc/forms.py
Normal 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)
|
427
ietf/doc/migrations/0005_add_statchg.py
Normal file
427
ietf/doc/migrations/0005_add_statchg.py
Normal 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']
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
|
||||
from ietf.doc.tests_conflict_review import *
|
||||
from ietf.doc.tests_status_change import *
|
||||
|
|
392
ietf/doc/tests_status_change.py
Normal file
392
ietf/doc/tests_status_change.py
Normal 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')
|
||||
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)
|
12
ietf/doc/urls_status_change.py
Normal file
12
ietf/doc/urls_status_change.py
Normal 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'),
|
||||
)
|
||||
|
|
@ -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,
|
||||
|
|
596
ietf/doc/views_status_change.py
Normal file
596
ietf/doc/views_status_change.py
Normal file
|
@ -0,0 +1,596 @@
|
|||
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)
|
||||
|
||||
# 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']
|
||||
if Document.objects.filter(name='status-change-%s'%name):
|
||||
raise forms.ValidationError("status-change-%s already exists"%name)
|
||||
return name
|
||||
|
||||
def clean(self):
|
||||
return clean_helper(self,StartStatusChangeForm)
|
||||
|
||||
#TODO - cleaned data, especially on document_name
|
||||
|
||||
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):
|
||||
"""Start the RFC status change review process, setting the initial shepherding AD, and possibly putting the review on a telechat."""
|
||||
|
||||
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 = {
|
||||
}
|
||||
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))
|
|
@ -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,6 +41,8 @@ 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/$', 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'^(?P<name>[A-Za-z0-9._+-]+)/((?P<rev>[0-9-]+)/)?$', views_doc.document_main, name="doc_view"),
|
||||
|
@ -81,11 +84,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'),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -60,14 +60,14 @@ def render_document_top(request, doc, tab, name):
|
|||
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 +190,33 @@ 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())
|
||||
|
||||
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=doc.relateddocument_set.all().order_by('relationship__name'),
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
raise Http404()
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -313,14 +359,14 @@
|
|||
<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>
|
||||
|
@ -361,6 +407,12 @@
|
|||
<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="ietf" model="name.grouptypename">
|
||||
<field type="CharField" name="name">IETF</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
|
@ -415,6 +467,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 +617,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>
|
||||
|
@ -760,6 +824,9 @@
|
|||
<object pk="conflrev" model="doc.statetype">
|
||||
<field type="CharField" name="label">Conflict 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 +899,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>
|
||||
|
@ -1363,6 +1448,15 @@
|
|||
<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="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 +1937,87 @@
|
|||
<field type="IntegerField" name="order">2</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">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="103"></object><object pk="109"></object><object pk="110"></object></field>
|
||||
</object>
|
||||
<object pk="103" 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="104"></object><object pk="109"></object><object pk="110"></object></field>
|
||||
</object>
|
||||
<object pk="104" 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="105"></object><object pk="106"></object><object pk="107"></object><object pk="109"></object><object pk="110"></object></field>
|
||||
</object>
|
||||
<object pk="105" 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="104"></object><object pk="106"></object><object pk="107"></object><object pk="109"></object><object pk="110"></object></field>
|
||||
</object>
|
||||
<object pk="106" 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="107" 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="108"></object><object pk="109"></object></field>
|
||||
</object>
|
||||
<object pk="108" 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="109" 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="102"></object></field>
|
||||
</object>
|
||||
<object pk="110" 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="102"></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 +2027,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>
|
||||
|
|
157
ietf/name/migrations/0005_add_newstat.py
Normal file
157
ietf/name/migrations/0005_add_newstat.py
Normal 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']
|
161
ietf/name/migrations/0006_add_revname_column.py
Normal file
161
ietf/name/migrations/0006_add_revname_column.py
Normal 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']
|
177
ietf/name/migrations/0007_reverse_relation_names.py
Normal file
177
ietf/name/migrations/0007_reverse_relation_names.py
Normal 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']
|
|
@ -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"""
|
||||
|
|
|
@ -206,6 +206,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'
|
||||
|
|
|
@ -102,6 +102,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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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%}
|
|
@ -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>
|
25
ietf/templates/doc/status_change/approval_text.txt
Normal file
25
ietf/templates/doc/status_change/approval_text.txt
Normal 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 %}
|
41
ietf/templates/doc/status_change/approve.html
Normal file
41
ietf/templates/doc/status_change/approve.html
Normal 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 %}
|
73
ietf/templates/doc/status_change/edit_relations.html
Normal file
73
ietf/templates/doc/status_change/edit_relations.html
Normal 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 %}
|
17
ietf/templates/doc/status_change/initial_template.txt
Normal file
17
ietf/templates/doc/status_change/initial_template.txt
Normal 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.
|
89
ietf/templates/doc/status_change/start.html
Normal file
89
ietf/templates/doc/status_change/start.html
Normal file
|
@ -0,0 +1,89 @@
|
|||
{% 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_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>
|
||||
{% 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>
|
||||
{% if field.label == "Document name" %}
|
||||
<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>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td colspan="2" class="actions">
|
||||
<input type="submit" value="Submit"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -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>
|
23
ietf/templates/doc/status_change/status_changes.html
Normal file
23
ietf/templates/doc/status_change/status_changes.html
Normal 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 %}">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 %}
|
||||
|
41
ietf/templates/doc/status_change/submit.html
Normal file
41
ietf/templates/doc/status_change/submit.html
Normal 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 %}
|
|
@ -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>
|
||||
|
|
135
ietf/templates/idrfc/document_status_change.html
Normal file
135
ietf/templates/idrfc/document_status_change.html
Normal 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 %}
|
||||
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue