Remove .state and .*_state on Document in favour of generic states

mapping, port the codebase to use these states
 - Legacy-Id: 3660
This commit is contained in:
Ole Laursen 2011-11-16 18:18:06 +00:00
parent 64c3ef01c0
commit 5d291f222c
34 changed files with 705 additions and 640 deletions

View file

@ -4,14 +4,14 @@ from django.conf import settings
from django.template.loader import render_to_string
from django.db.models import Q
import datetime, os, shutil, glob, re
import datetime, os, shutil, glob, re, itertools
from ietf.idtracker.models import InternetDraft, IDDates, IDStatus, IDState, DocumentComment, IDAuthor,WGChair
from ietf.utils.mail import send_mail, send_mail_subj
from ietf.idrfc.utils import log_state_changed, add_document_comment
from doc.models import Document, DocEvent, save_document_in_history
from name.models import IesgDocStateName, DocStateName, DocTagName
from person.models import Person, Email
from redesign.doc.models import Document, DocEvent, save_document_in_history, State
from redesign.name.models import DocTagName
from redesign.person.models import Person, Email
INTERNET_DRAFT_DAYS_TO_EXPIRE = 185
@ -36,7 +36,11 @@ def document_expires(doc):
return None
def expirable_documents():
return Document.objects.filter(state="active").exclude(tags="rfc-rev").filter(Q(iesg_state=None) | Q(iesg_state__order__gte=42))
d = Document.objects.filter(states__type="draft", states__slug="active").exclude(tags="rfc-rev")
# we need to get those that either don't have a state or have a
# state >= 42 (AD watching), unfortunately that doesn't appear to
# be possible to get to work directly in Django 1.1
return itertools.chain(d.exclude(states__type="draft-iesg").distinct(), d.filter(states__type="draft-iesg", states__order__gte=42).distinct())
def get_soon_to_expire_ids(days):
start_date = datetime.date.today() - datetime.timedelta(InternetDraft.DAYS_TO_EXPIRE - 1)
@ -104,7 +108,8 @@ def send_expire_warning_for_idREDESIGN(doc):
if doc.group.type_id != "individ":
cc = [e.formatted_email() for e in Email.objects.filter(role__group=doc.group, role__name="chair") if not e.address.startswith("unknown-email")]
state = doc.iesg_state.name if doc.iesg_state else "I-D Exists"
s = doc.get_state("draft-iesg")
state = s.name if s else "I-D Exists"
frm = None
request = None
@ -138,8 +143,9 @@ def send_expire_notice_for_idREDESIGN(doc):
if not doc.ad:
return
state = doc.iesg_state.name if doc.iesg_state else "I-D Exists"
s = doc.get_state("draft-iesg")
state = s.name if s else "I-D Exists"
request = None
to = doc.ad.formatted_email()
send_mail(request, to,
@ -216,10 +222,10 @@ def expire_idREDESIGN(doc):
save_document_in_history(doc)
if doc.latest_event(type='started_iesg_process'):
dead_state = IesgDocStateName.objects.get(slug="dead")
if doc.iesg_state != dead_state:
prev = doc.iesg_state
doc.iesg_state = dead_state
dead_state = State.objects.get(type="draft-iesg", slug="dead")
prev = doc.get_state("draft-iesg")
if prev != dead_state:
doc.set_state(dead_state)
log_state_changed(None, doc, system, prev)
e = DocEvent(doc=doc, by=system)
@ -228,7 +234,7 @@ def expire_idREDESIGN(doc):
e.save()
doc.rev = new_revision # FIXME: incrementing the revision like this is messed up
doc.state = DocStateName.objects.get(slug="expired")
doc.set_state(State.objects.get(type="draft", slug="expired"))
doc.time = datetime.datetime.now()
doc.save()
@ -334,10 +340,10 @@ def clean_up_id_filesREDESIGN():
try:
doc = Document.objects.get(name=filename, rev=revision)
if doc.state_id == "rfc":
if doc.get_state_slug() == "rfc":
if ext != ".txt":
move_file_to("unknown_ids")
elif doc.state_id in ("expired", "auth-rm", "repl", "ietf-rm"):
elif doc.get_state_slug() in ("expired", "repl", "auth-rm", "ietf-rm"):
e = doc.latest_event(type__in=('expired_document', 'new_revision', "completed_resurrect"))
expiration_date = e.time.date() if e and e.type == "expired_document" else None

View file

@ -121,11 +121,11 @@ class IdWrapper:
def rfc_editor_state(self):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
if self._draft.rfc_state:
s = self._draft.get_state("draft-rfceditor")
if s:
# extract possible extra states
tags = self._draft.tags.filter(slug__in=("iana-crd", "ref", "missref"))
s = [self._draft.rfc_state.name] + [t.slug.replace("-crd", "").upper() for t in tags]
return " ".join(s)
return " ".join([s.name] + [t.slug.replace("-crd", "").upper() for t in tags])
else:
return None

View file

@ -8,8 +8,7 @@ from ietf.idtracker.models import InternetDraft, DocumentComment, BallotInfo
from ietf.idrfc.mails import *
from ietf.idrfc.utils import *
from doc.models import Document, DocEvent, LastCallDocEvent, WriteupDocEvent, save_document_in_history
from name.models import IesgDocStateName
from doc.models import Document, DocEvent, LastCallDocEvent, WriteupDocEvent, save_document_in_history, State
from person.models import Person
def request_last_call(request, doc):
@ -47,7 +46,7 @@ def get_expired_last_calls():
def get_expired_last_callsREDESIGN():
today = datetime.date.today()
for d in Document.objects.filter(iesg_state="lc"):
for d in Document.objects.filter(states__type="draft-iesg", states__slug="lc"):
e = d.latest_event(LastCallDocEvent, type="sent_last_call")
if e and e.expires.date() <= today:
yield d
@ -71,18 +70,18 @@ def expire_last_call(doc):
email_last_call_expired(doc)
def expire_last_callREDESIGN(doc):
state = IesgDocStateName.objects.get(slug="writeupw")
state = State.objects.get(type="draft-iesg", slug="writeupw")
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
if e and "What does this protocol do and why" not in e.text:
# if it boiler-plate text has been removed, we assume the
# if boiler-plate text has been removed, we assume the
# write-up has been written
state = IesgDocStateName.objects.get(slug="goaheadw")
state = State.objects.get(type="draft-iesg", slug="goaheadw")
save_document_in_history(doc)
prev = doc.iesg_state
doc.iesg_state = state
prev = doc.get_state("draft-iesg")
doc.set_state(state)
e = log_state_changed(None, doc, Person.objects.get(name="(System)"), prev)
doc.time = e.time

View file

@ -269,7 +269,7 @@ def generate_approval_mail_rfc_editor(request, doc):
DO_NOT_PUBLISH_IESG_STATES = ("nopubadw", "nopubanw")
def generate_approval_mailREDESIGN(request, doc):
if doc.iesg_state_id in DO_NOT_PUBLISH_IESG_STATES or doc.tags.filter(slug='via-rfc'):
if doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES or doc.tags.filter(slug='via-rfc'):
mail = generate_approval_mail_rfc_editor(request, doc)
else:
mail = generate_approval_mail_approved(request, doc)
@ -320,7 +320,7 @@ def generate_approval_mail_approved(request, doc):
else:
contacts = "The IESG contact person is %s." % director.name
doc_type = "RFC" if doc.state_id == "rfc" else "Internet Draft"
doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft"
return render_to_string("idrfc/approval_mail.txt",
dict(doc=doc,
@ -338,8 +338,8 @@ def generate_approval_mail_approved(request, doc):
def generate_approval_mail_rfc_editorREDESIGN(request, doc):
full_status = full_intended_status(doc.intended_std_level.name)
status = full_status.replace("a ", "").replace("an ", "")
disapproved = doc.iesg_state_id in DO_NOT_PUBLISH_IESG_STATES
doc_type = "RFC" if doc.state_id == "rfc" else "Internet Draft"
disapproved = doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES
doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft"
return render_to_string("idrfc/approval_mail_rfc_editor.txt",
dict(doc=doc,
@ -619,7 +619,7 @@ def email_last_call_expired(doc):
cc="iesg-secretary@ietf.org")
def email_last_call_expiredREDESIGN(doc):
text = "IETF Last Call has ended, and the state has been changed to\n%s." % doc.iesg_state.name
text = "IETF Last Call has ended, and the state has been changed to\n%s." % doc.get_state("draft-iesg").name
send_mail(None,
"iesg@ietf.org",

View file

@ -197,8 +197,8 @@ import django.db.transaction
def get_rfc_tag_mapping():
"""Return dict with RFC Editor state name -> DocTagName"""
from name.models import DocTagName
from name.utils import name
from redesign.name.models import DocTagName
from redesign.name.utils import name
return {
'IANA': name(DocTagName, 'iana-crd', 'IANA coordination', "RFC-Editor/IANA Registration Coordination"),
@ -207,22 +207,21 @@ def get_rfc_tag_mapping():
}
def get_rfc_state_mapping():
"""Return dict with RFC Editor state name -> RfcDocStateName"""
from name.models import RfcDocStateName
from name.utils import name
"""Return dict with RFC Editor state name -> State"""
from redesign.doc.models import State, StateType
t = StateType.objects.get(slug="draft-rfceditor")
return {
'AUTH': name(RfcDocStateName, 'auth', 'AUTH', "Awaiting author action"),
'AUTH48': name(RfcDocStateName, 'auth48', "AUTH48", "Awaiting final author approval"),
'EDIT': name(RfcDocStateName, 'edit', 'EDIT', "Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing"),
'IANA': name(RfcDocStateName, 'iana-crd', 'IANA', "RFC-Editor/IANA Registration Coordination"),
'IESG': name(RfcDocStateName, 'iesg', 'IESG', "Holding for IESG action"),
'ISR': name(RfcDocStateName, 'isr', 'ISR', "Independent Submission Review by the ISE "),
'ISR-AUTH': name(RfcDocStateName, 'isr-auth', 'ISR-AUTH', "Independent Submission awaiting author update, or in discussion between author and ISE"),
'REF': name(RfcDocStateName, 'ref', 'REF', "Holding for normative reference"),
'RFC-EDITOR': name(RfcDocStateName, 'rfc-edit', 'RFC-EDITOR', "Awaiting final RFC Editor review before AUTH48"),
'TO': name(RfcDocStateName, 'timeout', 'TO', "Time-out period during which the IESG reviews document for conflict/concurrence with other IETF working group work"),
'MISSREF': name(RfcDocStateName, 'missref', 'MISSREF', "Awaiting missing normative reference"),
'AUTH': State.objects.get_or_create(type=t, slug='auth', name='AUTH', desc="Awaiting author action")[0],
'AUTH48': State.objects.get_or_create(type=t, slug='auth48', name="AUTH48", desc="Awaiting final author approval")[0],
'EDIT': State.objects.get_or_create(type=t, slug='edit', name='EDIT', desc="Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing")[0],
'IANA': State.objects.get_or_create(type=t, slug='iana-crd', name='IANA', desc="RFC-Editor/IANA Registration Coordination")[0],
'IESG': State.objects.get_or_create(type=t, slug='iesg', name='IESG', desc="Holding for IESG action")[0],
'ISR': State.objects.get_or_create(type=t, slug='isr', name='ISR', desc="Independent Submission Review by the ISE ")[0],
'ISR-AUTH': State.objects.get_or_create(type=t, slug='isr-auth', name='ISR-AUTH', desc="Independent Submission awaiting author update, or in discussion between author and ISE")[0],
'REF': State.objects.get_or_create(type=t, slug='ref', name='REF', desc="Holding for normative reference")[0],
'RFC-EDITOR': State.objects.get_or_create(type=t, slug='rfc-edit', name='RFC-EDITOR', desc="Awaiting final RFC Editor review before AUTH48")[0],
'TO': State.objects.get_or_create(type=t, slug='timeout', name='TO', desc="Time-out period during which the IESG reviews document for conflict/concurrence with other IETF working group work")[0],
'MISSREF': State.objects.get_or_create(type=t, slug='missref', name='MISSREF', desc="Awaiting missing normative reference")[0],
}
@ -237,10 +236,9 @@ def insert_into_databaseREDESIGN(drafts, refs):
rfc_editor_tags = tags.values()
log("removing old data...")
for d in Document.objects.exclude(rfc_state=None).filter(tags__in=rfc_editor_tags):
for d in Document.objects.filter(states__type="draft-rfceditor").distinct():
d.tags.remove(*rfc_editor_tags)
Document.objects.exclude(rfc_state=None).update(rfc_state=None)
d.unset_state("draft-rfceditor")
log("inserting new data...")
@ -254,8 +252,7 @@ def insert_into_databaseREDESIGN(drafts, refs):
s = state.split(" ")
if s:
# first is state
d.rfc_state = states[s[0]]
d.save()
d.set_state(states[s[0]])
# remainding are tags
for x in s[1:]:

View file

@ -178,11 +178,11 @@ import django.db.transaction
@django.db.transaction.commit_on_success
def insert_to_databaseREDESIGN(data):
from person.models import Person
from doc.models import Document, DocAlias, DocEvent, RelatedDocument
from group.models import Group
from name.models import DocTagName, DocRelationshipName
from name.utils import name
from redesign.person.models import Person
from redesign.doc.models import Document, DocAlias, DocEvent, RelatedDocument, State
from redesign.group.models import Group
from redesign.name.models import DocTagName, DocRelationshipName
from redesign.name.utils import name
system = Person.objects.get(name="(System)")
std_level_mapping = get_std_level_mapping()
@ -242,8 +242,8 @@ def insert_to_databaseREDESIGN(data):
doc.std_level = std_level_mapping[current_status]
changed = True
if doc.state_id != "rfc":
doc.state_id = "rfc"
if doc.get_state_slug() != "rfc":
doc.set_state(State.objects.filter(type="draft", slug="rfc"))
changed = True
if doc.stream != stream_mapping[stream]:

View file

@ -62,14 +62,13 @@ class ChangeStateTestCase(django.test.TestCase):
def test_change_state(self):
draft = make_test_data()
draft.iesg_state = IesgDocStateName.objects.get(slug="ad-eval")
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="ad-eval"))
url = urlreverse('doc_change_state', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
first_state = draft.iesg_state
next_states = get_next_iesg_states(first_state)
first_state = draft.get_state("draft-iesg")
next_states = first_state.next_states
# normal get
r = self.client.get(url)
@ -82,23 +81,23 @@ class ChangeStateTestCase(django.test.TestCase):
# faulty post
r = self.client.post(url, dict(state="foobarbaz"))
r = self.client.post(url, dict(state=State.objects.get(type="draft", slug="active").pk))
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form ul.errorlist')) > 0)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state, first_state)
self.assertEquals(draft.get_state("draft-iesg"), first_state)
# change state
events_before = draft.docevent_set.count()
mailbox_before = len(outbox)
r = self.client.post(url, dict(state="review-e"))
r = self.client.post(url, dict(state=State.objects.get(type="draft-iesg", slug="review-e").pk))
self.assertEquals(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state_id, "review-e")
self.assertEquals(draft.get_state_slug("draft-iesg"), "review-e")
self.assertEquals(draft.docevent_set.count(), events_before + 1)
self.assertTrue("State changed" in draft.docevent_set.all()[0].desc)
self.assertEquals(len(outbox), mailbox_before + 2)
@ -115,8 +114,7 @@ class ChangeStateTestCase(django.test.TestCase):
def test_request_last_call(self):
draft = make_test_data()
draft.iesg_state = IesgDocStateName.objects.get(slug="ad-eval")
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="ad-eval"))
self.client.login(remote_user="secretary")
url = urlreverse('doc_change_state', kwargs=dict(name=draft.name))
@ -124,7 +122,7 @@ class ChangeStateTestCase(django.test.TestCase):
mailbox_before = len(outbox)
self.assertTrue(not draft.latest_event(type="changed_ballot_writeup_text"))
r = self.client.post(url, dict(state="lc-req"))
r = self.client.post(url, dict(state=State.objects.get(type="draft-iesg", slug="lc-req").pk))
self.assertContains(r, "Your request to issue the Last Call")
# last call text
@ -189,7 +187,7 @@ class EditInfoTestCase(django.test.TestCase):
status_date=str(date.today() + timedelta(2)),
via_rfc_editor="1",
ad=str(new_ad.pk),
create_in_state="pub-req",
create_in_state=State.objects.get(type="draft-iesg", slug="pub-req").pk,
notify="test@example.com",
note="New note",
telechat_date="",
@ -214,7 +212,7 @@ class EditInfoTestCase(django.test.TestCase):
data = dict(intended_std_level=str(draft.intended_std_level_id),
status_date=str(date.today() + timedelta(2)),
via_rfc_editor="1",
create_in_state="pub-req",
create_in_state=State.objects.get(type="draft-iesg", slug="pub-req").pk,
ad=str(draft.ad_id),
notify="test@example.com",
note="",
@ -249,8 +247,8 @@ class EditInfoTestCase(django.test.TestCase):
def test_start_iesg_process_on_draft(self):
draft = make_test_data()
draft.ad = None
draft.iesg_state = None
draft.save()
draft.unset_state("draft-iesg")
draft.docevent_set.all().delete()
url = urlreverse('doc_edit_info', kwargs=dict(name=draft.name))
@ -275,7 +273,7 @@ class EditInfoTestCase(django.test.TestCase):
status_date=str(date.today() + timedelta(2)),
via_rfc_editor="1",
ad=ad.pk,
create_in_state="watching",
create_in_state=State.objects.get(type="draft-iesg", slug="watching").pk,
notify="test@example.com",
note="This is a note",
telechat_date="",
@ -284,7 +282,7 @@ class EditInfoTestCase(django.test.TestCase):
draft = Document.objects.get(name=draft.name)
self.assertTrue(draft.tags.filter(slug="via-rfc"))
self.assertEquals(draft.iesg_state_id, "watching")
self.assertEquals(draft.get_state_slug("draft-iesg"), "watching")
self.assertEquals(draft.ad, ad)
self.assertEquals(draft.note, "This is a note")
self.assertTrue(not draft.latest_event(TelechatDocEvent, type="scheduled_for_telechat"))
@ -299,8 +297,7 @@ class ResurrectTestCase(django.test.TestCase):
def test_request_resurrect(self):
draft = make_test_data()
draft.state_id = "expired"
draft.save()
draft.set_state(State.objects.get(type="draft", slug="expired"))
url = urlreverse('doc_request_resurrect', kwargs=dict(name=draft.name))
@ -331,8 +328,8 @@ class ResurrectTestCase(django.test.TestCase):
def test_resurrect(self):
draft = make_test_data()
draft.state_id = "expired"
draft.save()
draft.set_state(State.objects.get(type="draft", slug="expired"))
DocEvent.objects.create(doc=draft,
type="requested_resurrect",
by=Person.objects.get(name="Aread Irector"))
@ -357,7 +354,7 @@ class ResurrectTestCase(django.test.TestCase):
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.docevent_set.count(), events_before + 1)
self.assertEquals(draft.latest_event().type, "completed_resurrect")
self.assertEquals(draft.state_id, "active")
self.assertEquals(draft.get_state_slug(), "active")
self.assertEquals(len(outbox), mailbox_before + 1)
class AddCommentTestCase(django.test.TestCase):
@ -515,9 +512,8 @@ class DeferBallotTestCase(django.test.TestCase):
def test_defer_ballot(self):
draft = make_test_data()
draft.iesg_state_id = "iesg-eva"
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva"))
url = urlreverse('doc_defer_ballot', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "ad", url)
@ -532,7 +528,7 @@ class DeferBallotTestCase(django.test.TestCase):
self.assertEquals(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state_id, "defer")
self.assertEquals(draft.get_state_slug("draft-iesg"), "defer")
self.assertEquals(len(outbox), mailbox_before + 2)
self.assertTrue("State Update" in outbox[-2]['Subject'])
@ -541,9 +537,8 @@ class DeferBallotTestCase(django.test.TestCase):
def test_undefer_ballot(self):
draft = make_test_data()
draft.iesg_state_id = "defer"
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="defer"))
url = urlreverse('doc_undefer_ballot', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "ad", url)
@ -556,7 +551,7 @@ class DeferBallotTestCase(django.test.TestCase):
self.assertEquals(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state_id, "iesg-eva")
self.assertEquals(draft.get_state_slug("draft-iesg"), "iesg-eva")
class BallotWriteupsTestCase(django.test.TestCase):
fixtures = ['names']
@ -617,7 +612,7 @@ class BallotWriteupsTestCase(django.test.TestCase):
last_call_text=draft.latest_event(WriteupDocEvent, type="changed_last_call_text").text,
send_last_call_request="1"))
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state_id, "lc-req")
self.assertEquals(draft.get_state_slug("draft-iesg"), "lc-req")
self.assertEquals(len(outbox), mailbox_before + 3)
self.assertTrue("Last Call" in outbox[-1]['Subject'])
self.assertTrue(draft.name in outbox[-1]['Subject'])
@ -727,8 +722,7 @@ class BallotWriteupsTestCase(django.test.TestCase):
self.assertTrue("Subject: Protocol Action" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
# test regenerate when it's a disapprove
draft.iesg_state_id = "nopubadw"
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="nopubadw"))
r = self.client.post(url, dict(regenerate_approval_text="1"))
self.assertEquals(r.status_code, 200)
@ -740,8 +734,8 @@ class ApproveBallotTestCase(django.test.TestCase):
def test_approve_ballot(self):
draft = make_test_data()
draft.iesg_state_id = "iesg-eva" # make sure it's approvable
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) # make sure it's approvable
url = urlreverse('doc_approve_ballot', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
@ -759,7 +753,7 @@ class ApproveBallotTestCase(django.test.TestCase):
self.assertEquals(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state_id, "ann")
self.assertEquals(draft.get_state_slug("draft-iesg"), "ann")
self.assertEquals(len(outbox), mailbox_before + 4)
self.assertTrue("Protocol Action" in outbox[-2]['Subject'])
# the IANA copy
@ -767,8 +761,7 @@ class ApproveBallotTestCase(django.test.TestCase):
def test_disapprove_ballot(self):
draft = make_test_data()
draft.iesg_state_id = "nopubadw"
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="nopubadw"))
url = urlreverse('doc_approve_ballot', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
@ -780,7 +773,7 @@ class ApproveBallotTestCase(django.test.TestCase):
self.assertEquals(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state_id, "dead")
self.assertEquals(draft.get_state_slug("draft-iesg"), "dead")
self.assertEquals(len(outbox), mailbox_before + 3)
self.assertTrue("NOT be published" in str(outbox[-1]))
@ -789,9 +782,8 @@ class MakeLastCallTestCase(django.test.TestCase):
def test_make_last_call(self):
draft = make_test_data()
draft.iesg_state_id = "lc-req"
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="lc-req"))
url = urlreverse('doc_make_last_call', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "secretary", url)
@ -813,7 +805,7 @@ class MakeLastCallTestCase(django.test.TestCase):
self.assertEquals(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state.slug, "lc")
self.assertEquals(draft.get_state_slug("draft-iesg"), "lc")
self.assertEquals(draft.latest_event(LastCallDocEvent, "sent_last_call").expires.strftime("%Y-%m-%d"), expire_date)
self.assertEquals(len(outbox), mailbox_before + 4)
@ -866,8 +858,7 @@ class ExpireIDsTestCase(django.test.TestCase):
self.assertEquals(len(list(get_soon_to_expire_ids(14))), 0)
# hack into expirable state
draft.iesg_state = None
draft.save()
draft.unset_state("draft-iesg")
NewRevisionDocEvent.objects.create(
type="new_revision",
@ -897,9 +888,8 @@ class ExpireIDsTestCase(django.test.TestCase):
self.assertEquals(len(list(get_expired_ids())), 0)
# hack into expirable state
draft.iesg_state = None
draft.save()
draft.unset_state("draft-iesg")
NewRevisionDocEvent.objects.create(
type="new_revision",
by=Person.objects.get(name="Aread Irector"),
@ -911,9 +901,8 @@ class ExpireIDsTestCase(django.test.TestCase):
self.assertEquals(len(list(get_expired_ids())), 1)
draft.iesg_state = IesgDocStateName.objects.get(slug="watching")
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="watching"))
self.assertEquals(len(list(get_expired_ids())), 1)
# test notice
@ -933,9 +922,9 @@ class ExpireIDsTestCase(django.test.TestCase):
expire_id(draft)
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.state_id, "expired")
self.assertEquals(draft.get_state_slug(), "expired")
self.assertEquals(int(draft.rev), int(revision_before) + 1)
self.assertEquals(draft.iesg_state_id, "dead")
self.assertEquals(draft.get_state_slug("draft-iesg"), "dead")
self.assertTrue(draft.latest_event(type="expired_document"))
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, txt)))
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, txt)))
@ -968,7 +957,7 @@ class ExpireIDsTestCase(django.test.TestCase):
# RFC draft
draft.state = DocStateName.objects.get(slug="rfc")
draft.set_state(State.objects.get(type="draft", slug="rfc"))
draft.save()
txt = "%s-%s.txt" % (draft.name, draft.rev)
@ -986,7 +975,7 @@ class ExpireIDsTestCase(django.test.TestCase):
# expire draft
draft.state = DocStateName.objects.get(slug="expired")
draft.set_state(State.objects.get(type="draft", slug="expired"))
draft.save()
e = DocEvent()
@ -1028,11 +1017,10 @@ class ExpireLastCallTestCase(django.test.TestCase):
def test_expire_last_call(self):
from ietf.idrfc.lastcall import get_expired_last_calls, expire_last_call
# check that non-expirable drafts aren't expired
# check that non-expirable drafts aren't expired
draft = make_test_data()
draft.iesg_state_id = "lc"
draft.save()
draft.set_state(State.objects.get(type="draft-iesg", slug="lc"))
secretary = Person.objects.get(name="Sec Retary")
@ -1067,7 +1055,7 @@ class ExpireLastCallTestCase(django.test.TestCase):
expire_last_call(drafts[0])
draft = Document.objects.get(name=draft.name)
self.assertEquals(draft.iesg_state.slug, "writeupw")
self.assertEquals(draft.get_state_slug("draft-iesg"), "writeupw")
self.assertEquals(draft.docevent_set.count(), events_before + 1)
self.assertEquals(len(outbox), mailbox_before + 1)
self.assertTrue("Last Call Expired" in outbox[-1]["Subject"])

View file

@ -65,18 +65,20 @@ def log_state_changed(request, doc, by, email_watch_list=True, note=''):
def log_state_changedREDESIGN(request, doc, by, prev_iesg_state, note=''):
from doc.models import DocEvent
state = doc.get_state("draft-iesg")
e = DocEvent(doc=doc, by=by)
e.type = "changed_document"
e.desc = u"State changed to <b>%s</b> from %s" % (
doc.iesg_state.name,
prev_iesg_state.name if prev_iesg_state else "None")
state.name,
prev_iesg_state.name if prev_iesg_state else "I-D Exists")
if note:
e.desc += "<br>%s" % note
if doc.iesg_state_id == "lc":
if state.slug == "lc":
writeup = doc.latest_event(WriteupDocEvent, type="changed_last_call_text")
if writeup:
if writeup and writeup.text:
e.desc += "<br><br><b>The following Last Call Announcement was sent out:</b><br><br>"
e.desc += writeup.text.replace("\n", "<br><br>")

View file

@ -25,8 +25,8 @@ from ietf.idrfc.utils import *
from ietf.idrfc.lastcall import request_last_call
from ietf.idrfc.idrfc_wrapper import BallotWrapper
from doc.models import Document, DocEvent, BallotPositionDocEvent, LastCallDocEvent, save_document_in_history
from name.models import BallotPositionName, IesgDocStateName
from redesign.doc.models import *
from redesign.name.models import BallotPositionName
BALLOT_CHOICES = (("yes", "Yes"),
@ -227,7 +227,7 @@ def edit_positionREDESIGN(request, name):
"""Vote and edit discuss and comment on Internet Draft as Area Director."""
doc = get_object_or_404(Document, docalias__name=name)
started_process = doc.latest_event(type="started_iesg_process")
if not doc.iesg_state or not started_process:
if not doc.get_state("draft-iesg") or not started_process:
raise Http404()
ad = login = request.user.get_profile()
@ -337,7 +337,7 @@ def edit_positionREDESIGN(request, name):
form = EditPositionForm(initial=initial)
ballot_deferred = None
if doc.iesg_state_id == "defer":
if doc.get_state_slug("draft-iesg") == "defer":
ballot_deferred = doc.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
return render_to_response('idrfc/edit_positionREDESIGN.html',
@ -543,7 +543,7 @@ def defer_ballot(request, name):
def defer_ballotREDESIGN(request, name):
"""Signal post-pone of Internet Draft ballot, notifying relevant parties."""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.iesg_state:
if not doc.get_state("draft-iesg"):
raise Http404()
login = request.user.get_profile()
@ -552,8 +552,8 @@ def defer_ballotREDESIGN(request, name):
if request.method == 'POST':
save_document_in_history(doc)
prev = doc.iesg_state
doc.iesg_state = IesgDocStateName.objects.get(slug='defer')
prev = doc.get_state("draft-iesg")
doc.set_state(State.objects.get(type="draft-iesg", slug='defer'))
e = log_state_changed(request, doc, login, prev)
doc.time = e.time
@ -608,7 +608,7 @@ def undefer_ballot(request, name):
def undefer_ballotREDESIGN(request, name):
"""Delete deferral of Internet Draft ballot."""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.iesg_state:
if not doc.get_state("draft-iesg"):
raise Http404()
login = request.user.get_profile()
@ -617,8 +617,8 @@ def undefer_ballotREDESIGN(request, name):
if request.method == 'POST':
save_document_in_history(doc)
prev = doc.iesg_state
doc.iesg_state = IesgDocStateName.objects.get(slug='iesg-eva')
prev = doc.get_state("draft-iesg")
doc.set_state(State.objects.get(type="draft-iesg", slug='iesg-eva'))
e = log_state_changed(request, doc, login, prev)
doc.time = e.time
@ -748,7 +748,7 @@ class LastCallTextFormREDESIGN(forms.Form):
def lastcalltextREDESIGN(request, name):
"""Editing of the last call text"""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.iesg_state:
if not doc.get_state("draft-iesg"):
raise Http404()
login = request.user.get_profile()
@ -775,8 +775,8 @@ def lastcalltextREDESIGN(request, name):
if "send_last_call_request" in request.POST:
save_document_in_history(doc)
prev = doc.iesg_state
doc.iesg_state = IesgDocStateName.objects.get(slug='lc-req')
prev = doc.get_state("draft-iesg")
doc.set_state(State.objects.get(type="draft-iesg", slug='lc-req'))
e = log_state_changed(request, doc, login, prev)
doc.time = e.time
@ -797,10 +797,11 @@ def lastcalltextREDESIGN(request, name):
# make sure form has the updated text
form = LastCallTextForm(initial=dict(last_call_text=e.text))
can_request_last_call = doc.iesg_state.order < 27
can_make_last_call = doc.iesg_state.order < 20
can_announce = doc.iesg_state.order > 19
s = doc.get_state("draft-iesg")
can_request_last_call = s.order < 27
can_make_last_call = s.order < 20
can_announce = s.order > 19
need_intended_status = ""
if not doc.intended_std_level:
@ -1039,7 +1040,7 @@ class ApprovalTextFormREDESIGN(forms.Form):
def ballot_approvaltextREDESIGN(request, name):
"""Editing of approval text"""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.iesg_state:
if not doc.get_state("draft-iesg"):
raise Http404()
login = request.user.get_profile()
@ -1069,7 +1070,7 @@ def ballot_approvaltextREDESIGN(request, name):
# make sure form has the updated text
form = ApprovalTextForm(initial=dict(approval_text=existing.text))
can_announce = doc.iesg_state.order > 19
can_announce = doc.get_state("draft-iesg").order > 19
need_intended_status = ""
if not doc.intended_std_level:
need_intended_status = doc.file_tag()
@ -1162,7 +1163,7 @@ def approve_ballot(request, name):
def approve_ballotREDESIGN(request, name):
"""Approve ballot, sending out announcement, changing state."""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.iesg_state:
if not doc.get_state("draft-iesg"):
raise Http404()
login = request.user.get_profile()
@ -1188,15 +1189,15 @@ def approve_ballotREDESIGN(request, name):
if request.method == 'POST':
if action == "do_not_publish":
new_state = IesgDocStateName.objects.get(slug="dead")
new_state = State.objects.get(type="draft-iesg", slug="dead")
else:
new_state = IesgDocStateName.objects.get(slug="ann")
new_state = State.objects.get(type="draft-iesg", slug="ann")
# fixup document
save_document_in_history(doc)
prev = doc.iesg_state
doc.iesg_state = new_state
prev = doc.get_state("draft-iesg")
doc.set_state(new_state)
e = DocEvent(doc=doc, by=login)
if action == "do_not_publish":
@ -1208,7 +1209,7 @@ def approve_ballotREDESIGN(request, name):
e.save()
change_description = e.desc + " and state has been changed to %s" % doc.iesg_state.name
change_description = e.desc + " and state has been changed to %s" % doc.get_state("draft-iesg").name
e = log_state_changed(request, doc, login, prev)
@ -1296,7 +1297,7 @@ def make_last_call(request, name):
def make_last_callREDESIGN(request, name):
"""Make last call for Internet Draft, sending out announcement."""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.iesg_state:
if not doc.get_state("draft-iesg"):
raise Http404()
login = request.user.get_profile()
@ -1314,14 +1315,14 @@ def make_last_callREDESIGN(request, name):
save_document_in_history(doc)
prev = doc.iesg_state
doc.iesg_state = IesgDocStateName.objects.get(slug='lc')
prev = doc.get_state("draft-iesg")
doc.set_state(State.objects.get(type="draft-iesg", slug='lc'))
e = log_state_changed(request, doc, login, prev)
doc.time = e.time
doc.save()
change_description = "Last call has been made for %s and state has been changed to %s" % (doc.name, doc.iesg_state.name)
change_description = "Last call has been made for %s and state has been changed to %s" % (doc.name, doc.get_state("draft-iesg").name)
email_state_changed(request, doc, change_description)
email_owner(request, doc, doc.ad, login, change_description)

View file

@ -23,9 +23,9 @@ from ietf.idrfc.mails import *
from ietf.idrfc.utils import *
from ietf.idrfc.lastcall import request_last_call
from doc.models import Document, DocEvent, StatusDateDocEvent, TelechatDocEvent, save_document_in_history, DocHistory
from name.models import IesgDocStateName, IntendedStdLevelName, DocTagName, get_next_iesg_states, DocStateName
from person.models import Person, Email
from redesign.doc.models import *
from redesign.name.models import IntendedStdLevelName, DocTagName
from redesign.person.models import Person, Email
class ChangeStateForm(forms.Form):
state = forms.ModelChoiceField(IDState.objects.all(), empty_label=None, required=True)
@ -85,7 +85,7 @@ def change_state(request, name):
context_instance=RequestContext(request))
class ChangeStateFormREDESIGN(forms.Form):
state = forms.ModelChoiceField(IesgDocStateName.objects.all(), empty_label=None, required=True)
state = forms.ModelChoiceField(State.objects.filter(type="draft-iesg"), empty_label=None, required=True)
# FIXME: no tags yet
#substate = forms.ModelChoiceField(IDSubState.objects.all(), required=False)
comment = forms.CharField(widget=forms.Textarea, required=False)
@ -95,7 +95,7 @@ def change_stateREDESIGN(request, name):
"""Change state of Internet Draft, notifying parties as necessary
and logging the change as a comment."""
doc = get_object_or_404(Document, docalias__name=name)
if (not doc.latest_event(type="started_iesg_process")) or doc.state_id == "expired":
if (not doc.latest_event(type="started_iesg_process")) or doc.get_state_slug() == "expired":
raise Http404()
login = request.user.get_profile()
@ -105,11 +105,11 @@ def change_stateREDESIGN(request, name):
if form.is_valid():
state = form.cleaned_data['state']
comment = form.cleaned_data['comment']
if state != doc.iesg_state:
prev = doc.get_state("draft-iesg")
if state != prev:
save_document_in_history(doc)
prev = doc.iesg_state
doc.iesg_state = state
doc.set_state(state)
e = log_state_changed(request, doc, login, prev, comment)
@ -119,7 +119,7 @@ def change_stateREDESIGN(request, name):
email_state_changed(request, doc, e.desc)
email_owner(request, doc, doc.ad, login, e.desc)
if doc.iesg_state_id == "lc-req":
if state.slug == "lc-req":
request_last_call(request, doc)
return render_to_response('idrfc/last_call_requested.html',
@ -130,14 +130,16 @@ def change_stateREDESIGN(request, name):
return HttpResponseRedirect(doc.get_absolute_url())
else:
form = ChangeStateForm(initial=dict(state=doc.iesg_state_id))
state = doc.get_state("draft-iesg")
form = ChangeStateForm(initial=dict(state=state.pk if state else None))
next_states = get_next_iesg_states(doc.iesg_state)
state = doc.get_state("draft-iesg")
next_states = state.next_states.all() if state else None
prev_state = None
hists = DocHistory.objects.filter(doc=doc).exclude(iesg_state=doc.iesg_state).order_by("-time")[:1]
hists = doc.history_set.exclude(states=doc.get_state("draft-iesg")).order_by('-time')[:1]
if hists:
prev_state = hists[0].iesg_state
prev_state = hists[0].get_state("draft-iesg")
return render_to_response('idrfc/change_stateREDESIGN.html',
dict(form=form,
@ -383,7 +385,7 @@ class EditInfoFormREDESIGN(forms.Form):
status_date = forms.DateField(required=False, help_text="Format is YYYY-MM-DD")
via_rfc_editor = forms.BooleanField(required=False, label="Via IRTF or RFC Editor")
ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active").order_by('name'), label="Responsible AD", empty_label=None, required=True)
create_in_state = forms.ModelChoiceField(IesgDocStateName.objects.filter(slug__in=("pub-req", "watching")), empty_label=None, required=True)
create_in_state = forms.ModelChoiceField(State.objects.filter(type="draft-iesg", slug__in=("pub-req", "watching")), empty_label=None, required=True)
notify = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)
note = forms.CharField(widget=forms.Textarea, label="IESG note", required=False)
telechat_date = forms.TypedChoiceField(coerce=lambda x: datetime.datetime.strptime(x, '%Y-%m-%d').date(), empty_value=None, required=False)
@ -447,15 +449,14 @@ def edit_infoREDESIGN(request, name):
"""Edit various Internet Draft attributes, notifying parties as
necessary and logging changes as document events."""
doc = get_object_or_404(Document, docalias__name=name)
if doc.state_id == "expired":
if doc.get_state_slug() == "expired":
raise Http404()
login = request.user.get_profile()
new_document = False
if not doc.iesg_state: # FIXME: should probably receive "new document" as argument to view instead of this
if not doc.get_state("draft-iesg"): # FIXME: should probably receive "new document" as argument to view instead of this
new_document = True
doc.iesg_state = IesgDocStateName.objects.get(slug="pub-req")
doc.notify = get_initial_notify(doc)
e = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
@ -471,11 +472,12 @@ def edit_infoREDESIGN(request, name):
r = form.cleaned_data
if new_document:
doc.set_state(r['create_in_state'])
# fix so Django doesn't barf in the diff below because these
# fields can't be NULL
doc.ad = r['ad']
doc.iesg_state = r['create_in_state']
replaces = Document.objects.filter(docalias__relateddocument__source=doc, docalias__relateddocument__relationship="replaces")
if replaces:
# this should perhaps be somewhere else, e.g. the
@ -491,7 +493,7 @@ def edit_infoREDESIGN(request, name):
e.type = "started_iesg_process"
e.by = login
e.doc = doc
e.desc = "IESG process started in state <b>%s</b>" % doc.iesg_state.name
e.desc = "IESG process started in state <b>%s</b>" % doc.get_state("draft-iesg").name
e.save()
orig_ad = doc.ad
@ -619,7 +621,7 @@ def request_resurrect(request, name):
def request_resurrectREDESIGN(request, name):
"""Request resurrect of expired Internet Draft."""
doc = get_object_or_404(Document, docalias__name=name)
if doc.state_id != "expired":
if doc.get_state_slug() != "expired":
raise Http404()
login = request.user.get_profile()
@ -674,7 +676,7 @@ def resurrect(request, name):
def resurrectREDESIGN(request, name):
"""Resurrect expired Internet Draft."""
doc = get_object_or_404(Document, docalias__name=name)
if doc.state_id != "expired":
if doc.get_state_slug() != "expired":
raise Http404()
login = request.user.get_profile()
@ -691,7 +693,7 @@ def resurrectREDESIGN(request, name):
e.desc = "Resurrection was completed"
e.save()
doc.state = DocStateName.objects.get(slug="active")
doc.set_state(State.objects.get(type="draft", slug="active"))
doc.time = datetime.datetime.now()
doc.save()
return HttpResponseRedirect(doc.get_absolute_url())
@ -738,7 +740,7 @@ def add_comment(request, name):
def add_commentREDESIGN(request, name):
"""Add comment to Internet Draft."""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.iesg_state:
if not doc.get_state("draft-iesg"):
raise Http404()
login = request.user.get_profile()

View file

@ -290,7 +290,7 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
addInputEvents(area.widget)
ad = forms.ChoiceField(choices=(), required=False)
addInputEvents(ad.widget)
state = forms.ModelChoiceField(IesgDocStateName.objects.all(), empty_label="any state", required=False)
state = forms.ModelChoiceField(State.objects.filter(type="draft-iesg"), empty_label="any state", required=False)
addInputEvents(state.widget)
subState = forms.ChoiceField(choices=(), required=False)
addInputEvents(subState.widget)
@ -360,18 +360,15 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
Q(title__icontains=query["name"])).distinct()
# rfc/active/old check buttons
allowed = []
disallowed = []
allowed_states = []
if query["rfcs"]:
allowed_states.append("rfc")
if query["activeDrafts"]:
allowed_states.append("active")
if query["oldDrafts"]:
allowed_states.extend(['repl', 'expired', 'auth-rm', 'ietf-rm'])
def add(allow, states):
l = allowed if allow else disallowed
l.extend(states)
add(query["rfcs"], ['rfc'])
add(query["activeDrafts"], ['active'])
add(query["oldDrafts"], ['repl', 'expired', 'auth-rm', 'ietf-rm'])
docs = docs.filter(state__in=allowed).exclude(state__in=disallowed)
docs = docs.filter(states__type="draft", states__slug__in=allowed_states)
# radio choices
by = query["by"]
@ -388,13 +385,13 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
docs = docs.filter(ad=query["ad"])
elif by == "state":
if query["state"]:
docs = docs.filter(iesg_state=query["state"])
docs = docs.filter(states=query["state"])
if query["subState"]:
docs = docs.filter(tags=query["subState"])
# evaluate and fill in values with aggregate queries to avoid
# too many individual queries
results = list(docs.select_related("state", "iesg_state", "ad", "ad__person", "std_level", "intended_std_level", "group")[:MAX])
results = list(docs.select_related("states", "ad", "ad__person", "std_level", "intended_std_level", "group")[:MAX])
rfc_aliases = dict(DocAlias.objects.filter(name__startswith="rfc", document__in=[r.pk for r in results]).values_list("document_id", "name"))
# canonical name
@ -452,7 +449,7 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
if rfc_num != None:
res.append(2)
elif d.state_id == "active":
elif d.get_state_slug() == "active":
res.append(1)
else:
res.append(3)
@ -465,15 +462,15 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
if rfc_num != None:
res.append(rfc_num)
else:
res.append(d.state)
res.append(d.get_state().order)
elif sort_by == "ipr":
res.append(d.name)
elif sort_by == "ad":
if rfc_num != None:
res.append(rfc_num)
elif d.state_id == "active":
if d.iesg_state:
res.append(d.iesg_state.order)
elif d.get_state_slug() == "active":
if d.get_state("draft-iesg"):
res.append(get_state("draft-iesg").order)
else:
res.append(0)
else:
@ -599,7 +596,7 @@ def by_ad(request, name):
@cache_page(15*60) # 15 minutes
def all(request):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
active = (dict(filename=n) for n in InternetDraft.objects.filter(state="active").order_by("name").values_list('name', flat=True))
active = (dict(filename=n) for n in InternetDraft.objects.filter(states__type="draft", states__slug="active").order_by("name").values_list('name', flat=True))
rfc1 = (dict(filename=d, rfc_number=int(n[3:])) for d, n in DocAlias.objects.filter(document__state="rfc", name__startswith="rfc").exclude(document__name__startswith="rfc").order_by("document__name").values_list('document__name','name').distinct())
rfc2 = (dict(rfc_number=r, draft=None) for r in sorted(int(n[3:]) for n in Document.objects.filter(type="draft", name__startswith="rfc").values_list('name', flat=True)))
dead = InternetDraft.objects.exclude(state__in=("active", "rfc")).select_related("state").order_by("name")

View file

@ -59,7 +59,7 @@ class InLastCall(Feed):
def items(self):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
ret = list(IDInternal.objects.filter(iesg_state='lc'))
ret = list(IDInternal.objects.filter(states__type="draft-iesg", states__slug="lc"))
else:
ret = list(IDInternal.objects.filter(primary_flag=1).filter(cur_state__state='In Last Call'))
ret.sort(key=lambda item: (item.document().lc_expiration_date or datetime.date.today()))

View file

@ -1152,8 +1152,8 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
IESGLoginOld = IESGLogin
IETFWGOld = IETFWG
IRTFOld = IRTF
from redesign.doc.proxy import InternetDraft, IDInternal, BallotInfo, Rfc
from redesign.name.proxy import IDState, IDSubState
from redesign.doc.proxy import InternetDraft, IDInternal, BallotInfo, Rfc, IDState
from redesign.name.proxy import IDSubState
from redesign.group.proxy import Area, Acronym, IETFWG, IRTF
from redesign.person.proxy import IESGLogin

View file

@ -29,7 +29,7 @@ IESG to do anything with the document.
def status(request):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
drafts = list(IDInternal.objects.exclude(iesg_state=None).exclude(iesg_state__in=('pub', 'dead', 'watching', 'rfcqueue')).order_by('iesg_state__order'))
drafts = list(IDInternal.objects.filter(states__type="draft-iesg").exclude(states__type="draft-iesg", states__slug__in=('pub', 'dead', 'watching', 'rfcqueue')).distinct().order_by('states__order'))
drafts.sort(key=lambda d: (d.cur_state_id, d.status_date or datetime.date.min, d.b_sent_date or datetime.date.min))
# sadly we can't use the generic view because it only works with a queryset...
return render_to_response('idtracker/status_of_items.html', dict(object_list=drafts, title="IESG Status of Items"), context_instance=RequestContext(request))
@ -39,7 +39,7 @@ def status(request):
def last_call(request):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
drafts = list(IDInternal.objects.exclude(iesg_state=None).filter(iesg_state__in=('lc', 'writeupw', 'goaheadw')).order_by('iesg_state__order'))
drafts = list(IDInternal.objects.filter(states__type="draft-iesg", states__slug__in=('lc', 'writeupw', 'goaheadw')).distinct().order_by('states__order'))
drafts.sort(key=lambda d: (d.cur_state_id, d.status_date or datetime.date.min, d.b_sent_date or datetime.date.min))
# sadly we can't use the generic view because it only works with a queryset...
return render_to_response('idtracker/status_of_items.html', dict(object_list=drafts, title="Documents in Last Call", lastcall=1), context_instance=RequestContext(request))

View file

@ -483,7 +483,7 @@ def discusses(request):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
res = []
for d in IDInternal.objects.filter(iesg_state__in=("pub-req", "ad-eval", "review-e", "lc-req", "lc", "writeupw", "goaheadw", "iesg-eva", "defer", "watching"), docevent__ballotpositiondocevent__pos="discuss").distinct():
for d in IDInternal.objects.filter(states__type="draft-iesg", states__slug__in=("pub-req", "ad-eval", "review-e", "lc-req", "lc", "writeupw", "goaheadw", "iesg-eva", "defer", "watching"), docevent__ballotpositiondocevent__pos="discuss").distinct():
found = False
for p in d.positions.all():
if p.discuss:

View file

@ -25,7 +25,7 @@ class EditStreamInfoTestCase(django.test.TestCase):
draft = make_test_data()
draft.stream_id = "ise"
draft.group = Group.objects.get(type="individ")
draft.unset_state(State.objects.get(type="draft-stream-ietf", slug="wg-doc"))
draft.unset_state("draft-stream-ietf")
draft.save()
url = urlreverse('edit_adopt', kwargs=dict(name=draft.name))

View file

@ -328,18 +328,25 @@ def update_state(doc, comment, person, to_state, estimated_date=None, extra_noti
e.desc = u"%s changed to <b>%s</b> from %s" % (to_state.type.label, to_state, from_state)
e.save()
if estimated_date:
t = DocReminderTypeName.objects.get(slug="stream-s")
try:
reminder = DocReminder.objects.get(event__doc=doc, type=t,
active=True)
except DocReminder.DoesNotExist:
reminder = DocReminder(type=t)
# reminder
reminder_type = DocReminderTypeName.objects.get(slug="stream-s")
try:
reminder = DocReminder.objects.get(event__doc=doc, type=reminder_type,
active=True)
except DocReminder.DoesNotExist:
reminder = None
reminder.event = e
reminder.due = estimated_date
reminder.active = True
reminder.save()
if estimated_date:
if not reminder:
reminder = DocReminder(type=reminder_type)
reminder.event = e
reminder.due = estimated_date
reminder.active = True
reminder.save()
elif reminder:
reminder.active = False
reminder.save()
receivers = get_notification_receivers(doc, extra_notify)
send_mail(None, receivers, settings.DEFAULT_FROM_EMAIL,

View file

@ -177,7 +177,7 @@ class SubmitTestCase(django.test.TestCase):
self.assertTrue(name in confirmation["Subject"])
# dig out confirmation link
msg = confirmation.get_payload(i=1).get_payload(i=0).get_payload(decode=True)
msg = confirmation.get_payload(decode=True)
line_start = "I-D Submission Tool URL:"
self.assertTrue(line_start in msg)
confirm_url = None

View file

@ -108,8 +108,7 @@ def perform_postREDESIGN(submission):
draft.rev = submission.revision
draft.pages = submission.txt_page_count
draft.abstract = submission.abstract
was_rfc = draft.state_id == "rfc"
draft.state_id = "active"
was_rfc = draft.get_state_slug() == "rfc"
if draft.name.startswith("draft-iab-"):
stream_slug = "iab"
@ -121,10 +120,12 @@ def perform_postREDESIGN(submission):
stream_slug = "ietf"
draft.stream = DocStreamName.objects.get(slug=stream_slug)
draft.save()
draft.set_state(State.objects.get(type="draft", slug="active"))
if draft.stream_id == "ietf":
# automatically set state "WG Document"
draft.set_state(State.objects.get(type="draft_stream_%s" % draft.stream_id, slug="wg-doc"))
draft.save()
draft.set_state(State.objects.get(type="draft-stream-%s" % draft.stream_id, slug="wg-doc"))
DocAlias.objects.get_or_create(name=submission.filename, document=draft)
@ -162,7 +163,7 @@ def perform_postREDESIGN(submission):
submission.status_id = POSTED
announce_to_lists(submission)
if draft.iesg_state != None and not was_rfc:
if draft.get_state("draft-iesg") != None and not was_rfc:
announce_new_version(submission, draft, state_change_msg)
announce_to_authors(submission)

View file

@ -153,8 +153,6 @@ def make_test_data():
time=datetime.datetime.now(),
type_id="draft",
title="Optimizing Martian Network Topologies",
state_id="active",
iesg_state_id="pub-req",
stream_id="ietf",
group=group,
abstract="Techniques for achieving near-optimal Martian networks.",
@ -167,6 +165,8 @@ def make_test_data():
note="",
)
draft.set_state(State.objects.get(type="draft", slug="active"))
draft.set_state(State.objects.get(type="draft-iesg", slug="pub-req"))
draft.set_state(State.objects.get(type="draft-stream-%s" % draft.stream_id, slug="wg-doc"))
doc_alias = DocAlias.objects.create(
@ -244,7 +244,7 @@ def make_test_data():
type_id="ietf",
date=datetime.date.today() + datetime.timedelta(days=180),
city="New York",
country="United States",
country="US",
time_zone="US/Eastern",
break_area="Lounge",
reg_area="Lobby",

View file

@ -110,10 +110,9 @@ class ManageShepherdsTestCase(django.test.TestCase):
from redesign.doc.models import Document
common = dict(group=group,
state_id="active",
ad=Person.objects.get(user__username="ad"),
type_id="draft")
Document.objects.create(name="test-no-shepherd",
Document.objects.create(name="test-shepherd-no",
title="No shepherd",
shepherd=None,
**common)
@ -124,6 +123,8 @@ class ManageShepherdsTestCase(django.test.TestCase):
Document.objects.create(name="test-shepherd-other", title="Shepherd other",
shepherd=Person.objects.get(user__username="plain"),
**common)
for d in Document.objects.filter(name__startswith="test-shepherd"):
d.set_state(State.objects.get(type="draft", slug="active"))
# get and make sure they are divided correctly
r = self.client.get(url)

View file

@ -226,7 +226,7 @@ def wg_shepherd_documents(request, acronym):
current_person = get_person_for_user(user)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
base_qs = InternetDraft.objects.filter(group=wg, state="active").select_related("status").order_by('title')
base_qs = InternetDraft.objects.filter(group=wg, states__type="draft", states__slug="active").select_related("status").order_by('title')
else:
form = SearchForm({'by': 'group', 'group': str(wg.group_acronym.acronym),
'activeDrafts': 'on'})

View file

@ -26,7 +26,7 @@ class StatesWidget(forms.SelectMultiple):
requires 'instance' have been set on the widget."""
def render(self, name, value, attrs=None, choices=()):
types = StateType.objects.filter(slug__in=get_state_types(self.instance))
types = StateType.objects.filter(slug__in=get_state_types(self.instance)).order_by("slug")
categorized_choices = []
for t in types:
@ -78,12 +78,16 @@ class DocumentForm(forms.ModelForm):
model = Document
class DocumentAdmin(admin.ModelAdmin):
list_display = ['name', 'rev', 'state', 'group', 'pages', 'intended_std_level', 'author_list', 'time']
list_display = ['name', 'rev', 'group', 'pages', 'intended_std_level', 'author_list', 'time']
search_fields = ['name']
list_filter = ['type']
raw_id_fields = ['authors', 'related', 'group', 'shepherd', 'ad']
inlines = [DocAliasInline]
form = DocumentForm
def state(self, instance):
return self.get_state()
admin.site.register(Document, DocumentAdmin)
class DocHistoryAdmin(admin.ModelAdmin):
@ -92,6 +96,9 @@ class DocHistoryAdmin(admin.ModelAdmin):
ordering = ['time', 'doc', 'rev']
raw_id_fields = ['doc', 'authors', 'related', 'group', 'shepherd', 'ad']
def state(self, instance):
return self.get_state()
admin.site.register(DocHistory, DocHistoryAdmin)
class DocAliasAdmin(admin.ModelAdmin):

View file

@ -37,20 +37,15 @@ class State(models.Model):
class DocumentInfo(models.Model):
"""Any kind of document. Draft, RFC, Charter, IPR Statement, Liaison Statement"""
time = models.DateTimeField(default=datetime.datetime.now) # should probably have auto_now=True
# Document related
type = models.ForeignKey(DocTypeName, blank=True, null=True) # Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email, Review, Issue, Wiki, External ...
title = models.CharField(max_length=255)
# State
states = models.ManyToManyField(State, blank=True)
state = models.ForeignKey(DocStateName, blank=True, null=True) # Active/Expired/RFC/Replaced/Withdrawn
states = models.ManyToManyField(State, blank=True) # plain state (Active/Expired/...), IESG state, stream state
tags = models.ManyToManyField(DocTagName, blank=True, null=True) # Revised ID Needed, ExternalParty, AD Followup, ...
stream = models.ForeignKey(DocStreamName, blank=True, null=True) # IETF, IAB, IRTF, Independent Submission
group = models.ForeignKey(Group, blank=True, null=True) # WG, RG, IAB, IESG, Edu, Tools
iesg_state = models.ForeignKey(IesgDocStateName, verbose_name="IESG state", blank=True, null=True) #
iana_state = models.ForeignKey(IanaDocStateName, verbose_name="IANA state", blank=True, null=True)
rfc_state = models.ForeignKey(RfcDocStateName, verbose_name="RFC state", blank=True, null=True)
# Other
abstract = models.TextField()
rev = models.CharField(verbose_name="revision", max_length=16, blank=True)
pages = models.IntegerField(blank=True, null=True)
@ -74,6 +69,8 @@ class DocumentInfo(models.Model):
raise NotImplemented
def set_state(self, state):
"""Switch state type implicit in state to state. This just
sets the state, doesn't log the change."""
already_set = self.states.filter(type=state.type)
others = [s for s in already_set if s != state]
if others:
@ -81,20 +78,37 @@ class DocumentInfo(models.Model):
if state not in already_set:
self.states.add(state)
def unset_state(self, state):
self.states.remove(state)
def unset_state(self, state_type):
"""Unset state of type so no state of that type is any longer set."""
self.states.remove(*self.states.filter(type=state_type))
def get_state(self, state_type=None):
"""Get state of type, or default state for document type if not specified."""
if state_type == None:
state_type = self.type_id
def get_state(self, state_type):
try:
return self.states.get(type=state_type)
except State.DoesNotExist:
return None
class Meta:
abstract = True
def get_state_slug(self, state_type=None):
"""Get state of type, or default if not specified, returning
the slug of the state or None. This frees the caller of having
to check against None before accessing the slug for a
comparison."""
s = self.get_state(state_type)
if s:
return s.slug
else:
return None
def author_list(self):
return ", ".join(email.address for email in self.authors.all())
class Meta:
abstract = True
class RelatedDocument(models.Model):
source = models.ForeignKey('Document')
target = models.ForeignKey('DocAlias')
@ -128,7 +142,7 @@ class Document(DocumentInfo):
def get_absolute_url(self):
name = self.name
if self.state == "rfc":
if self.get_state_slug() == "rfc":
aliases = self.docalias_set.filter(name__startswith="rfc")
if aliases:
name = aliases[0].name
@ -152,7 +166,7 @@ class Document(DocumentInfo):
def canonical_name(self):
name = self.name
if self.type_id == "draft" and self.state_id == "rfc":
if self.type_id == "draft" and self.get_state() == "rfc":
a = self.docalias_set.filter(name__startswith="rfc")
if a:
name = a[0].name

View file

@ -12,12 +12,12 @@ class InternetDraft(Document):
objects = TranslatingManager(dict(filename="name",
filename__contains="name__contains",
id_document_tag="pk",
status=lambda v: ("state", { 1: 'active', 2: 'expired', 3: 'rfc', 4: 'auth-rm', 5: 'repl', 6: 'ietf-rm'}[v]),
status=lambda v: ("states__slug", { 1: 'active', 2: 'expired', 3: 'rfc', 4: 'auth-rm', 5: 'repl', 6: 'ietf-rm'}[v], "states__type", "draft"),
job_owner="ad",
rfc_number=lambda v: ("docalias__name", "rfc%s" % v),
cur_state="iesg_state__order",
cur_state=lambda v: ("states__order", v, 'states__type', 'draft-iesg'),
idinternal__primary_flag=None,
idinternal__cur_state__state="iesg_state__name",
idinternal__cur_state__state=lambda v: ("states__name", v, 'states__type', 'draft-iesg'),
), always_filter=dict(type="draft"))
DAYS_TO_EXPIRE=185
@ -89,11 +89,12 @@ class InternetDraft(Document):
#status = models.ForeignKey(IDStatus)
@property
def status(self):
return IDStatus().from_object(self.state) if self.state else None
s = self.get_state()
return IDStatus().from_object(s) if s else None
@property
def status_id(self):
return { 'active': 1, 'repl': 5, 'expired': 2, 'rfc': 3, 'auth-rm': 4, 'ietf-rm': 6 }[self.state_id]
return { 'active': 1, 'repl': 5, 'expired': 2, 'rfc': 3, 'auth-rm': 4, 'ietf-rm': 6 }[self.get_state_slug()]
#intended_status = models.ForeignKey(IDIntendedStatus)
@property
@ -180,7 +181,7 @@ class InternetDraft(Document):
e = self.latest_event(type="started_iesg_process")
if e:
start = e.time
if self.state_id == "rfc" and self.name.startswith("draft") and not hasattr(self, "viewing_as_rfc"):
if self.get_state_slug() == "rfc" and self.name.startswith("draft") and not hasattr(self, "viewing_as_rfc"):
previous_process = self.latest_event(type="started_iesg_process", time__lt=e.time)
if previous_process:
start = previous_process.time
@ -211,7 +212,7 @@ class InternetDraft(Document):
e = self.changed_ballot_position
else:
e = self.latest_event(type="changed_ballot_position")
return self if self.iesg_state or e else None
return self if e or self.get_state("draft-iesg") else None
# reverse relationship
@property
@ -238,7 +239,7 @@ class InternetDraft(Document):
return self.docstate()
def revision_display(self):
r = int(self.revision)
if self.state_id != 'active' and not self.expired_tombstone:
if self.get_state_slug() != 'active' and not self.expired_tombstone:
r = max(r - 1, 0)
return "%02d" % r
def expiration(self):
@ -296,7 +297,7 @@ class InternetDraft(Document):
#rfc_flag = models.IntegerField(null=True)
@property
def rfc_flag(self):
return self.state_id == "rfc"
return self.get_state_slug() == "rfc"
#ballot = models.ForeignKey(BallotInfo, related_name='drafts', db_column="ballot_id")
@property
@ -345,17 +346,23 @@ class InternetDraft(Document):
#cur_state = models.ForeignKey(IDState, db_column='cur_state', related_name='docs')
@property
def cur_state(self):
return IDState().from_object(self.iesg_state) if self.iesg_state else None
s = self.get_state("draft-iesg")
return IDState().from_object(s) if s else None
@property
def cur_state_id(self):
return self.iesg_state.order if self.iesg_state else None
s = self.get_state("draft-iesg")
return s.order if s else None
#prev_state = models.ForeignKey(IDState, db_column='prev_state', related_name='docs_prev')
@property
def prev_state(self):
ds = self.history_set.exclude(iesg_state=self.iesg_state).order_by('-time')[:1]
return IDState().from_object(ds[0].iesg_state) if ds else None
ds = self.history_set.exclude(states=self.get_state("draft-iesg")).order_by('-time')[:1]
if ds:
s = ds[0].get_state("draft-iesg")
if s:
return IDState().from_object(s) if ds else None
return None
#assigned_to = models.CharField(blank=True, max_length=25) # unused
@ -491,20 +498,19 @@ class InternetDraft(Document):
def ballot_others(self):
return []
def docstate(self):
if self.iesg_state:
return self.iesg_state.name
s = self.get_state("draft-iesg")
if s:
return s.name
else:
return "I-D Exists"
def change_state(self, state, sub_state):
self.iesg_state = state
# things from BallotInfo
#active = models.BooleanField()
@property
def active(self):
# taken from BallotWrapper
return self.latest_event(type="sent_ballot_announcement") and self.iesg_state and self.iesg_state.name in ['In Last Call', 'Waiting for Writeup', 'Waiting for AD Go-Ahead', 'IESG Evaluation', 'IESG Evaluation - Defer'] and (self.state_id == "rfc" or self.state_id == "active")
s = self.get_state("draft-iesg")
return self.latest_event(type="sent_ballot_announcement") and s and s.name in ['In Last Call', 'Waiting for Writeup', 'Waiting for AD Go-Ahead', 'IESG Evaluation', 'IESG Evaluation - Defer'] and (self.get_state_slug() in ("rfc", "active"))
#an_sent = models.BooleanField()
@property
@ -528,7 +534,7 @@ class InternetDraft(Document):
@property
def defer(self):
# we're deferred if we're in the deferred state
return self.iesg_state and self.iesg_state.name == "IESG Evaluation - Defer"
return self.get_state_slug("draft-iesg") == "defer"
#defer_by = models.ForeignKey(IESGLogin, db_column='defer_by', related_name='deferred', null=True)
@property
@ -916,3 +922,82 @@ class ObjectHistoryEntryProxy(DocEvent):
class Meta:
proxy = True
class IDStatus(State):
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
#status_id = models.AutoField(primary_key=True)
#status = models.CharField(max_length=25, db_column='status_value')
@property
def status(self):
return self.name
def __unicode__(self):
return super(self.__class__, self).__unicode__()
class Meta:
proxy = True
class IDState(State):
PUBLICATION_REQUESTED = 10
LAST_CALL_REQUESTED = 15
IN_LAST_CALL = 16
WAITING_FOR_WRITEUP = 18
WAITING_FOR_AD_GO_AHEAD = 19
IESG_EVALUATION = 20
IESG_EVALUATION_DEFER = 21
APPROVED_ANNOUNCEMENT_SENT = 30
AD_WATCHING = 42
DEAD = 99
DO_NOT_PUBLISH_STATES = (33, 34)
objects = TranslatingManager(dict(pk="order",
document_state_id="order",
document_state_id__in="order__in"))
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
#document_state_id = models.AutoField(primary_key=True)
@property
def document_state_id(self):
return self.order
#state = models.CharField(max_length=50, db_column='document_state_val')
@property
def state(self):
return self.name
#equiv_group_flag = models.IntegerField(null=True, blank=True) # unused
#description = models.TextField(blank=True, db_column='document_desc')
@property
def description(self):
return self.desc
@property
def nextstate(self):
# simulate related queryset
return IDState.objects.filter(pk__in=[x.pk for x in self.next_states])
@property
def next_state(self):
# simulate IDNextState
return self
def __str__(self):
return self.state
@staticmethod
def choices():
return [(state.pk, state.name) for state in IDState.objects.all()]
class Meta:
proxy = True

View file

@ -177,7 +177,7 @@ class IETFWG(Group):
def active_drafts(self):
from redesign.doc.proxy import InternetDraft
return InternetDraft.objects.filter(group=self, state="active")
return InternetDraft.objects.filter(group=self, states__type="draft", states__slug="active")
# def choices():
# return [(wg.group_acronym_id, wg.group_acronym.acronym) for wg in IETFWG.objects.all().filter(group_type__type='WG').select_related().order_by('acronym.acronym')]
# choices = staticmethod(choices)

View file

@ -47,9 +47,10 @@ connection.queries = DontSaveQueries()
# Regarding history, we currently don't try to create DocumentHistory
# objects, we just import the comments as events.
# imports InternetDraft, IDInternal, BallotInfo, Position,
# IESGComment, IESGDiscuss, DocumentComment, IDAuthor, idrfc.RfcIndex,
# idrfc.DraftVersions, StreamedID
# imports drafts and RFCs, more specifically InternetDraft,
# IDInternal, BallotInfo, Position, IESGComment, IESGDiscuss,
# DocumentComment, IDAuthor, idrfc.RfcIndex, idrfc.DraftVersions,
# StreamedID
def alias_doc(name, doc):
@ -85,36 +86,35 @@ intended_std_level_mapping["Draft"] = intended_std_level_mapping["Draft Standard
std_level_mapping = get_std_level_mapping()
state_mapping = {
'Active': name(DocStateName, "active", "Active"),
'Expired': name(DocStateName, "expired", "Expired"),
'RFC': name(DocStateName, "rfc", "RFC"),
'Withdrawn by Submitter': name(DocStateName, "auth-rm", "Withdrawn by Submitter"),
'Replaced': name(DocStateName, "repl", "Replaced"),
'Withdrawn by IETF': name(DocStateName, "ietf-rm", "Withdrawn by IETF"),
'Active': State.objects.get(type="draft", slug="active"),
'Expired': State.objects.get(type="draft", slug="expired"),
'RFC': State.objects.get(type="draft", slug="rfc"),
'Withdrawn by Submitter': State.objects.get(type="draft", slug="auth-rm"),
'Replaced': State.objects.get(type="draft", slug="repl"),
'Withdrawn by IETF': State.objects.get(type="draft", slug="ietf-rm"),
}
iesg_state_mapping = {
'RFC Published': name(IesgDocStateName, "pub", "RFC Published", 'The ID has been published as an RFC.', order=32),
'Dead': name(IesgDocStateName, "dead", "Dead", 'Document is "dead" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.)', order=99),
'Approved-announcement to be sent': name(IesgDocStateName, "approved", "Approved-announcement to be sent", 'The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message.', order=27),
'Approved-announcement sent': name(IesgDocStateName, "ann", "Approved-announcement sent", 'The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor.', order=30),
'AD is watching': name(IesgDocStateName, "watching", "AD is watching", 'An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and "I-D Exists" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD\'s own reasons).', order=42),
'IESG Evaluation': name(IesgDocStateName, "iesg-eva", "IESG Evaluation", 'The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as "discuss" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion.', order=20),
'AD Evaluation': name(IesgDocStateName, "ad-eval", "AD Evaluation", 'A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole.', order=11),
'Last Call Requested': name(IesgDocStateName, "lc-req", "Last Call Requested", 'The AD has requested that the Secretariat start an IETF Last Call, but the the actual Last Call message has not been sent yet.', order=15),
'In Last Call': name(IesgDocStateName, "lc", "In Last Call", 'The document is currently waiting for IETF Last Call to complete. Last Calls for WG documents typically last 2 weeks, those for individual submissions last 4 weeks.', order=16),
'Publication Requested': name(IesgDocStateName, "pub-req", "Publication Requested", 'A formal request has been made to advance/publish the document, following the procedures in Section 7.5 of RFC 2418. The request could be from a WG chair, from an individual through the RFC Editor, etc. (The Secretariat (iesg-secretary@ietf.org) is copied on these requests to ensure that the request makes it into the ID tracker.) A document in this state has not (yet) been reviewed by an AD nor has any official action been taken on it yet (other than to note that its publication has been requested.', order=10),
'RFC Ed Queue': name(IesgDocStateName, "rfcqueue", "RFC Ed Queue", 'The document is in the RFC editor Queue (as confirmed by http://www.rfc-editor.org/queue.html).', order=31),
'IESG Evaluation - Defer': name(IesgDocStateName, "defer", "IESG Evaluation - Defer", 'During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat.', order=21),
'Waiting for Writeup': name(IesgDocStateName, "writeupw", "Waiting for Writeup", 'Before a standards-track or BCP document is formally considered by the entire IESG, the AD must write up a protocol action. The protocol action is included in the approval message that the Secretariat sends out when the document is approved for publication as an RFC.', order=18),
'Waiting for AD Go-Ahead': name(IesgDocStateName, "goaheadw", "Waiting for AD Go-Ahead", 'As a result of the IETF Last Call, comments may need to be responded to and a revision of the ID may be needed as well. The AD is responsible for verifying that all Last Call comments have been adequately addressed and that the (possibly revised) document is in the ID directory and ready for consideration by the IESG as a whole.', order=19),
'Expert Review': name(IesgDocStateName, "review-e", "Expert Review", 'An AD sometimes asks for an external review by an outside party as part of evaluating whether a document is ready for advancement. MIBs, for example, are reviewed by the "MIB doctors". Other types of reviews may also be requested (e.g., security, operations impact, etc.). Documents stay in this state until the review is complete and possibly until the issues raised in the review are addressed. See the "note" field for specific details on the nature of the review.', order=12),
'DNP-waiting for AD note': name(IesgDocStateName, "nopubadw", "DNP-waiting for AD note", 'Do Not Publish: The IESG recommends against publishing the document, but the writeup explaining its reasoning has not yet been produced. DNPs apply primarily to individual submissions received through the RFC editor. See the "note" field for more details on who has the action item.', order=33),
'DNP-announcement to be sent': name(IesgDocStateName, "nopubanw", "DNP-announcement to be sent", 'The IESG recommends against publishing the document, the writeup explaining its reasoning has been produced, but the Secretariat has not yet sent out the official "do not publish" recommendation message.', order=34),
'RFC Published': State.objects.get(type="draft-iesg", slug="pub"),
'Dead': State.objects.get(type="draft-iesg", slug="dead"),
'Approved-announcement to be sent': State.objects.get(type="draft-iesg", slug="approved"),
'Approved-announcement sent': State.objects.get(type="draft-iesg", slug="ann"),
'AD is watching': State.objects.get(type="draft-iesg", slug="watching"),
'IESG Evaluation': State.objects.get(type="draft-iesg", slug="iesg-eva"),
'AD Evaluation': State.objects.get(type="draft-iesg", slug="ad-eval"),
'Last Call Requested': State.objects.get(type="draft-iesg", slug="lc-req"),
'In Last Call': State.objects.get(type="draft-iesg", slug="lc"),
'Publication Requested': State.objects.get(type="draft-iesg", slug="pub-req"),
'RFC Ed Queue': State.objects.get(type="draft-iesg", slug="rfcqueue"),
'IESG Evaluation - Defer': State.objects.get(type="draft-iesg", slug="defer"),
'Waiting for Writeup': State.objects.get(type="draft-iesg", slug="writeupw"),
'Waiting for AD Go-Ahead': State.objects.get(type="draft-iesg", slug="goaheadw"),
'Expert Review': State.objects.get(type="draft-iesg", slug="review-e"),
'DNP-waiting for AD note': State.objects.get(type="draft-iesg", slug="nopubadw"),
'DNP-announcement to be sent': State.objects.get(type="draft-iesg", slug="nopubanw"),
None: None, # FIXME: consider introducing the ID-exists state
}
ballot_position_mapping = {
'No Objection': name(BallotPositionName, 'noobj', 'No Objection'),
'Yes': name(BallotPositionName, 'yes', 'Yes'),
@ -265,12 +265,13 @@ re_comment_discuss_by_tag = re.compile(r" by [\w-]+ [\w-]+$")
def import_from_idinternal(d, idinternal):
d.time = idinternal.event_date
d.iesg_state = iesg_state_mapping[idinternal.cur_state.state]
d.ad = iesg_login_to_person(idinternal.job_owner)
d.notify = idinternal.state_change_notice_to or ""
d.note = (idinternal.note or "").replace('<br>', '\n').strip().replace('\n', '<br>')
d.save()
d.set_state(iesg_state_mapping[idinternal.cur_state.state])
# extract events
last_note_change_text = ""
started_iesg_process = ""
@ -798,9 +799,10 @@ for index, o in enumerate(all_drafts.iterator()):
d.time = o.revision_date
d.type = type_draft
d.title = o.title
d.state = state_mapping[o.status.status]
d.group = Group.objects.get(acronym=o.group.acronym)
d.set_state(state_mapping[o.status.status])
# try guess stream to have a default for old submissions
if o.filename.startswith("draft-iab-"):
d.stream = stream_mapping["IAB"]
@ -812,13 +814,13 @@ for index, o in enumerate(all_drafts.iterator()):
d.stream = stream_mapping["IETF"]
try:
d.stream = stream_mapping[StreamedID.objects.get(draft=o).stream.name]
old_stream = StreamedID.objects.get(draft=o).stream
if old_stream:
d.stream = stream_mapping[old_stream.name]
except StreamedID.DoesNotExist:
pass
d.iesg_state = iesg_state_mapping[None]
d.iana_state = None
d.rfc_state = None
d.unset_state("draft-iesg")
s = workflows.utils.get_state(o)
if s:
try:
@ -1063,7 +1065,8 @@ for index, o in enumerate(all_rfcs.iterator()):
d.time = datetime.datetime.now()
d.title = o.title
d.std_level = std_level_mapping[o.current_status]
d.state = state_mapping['RFC']
d.set_state(state_mapping["RFC"])
d.stream = stream_mapping[o.stream]
if not d.group and o.wg:
d.group = Group.objects.get(acronym=o.wg)

View file

@ -14,16 +14,76 @@ management.setup_environ(settings)
import workflows.models
from ietf.ietfworkflows.models import StateDescription
from ietf.idrfc.mirror_rfc_editor_queue import get_rfc_state_mapping
from redesign.doc.models import *
# import states for documents from workflows.Workflow and
# ietfworkflows.StateDescription
# adds states for documents and import states from workflows.Workflow
# and ietfworkflows.StateDescription
# state types
ietf_state_type, _ = StateType.objects.get_or_create(slug="draft-stream-ietf", label="WG state")
irtf_state_type, _ = StateType.objects.get_or_create(slug="draft-stream-irtf", label="RG state")
ise_state_type, _ = StateType.objects.get_or_create(slug="draft-stream-ise", label="ISE state")
iab_state_type, _ = StateType.objects.get_or_create(slug="draft-stream-iab", label="IAB state")
draft_type, _ = StateType.objects.get_or_create(slug="draft", label="State")
draft_iesg_type, _ = StateType.objects.get_or_create(slug="draft-iesg", label="IESG state")
draft_iana_type, _ = StateType.objects.get_or_create(slug="draft-iana", label="IANA state")
draft_rfc_type, _ = StateType.objects.get_or_create(slug="draft-rfceditor", label="RFC Editor state")
ietf_type, _ = StateType.objects.get_or_create(slug="draft-stream-ietf", label="WG state")
irtf_type, _ = StateType.objects.get_or_create(slug="draft-stream-irtf", label="RG state")
ise_type, _ = StateType.objects.get_or_create(slug="draft-stream-ise", label="ISE state")
iab_type, _ = StateType.objects.get_or_create(slug="draft-stream-iab", label="IAB state")
# draft states
print "Importing draft states"
State.objects.get_or_create(type=draft_type, slug="active", name="Active", order=1)
State.objects.get_or_create(type=draft_type, slug="expired", name="Expired", order=2)
State.objects.get_or_create(type=draft_type, slug="rfc", name="RFC", order=3)
State.objects.get_or_create(type=draft_type, slug="repl", name="Replaced", order=4)
State.objects.get_or_create(type=draft_type, slug="auth-rm", name="Withdrawn by Submitter", order=5)
State.objects.get_or_create(type=draft_type, slug="ietf-rm", name="Withdrawn by IETF", order=6)
# IESG draft states
State.objects.get_or_create(type=draft_iesg_type, slug="pub", name="RFC Published", desc='The ID has been published as an RFC.', order=32)
State.objects.get_or_create(type=draft_iesg_type, slug="dead", name="Dead", desc='Document is "dead" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.)', order=99)
State.objects.get_or_create(type=draft_iesg_type, slug="approved", name="Approved-announcement to be sent", desc='The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message.', order=27)
State.objects.get_or_create(type=draft_iesg_type, slug="ann", name="Approved-announcement sent", desc='The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor.', order=30)
State.objects.get_or_create(type=draft_iesg_type, slug="watching", name="AD is watching", desc='An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and "I-D Exists" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD\'s own reasons).', order=42)
State.objects.get_or_create(type=draft_iesg_type, slug="iesg-eva", name="IESG Evaluation", desc='The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as "discuss" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion.', order=20)
State.objects.get_or_create(type=draft_iesg_type, slug="ad-eval", name="AD Evaluation", desc='A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole.', order=11)
State.objects.get_or_create(type=draft_iesg_type, slug="lc-req", name="Last Call Requested", desc='The AD has requested that the Secretariat start an IETF Last Call, but the the actual Last Call message has not been sent yet.', order=15)
State.objects.get_or_create(type=draft_iesg_type, slug="lc", name="In Last Call", desc='The document is currently waiting for IETF Last Call to complete. Last Calls for WG documents typically last 2 weeks, those for individual submissions last 4 weeks.', order=16)
State.objects.get_or_create(type=draft_iesg_type, slug="pub-req", name="Publication Requested", desc='A formal request has been made to advance/publish the document, following the procedures in Section 7.5 of RFC 2418. The request could be from a WG chair, from an individual through the RFC Editor, etc. (The Secretariat (iesg-secretary@ietf.org) is copied on these requests to ensure that the request makes it into the ID tracker.) A document in this state has not (yet) been reviewed by an AD nor has any official action been taken on it yet (other than to note that its publication has been requested.', order=10)
State.objects.get_or_create(type=draft_iesg_type, slug="rfcqueue", name="RFC Ed Queue", desc='The document is in the RFC editor Queue (as confirmed by http://www.rfc-editor.org/queue.html).', order=31)
State.objects.get_or_create(type=draft_iesg_type, slug="defer", name="IESG Evaluation - Defer", desc='During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat.', order=21)
State.objects.get_or_create(type=draft_iesg_type, slug="writeupw", name="Waiting for Writeup", desc='Before a standards-track or BCP document is formally considered by the entire IESG, the AD must write up a protocol action. The protocol action is included in the approval message that the Secretariat sends out when the document is approved for publication as an RFC.', order=18)
State.objects.get_or_create(type=draft_iesg_type, slug="goaheadw", name="Waiting for AD Go-Ahead", desc='As a result of the IETF Last Call, comments may need to be responded to and a revision of the ID may be needed as well. The AD is responsible for verifying that all Last Call comments have been adequately addressed and that the (possibly revised) document is in the ID directory and ready for consideration by the IESG as a whole.', order=19)
State.objects.get_or_create(type=draft_iesg_type, slug="review-e", name="Expert Review", desc='An AD sometimes asks for an external review by an outside party as part of evaluating whether a document is ready for advancement. MIBs, for example, are reviewed by the "MIB doctors". Other types of reviews may also be requested (e.g., security, operations impact, etc.). Documents stay in this state until the review is complete and possibly until the issues raised in the review are addressed. See the "note" field for specific details on the nature of the review.', order=12)
State.objects.get_or_create(type=draft_iesg_type, slug="nopubadw", name="DNP-waiting for AD note", desc='Do Not Publish: The IESG recommends against publishing the document, but the writeup explaining its reasoning has not yet been produced. DNPs apply primarily to individual submissions received through the RFC editor. See the "note" field for more details on who has the action item.', order=33)
State.objects.get_or_create(type=draft_iesg_type, slug="nopubanw", name="DNP-announcement to be sent", desc='The IESG recommends against publishing the document, the writeup explaining its reasoning has been produced, but the Secretariat has not yet sent out the official "do not publish" recommendation message.', order=34)
for s in State.objects.filter(type=draft_iesg_type):
n = {
"pub-req": ("ad-eval", "watching", "dead"),
"ad-eval": ("watching", "lc-req", "review-e", "iesg-eva"),
"review-e": ("ad-eval", ),
"lc-req": ("lc", ),
"lc": ("writeupw", "goaheadw"),
"writeupw": ("goaheadw", ),
"goaheadw": ("iesg-eva", ),
"iesg-eva": ("nopubadw", "defer", "ann"),
"defer": ("iesg-eva", ),
"ann": ("approved", ),
"approved": ("rfcqueue", ),
"rfcqueue": ("pub", ),
"pub": ("dead", ),
"nopubadw": ("nopubanw", ),
"nopubanw": ("dead", ),
"watching": ("pub-req", ),
"dead": ("pub-req", ),
}
s.next_states = State.objects.filter(type=draft_iesg_type, slug__in=n[s.slug])
# import RFC Editor queue states
print "importing RFC Editor states"
get_rfc_state_mapping()
# WG states, we can get them from the state descriptions
wg_doc_state_slug = {
@ -41,59 +101,59 @@ wg_doc_state_slug = {
for o in StateDescription.objects.all().order_by('order'):
print "importing StateDescription", o.state.name
s, _ = State.objects.get_or_create(type=ietf_state_type, slug=wg_doc_state_slug[o.state.name], name=o.state.name)
s, _ = State.objects.get_or_create(type=ietf_type, slug=wg_doc_state_slug[o.state.name], name=o.state.name)
s.desc = o.definition.replace(" ", " ").replace("\n ", "\n").replace("\n\n", "DUMMY").replace("\n", "").replace("DUMMY", "\n\n") # get rid of linebreaks, but keep paragraphs
s.order = o.order
s.save()
# IAB
print "importing IAB stream states"
State.objects.get_or_create(type=iab_state_type, slug="candidat", name="Candidate IAB Document", desc="A document being considered for the IAB stream.", order=1)
State.objects.get_or_create(type=iab_state_type, slug="active", name="Active IAB Document", desc="This document has been adopted by the IAB and is being actively developed.", order=2)
State.objects.get_or_create(type=iab_state_type, slug="parked", name="Parked IAB Document", desc="This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the IAB for some other reason. Annotations probably explain why this document is parked.", order=3)
State.objects.get_or_create(type=iab_state_type, slug="review-i", name="IAB Review", desc="This document is awaiting the IAB itself to come to internal consensus.", order=4)
State.objects.get_or_create(type=iab_state_type, slug="review-c", name="Community Review", desc="This document has completed internal consensus within the IAB and is now under community review.", order=5)
State.objects.get_or_create(type=iab_state_type, slug="approved", name="Approved by IAB, To Be Sent to RFC Editor", desc="The consideration of this document is complete, but it has not yet been sent to the RFC Editor for publication (although that is going to happen soon).", order=6)
State.objects.get_or_create(type=iab_state_type, slug="diff-org", name="Sent to a Different Organization for Publication", desc="The IAB does not expect to publish the document itself, but has passed it on to a different organization that might continue work on the document. The expectation is that the other organization will eventually publish the document.", order=7)
State.objects.get_or_create(type=iab_state_type, slug="rfc-edit", name="Sent to the RFC Editor", desc="The IAB processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the IAB.", order=8)
State.objects.get_or_create(type=iab_state_type, slug="pub", name="Published RFC", desc="The document has been published as an RFC.", order=9)
State.objects.get_or_create(type=iab_state_type, slug="dead", name="Dead IAB Document", desc="This document was an active IAB document, but for some reason it is no longer being pursued for the IAB stream. It is possible that the document might be revived later, possibly in another stream.", order=10)
State.objects.get_or_create(type=iab_type, slug="candidat", name="Candidate IAB Document", desc="A document being considered for the IAB stream.", order=1)
State.objects.get_or_create(type=iab_type, slug="active", name="Active IAB Document", desc="This document has been adopted by the IAB and is being actively developed.", order=2)
State.objects.get_or_create(type=iab_type, slug="parked", name="Parked IAB Document", desc="This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the IAB for some other reason. Annotations probably explain why this document is parked.", order=3)
State.objects.get_or_create(type=iab_type, slug="review-i", name="IAB Review", desc="This document is awaiting the IAB itself to come to internal consensus.", order=4)
State.objects.get_or_create(type=iab_type, slug="review-c", name="Community Review", desc="This document has completed internal consensus within the IAB and is now under community review.", order=5)
State.objects.get_or_create(type=iab_type, slug="approved", name="Approved by IAB, To Be Sent to RFC Editor", desc="The consideration of this document is complete, but it has not yet been sent to the RFC Editor for publication (although that is going to happen soon).", order=6)
State.objects.get_or_create(type=iab_type, slug="diff-org", name="Sent to a Different Organization for Publication", desc="The IAB does not expect to publish the document itself, but has passed it on to a different organization that might continue work on the document. The expectation is that the other organization will eventually publish the document.", order=7)
State.objects.get_or_create(type=iab_type, slug="rfc-edit", name="Sent to the RFC Editor", desc="The IAB processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the IAB.", order=8)
State.objects.get_or_create(type=iab_type, slug="pub", name="Published RFC", desc="The document has been published as an RFC.", order=9)
State.objects.get_or_create(type=iab_type, slug="dead", name="Dead IAB Document", desc="This document was an active IAB document, but for some reason it is no longer being pursued for the IAB stream. It is possible that the document might be revived later, possibly in another stream.", order=10)
# IRTF
print "importing IRTF stream states"
State.objects.get_or_create(type=irtf_state_type, slug="candidat", name="Candidate RG Document", desc="This document is under consideration in an RG for becoming an IRTF document. A document in this state does not imply any RG consensus and does not imply any precedence or selection. It's simply a way to indicate that somebody has asked for a document to be considered for adoption by an RG.", order=1)
State.objects.get_or_create(type=irtf_state_type, slug="active", name="Active RG Document", desc="This document has been adopted by the RG and is being actively developed.", order=2)
State.objects.get_or_create(type=irtf_state_type, slug="parked", name="Parked RG Document", desc="This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the RG for some other reason.", order=3)
State.objects.get_or_create(type=irtf_state_type, slug="rg-lc", name="In RG Last Call", desc="The document is in its final review in the RG.", order=4)
State.objects.get_or_create(type=irtf_state_type, slug="sheph-w", name="Waiting for Document Shepherd", desc="IRTF documents have document shepherds who help RG documents through the process after the RG has finished with the document.", order=5)
State.objects.get_or_create(type=irtf_state_type, slug="chair-w", name="Waiting for IRTF Chair", desc="The IRTF Chair is meant to be performing some task such as sending a request for IESG Review.", order=6)
State.objects.get_or_create(type=irtf_state_type, slug="irsg-w", name="Awaiting IRSG Reviews", desc="The document shepherd has taken the document to the IRSG and solicited reviews from one or more IRSG members.", order=7)
State.objects.get_or_create(type=irtf_state_type, slug="irsgpoll", name="In IRSG Poll", desc="The IRSG is taking a poll on whether or not the document is ready to be published.", order=8)
State.objects.get_or_create(type=irtf_state_type, slug="iesg-rev", name="In IESG Review", desc="The IRSG has asked the IESG to do a review of the document, as described in RFC5742.", order=9)
State.objects.get_or_create(type=irtf_state_type, slug="rfc-edit", name="Sent to the RFC Editor", desc="The RG processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the RG.", order=10)
State.objects.get_or_create(type=irtf_state_type, slug="pub", name="Published RFC", desc="The document has been published as an RFC.", order=11)
State.objects.get_or_create(type=irtf_state_type, slug="iesghold", name="Document on Hold Based On IESG Request", desc="The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the IRTF has agreed to such a hold.", order=12)
State.objects.get_or_create(type=irtf_state_type, slug="dead", name="Dead IRTF Document", desc="This document was an active IRTF document, but for some reason it is no longer being pursued for the IRTF stream. It is possible that the document might be revived later, possibly in another stream.", order=13)
State.objects.get_or_create(type=irtf_type, slug="candidat", name="Candidate RG Document", desc="This document is under consideration in an RG for becoming an IRTF document. A document in this state does not imply any RG consensus and does not imply any precedence or selection. It's simply a way to indicate that somebody has asked for a document to be considered for adoption by an RG.", order=1)
State.objects.get_or_create(type=irtf_type, slug="active", name="Active RG Document", desc="This document has been adopted by the RG and is being actively developed.", order=2)
State.objects.get_or_create(type=irtf_type, slug="parked", name="Parked RG Document", desc="This document has lost its author or editor, is waiting for another document to be written, or cannot currently be worked on by the RG for some other reason.", order=3)
State.objects.get_or_create(type=irtf_type, slug="rg-lc", name="In RG Last Call", desc="The document is in its final review in the RG.", order=4)
State.objects.get_or_create(type=irtf_type, slug="sheph-w", name="Waiting for Document Shepherd", desc="IRTF documents have document shepherds who help RG documents through the process after the RG has finished with the document.", order=5)
State.objects.get_or_create(type=irtf_type, slug="chair-w", name="Waiting for IRTF Chair", desc="The IRTF Chair is meant to be performing some task such as sending a request for IESG Review.", order=6)
State.objects.get_or_create(type=irtf_type, slug="irsg-w", name="Awaiting IRSG Reviews", desc="The document shepherd has taken the document to the IRSG and solicited reviews from one or more IRSG members.", order=7)
State.objects.get_or_create(type=irtf_type, slug="irsgpoll", name="In IRSG Poll", desc="The IRSG is taking a poll on whether or not the document is ready to be published.", order=8)
State.objects.get_or_create(type=irtf_type, slug="iesg-rev", name="In IESG Review", desc="The IRSG has asked the IESG to do a review of the document, as described in RFC5742.", order=9)
State.objects.get_or_create(type=irtf_type, slug="rfc-edit", name="Sent to the RFC Editor", desc="The RG processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the RG.", order=10)
State.objects.get_or_create(type=irtf_type, slug="pub", name="Published RFC", desc="The document has been published as an RFC.", order=11)
State.objects.get_or_create(type=irtf_type, slug="iesghold", name="Document on Hold Based On IESG Request", desc="The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the IRTF has agreed to such a hold.", order=12)
State.objects.get_or_create(type=irtf_type, slug="dead", name="Dead IRTF Document", desc="This document was an active IRTF document, but for some reason it is no longer being pursued for the IRTF stream. It is possible that the document might be revived later, possibly in another stream.", order=13)
# ISE
print "importing ISE stream states"
State.objects.get_or_create(type=ise_state_type, slug="receive", name="Submission Received", desc="The draft has been sent to the ISE with a request for publication.", order=1)
State.objects.get_or_create(type=ise_state_type, slug="find-rev", name="Finding Reviewers", desc=" The ISE is finding initial reviewers for the document.", order=2)
State.objects.get_or_create(type=ise_state_type, slug="ise-rev", name="In ISE Review", desc="The ISE is actively working on the document.", order=3)
State.objects.get_or_create(type=ise_state_type, slug="need-res", name="Response to Review Needed", desc=" One or more reviews have been sent to the author, and the ISE is awaiting response.", order=4)
State.objects.get_or_create(type=ise_state_type, slug="iesg-rev", name="In IESG Review", desc="The ISE has asked the IESG to do a review of the document, as described in RFC5742.", order=5)
State.objects.get_or_create(type=ise_state_type, slug="rfc-edit", name="Sent to the RFC Editor", desc="The ISE processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the ISE.", order=6)
State.objects.get_or_create(type=ise_state_type, slug="pub", name="Published RFC", desc="The document has been published as an RFC.", order=7)
State.objects.get_or_create(type=ise_state_type, slug="dead", name="No Longer In Independent Submission Stream", desc="This document was actively considered in the Independent Submission stream, but the ISE chose not to publish it. It is possible that the document might be revived later. A document in this state may have a comment explaining the reasoning of the ISE (such as if the document was going to move to a different stream).", order=8)
State.objects.get_or_create(type=ise_state_type, slug="iesghold", name="Document on Hold Based On IESG Request", desc="The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the ISE has agreed to such a hold.", order=9)
State.objects.get_or_create(type=ise_type, slug="receive", name="Submission Received", desc="The draft has been sent to the ISE with a request for publication.", order=1)
State.objects.get_or_create(type=ise_type, slug="find-rev", name="Finding Reviewers", desc=" The ISE is finding initial reviewers for the document.", order=2)
State.objects.get_or_create(type=ise_type, slug="ise-rev", name="In ISE Review", desc="The ISE is actively working on the document.", order=3)
State.objects.get_or_create(type=ise_type, slug="need-res", name="Response to Review Needed", desc=" One or more reviews have been sent to the author, and the ISE is awaiting response.", order=4)
State.objects.get_or_create(type=ise_type, slug="iesg-rev", name="In IESG Review", desc="The ISE has asked the IESG to do a review of the document, as described in RFC5742.", order=5)
State.objects.get_or_create(type=ise_type, slug="rfc-edit", name="Sent to the RFC Editor", desc="The ISE processing of this document is complete and it has been sent to the RFC Editor for publication. The document may be in the RFC Editor's queue, or it may have been published as an RFC; this state doesn't distinguish between different states occurring after the document has left the ISE.", order=6)
State.objects.get_or_create(type=ise_type, slug="pub", name="Published RFC", desc="The document has been published as an RFC.", order=7)
State.objects.get_or_create(type=ise_type, slug="dead", name="No Longer In Independent Submission Stream", desc="This document was actively considered in the Independent Submission stream, but the ISE chose not to publish it. It is possible that the document might be revived later. A document in this state may have a comment explaining the reasoning of the ISE (such as if the document was going to move to a different stream).", order=8)
State.objects.get_or_create(type=ise_type, slug="iesghold", name="Document on Hold Based On IESG Request", desc="The IESG has requested that the document be held pending further review, as specified in RFC 5742, and the ISE has agreed to such a hold.", order=9)
# now import the next_states; we only go for the default ones, the
# WG-specific are handled in the group importer
workflows = [(ietf_state_type, workflows.models.Workflow.objects.get(name="Default WG Workflow")),
(irtf_state_type, workflows.models.Workflow.objects.get(name="IRTF Workflow")),
(ise_state_type, workflows.models.Workflow.objects.get(name="ISE Workflow")),
(iab_state_type, workflows.models.Workflow.objects.get(name="IAB Workflow")),
workflows = [(ietf_type, workflows.models.Workflow.objects.get(name="Default WG Workflow")),
(irtf_type, workflows.models.Workflow.objects.get(name="IRTF Workflow")),
(ise_type, workflows.models.Workflow.objects.get(name="ISE Workflow")),
(iab_type, workflows.models.Workflow.objects.get(name="IAB Workflow")),
]
for state_type, workflow in workflows:

View file

@ -10,11 +10,7 @@ admin.site.register(GroupStateName, NameAdmin)
admin.site.register(IesgGroupStateName, NameAdmin)
admin.site.register(RoleName, NameAdmin)
admin.site.register(DocStreamName, NameAdmin)
admin.site.register(DocStateName, NameAdmin)
admin.site.register(DocRelationshipName, NameAdmin)
admin.site.register(IesgDocStateName, NameAdmin)
admin.site.register(IanaDocStateName, NameAdmin)
admin.site.register(RfcDocStateName, NameAdmin)
admin.site.register(DocTypeName, NameAdmin)
admin.site.register(DocTagName, NameAdmin)
admin.site.register(StdLevelName, NameAdmin)

View file

@ -78,42 +78,6 @@
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="active" model="name.docstatename">
<field type="CharField" name="name">Active</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="expired" model="name.docstatename">
<field type="CharField" name="name">Expired</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="rfc" model="name.docstatename">
<field type="CharField" name="name">RFC</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="auth-rm" model="name.docstatename">
<field type="CharField" name="name">Withdrawn by Submitter</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="repl" model="name.docstatename">
<field type="CharField" name="name">Replaced</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="ietf-rm" model="name.docstatename">
<field type="CharField" name="name">Withdrawn by IETF</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="legacy" model="name.docstreamname">
<field type="CharField" name="name">Legacy</field>
<field type="TextField" name="desc"></field>
@ -192,6 +156,24 @@
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="iana-crd" model="name.doctagname">
<field type="CharField" name="name">IANA coordination</field>
<field type="TextField" name="desc">RFC-Editor/IANA Registration Coordination</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="ref" model="name.doctagname">
<field type="CharField" name="name">Holding for references</field>
<field type="TextField" name="desc">Holding for normative reference</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="missref" model="name.doctagname">
<field type="CharField" name="name">Missing references</field>
<field type="TextField" name="desc">Awaiting missing normative reference</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="point" model="name.doctagname">
<field type="CharField" name="name">Point Raised - writeup needed</field>
<field type="TextField" name="desc">IESG discussions on the document have raised some issues that need to be brought to the attention of the authors/WG, but those issues have not been written down yet. (It is common for discussions during a telechat to result in such situations. An AD may raise a possible issue during a telechat and only decide as a result of that discussion whether the issue is worth formally writing up and bringing to the attention of the authors/WG). A document stays in the "Point Raised - Writeup Needed" state until *ALL* IESG comments that have been raised have been documented.</field>
@ -426,108 +408,6 @@
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="pub-req" model="name.iesgdocstatename">
<field type="CharField" name="name">Publication Requested</field>
<field type="TextField" name="desc">A formal request has been made to advance/publish the document, following the procedures in Section 7.5 of RFC 2418. The request could be from a WG chair, from an individual through the RFC Editor, etc. (The Secretariat (iesg-secretary@ietf.org) is copied on these requests to ensure that the request makes it into the ID tracker.) A document in this state has not (yet) been reviewed by an AD nor has any official action been taken on it yet (other than to note that its publication has been requested.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">10</field>
</object>
<object pk="ad-eval" model="name.iesgdocstatename">
<field type="CharField" name="name">AD Evaluation</field>
<field type="TextField" name="desc">A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">11</field>
</object>
<object pk="review-e" model="name.iesgdocstatename">
<field type="CharField" name="name">Expert Review</field>
<field type="TextField" name="desc">An AD sometimes asks for an external review by an outside party as part of evaluating whether a document is ready for advancement. MIBs, for example, are reviewed by the "MIB doctors". Other types of reviews may also be requested (e.g., security, operations impact, etc.). Documents stay in this state until the review is complete and possibly until the issues raised in the review are addressed. See the "note" field for specific details on the nature of the review.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">12</field>
</object>
<object pk="lc-req" model="name.iesgdocstatename">
<field type="CharField" name="name">Last Call Requested</field>
<field type="TextField" name="desc">The AD has requested that the Secretariat start an IETF Last Call, but the the actual Last Call message has not been sent yet.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">15</field>
</object>
<object pk="lc" model="name.iesgdocstatename">
<field type="CharField" name="name">In Last Call</field>
<field type="TextField" name="desc">The document is currently waiting for IETF Last Call to complete. Last Calls for WG documents typically last 2 weeks, those for individual submissions last 4 weeks.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">16</field>
</object>
<object pk="writeupw" model="name.iesgdocstatename">
<field type="CharField" name="name">Waiting for Writeup</field>
<field type="TextField" name="desc">Before a standards-track or BCP document is formally considered by the entire IESG, the AD must write up a protocol action. The protocol action is included in the approval message that the Secretariat sends out when the document is approved for publication as an RFC.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">18</field>
</object>
<object pk="goaheadw" model="name.iesgdocstatename">
<field type="CharField" name="name">Waiting for AD Go-Ahead</field>
<field type="TextField" name="desc">As a result of the IETF Last Call, comments may need to be responded to and a revision of the ID may be needed as well. The AD is responsible for verifying that all Last Call comments have been adequately addressed and that the (possibly revised) document is in the ID directory and ready for consideration by the IESG as a whole.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">19</field>
</object>
<object pk="iesg-eva" model="name.iesgdocstatename">
<field type="CharField" name="name">IESG Evaluation</field>
<field type="TextField" name="desc">The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as "discuss" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">20</field>
</object>
<object pk="defer" model="name.iesgdocstatename">
<field type="CharField" name="name">IESG Evaluation - Defer</field>
<field type="TextField" name="desc">During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">21</field>
</object>
<object pk="approved" model="name.iesgdocstatename">
<field type="CharField" name="name">Approved-announcement to be sent</field>
<field type="TextField" name="desc">The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">27</field>
</object>
<object pk="ann" model="name.iesgdocstatename">
<field type="CharField" name="name">Approved-announcement sent</field>
<field type="TextField" name="desc">The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">30</field>
</object>
<object pk="rfcqueue" model="name.iesgdocstatename">
<field type="CharField" name="name">RFC Ed Queue</field>
<field type="TextField" name="desc">The document is in the RFC editor Queue (as confirmed by http://www.rfc-editor.org/queue.html).</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">31</field>
</object>
<object pk="pub" model="name.iesgdocstatename">
<field type="CharField" name="name">RFC Published</field>
<field type="TextField" name="desc">The ID has been published as an RFC.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">32</field>
</object>
<object pk="nopubadw" model="name.iesgdocstatename">
<field type="CharField" name="name">DNP-waiting for AD note</field>
<field type="TextField" name="desc">Do Not Publish: The IESG recommends against publishing the document, but the writeup explaining its reasoning has not yet been produced. DNPs apply primarily to individual submissions received through the RFC editor. See the "note" field for more details on who has the action item.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">33</field>
</object>
<object pk="nopubanw" model="name.iesgdocstatename">
<field type="CharField" name="name">DNP-announcement to be sent</field>
<field type="TextField" name="desc">The IESG recommends against publishing the document, the writeup explaining its reasoning has been produced, but the Secretariat has not yet sent out the official "do not publish" recommendation message.</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">34</field>
</object>
<object pk="watching" model="name.iesgdocstatename">
<field type="CharField" name="name">AD is watching</field>
<field type="TextField" name="desc">An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and "I-D Exists" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD's own reasons).</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">42</field>
</object>
<object pk="dead" model="name.iesgdocstatename">
<field type="CharField" name="name">Dead</field>
<field type="TextField" name="desc">Document is "dead" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.)</field>
<field type="BooleanField" name="used">1</field>
<field type="IntegerField" name="order">99</field>
</object>
<object pk="ps" model="name.intendedstdlevelname">
<field type="CharField" name="name">Proposed Standard</field>
<field type="TextField" name="desc"></field>
@ -804,58 +684,64 @@
<object pk="draft-stream-iab" model="doc.statetype">
<field type="CharField" name="label">IAB state</field>
</object>
<object pk="1" model="doc.state">
<object pk="draft-iana" model="doc.statetype">
<field type="CharField" name="label">IANA state</field>
</object>
<object pk="draft-rfc" model="doc.statetype">
<field type="CharField" name="label">RFC state</field>
</object>
<object pk="69" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
<field type="SlugField" name="slug">active</field>
<field type="CharField" name="name">Active</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc"></field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">1</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="2" model="doc.state">
<object pk="70" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
<field type="SlugField" name="slug">expired</field>
<field type="CharField" name="name">Expired</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc"></field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">2</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="3" model="doc.state">
<object pk="71" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
<field type="SlugField" name="slug">rfc</field>
<field type="CharField" name="name">RFC</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc"></field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">3</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="4" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
<field type="SlugField" name="slug">auth-rm</field>
<field type="CharField" name="name">Withdrawn by Submitter</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc"></field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="5" model="doc.state">
<object pk="72" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
<field type="SlugField" name="slug">repl</field>
<field type="CharField" name="name">Replaced</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc"></field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">4</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="6" model="doc.state">
<object pk="73" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
<field type="SlugField" name="slug">auth-rm</field>
<field type="CharField" name="name">Withdrawn by Submitter</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc"></field>
<field type="IntegerField" name="order">5</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="74" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft</field>
<field type="SlugField" name="slug">ietf-rm</field>
<field type="CharField" name="name">Withdrawn by IETF</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc"></field>
<field type="IntegerField" name="order">0</field>
<field type="IntegerField" name="order">6</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="7" model="doc.state">
@ -865,7 +751,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">A formal request has been made to advance/publish the document, following the procedures in Section 7.5 of RFC 2418. The request could be from a WG chair, from an individual through the RFC Editor, etc. (The Secretariat (iesg-secretary@ietf.org) is copied on these requests to ensure that the request makes it into the ID tracker.) A document in this state has not (yet) been reviewed by an AD nor has any official action been taken on it yet (other than to note that its publication has been requested.</field>
<field type="IntegerField" name="order">10</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="22"></object><object pk="23"></object></field>
</object>
<object pk="8" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -874,7 +760,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole.</field>
<field type="IntegerField" name="order">11</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="9"></object></field>
</object>
<object pk="9" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -883,7 +769,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">An AD sometimes asks for an external review by an outside party as part of evaluating whether a document is ready for advancement. MIBs, for example, are reviewed by the "MIB doctors". Other types of reviews may also be requested (e.g., security, operations impact, etc.). Documents stay in this state until the review is complete and possibly until the issues raised in the review are addressed. See the "note" field for specific details on the nature of the review.</field>
<field type="IntegerField" name="order">12</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="8"></object></field>
</object>
<object pk="10" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -928,7 +814,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as "discuss" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion.</field>
<field type="IntegerField" name="order">20</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="15"></object></field>
</object>
<object pk="15" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -937,7 +823,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat.</field>
<field type="IntegerField" name="order">21</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="14"></object></field>
</object>
<object pk="16" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -946,7 +832,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message.</field>
<field type="IntegerField" name="order">27</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="17"></object></field>
</object>
<object pk="17" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -955,7 +841,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor.</field>
<field type="IntegerField" name="order">30</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="16"></object></field>
</object>
<object pk="18" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -1000,7 +886,7 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and "I-D Exists" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD's own reasons).</field>
<field type="IntegerField" name="order">42</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="7"></object></field>
</object>
<object pk="23" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-iesg</field>
@ -1009,6 +895,105 @@
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Document is "dead" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.)</field>
<field type="IntegerField" name="order">99</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="7"></object></field>
</object>
<object pk="79" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">edit</field>
<field type="CharField" name="name">EDIT</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Approved by the stream manager (e.g., IESG, IAB, IRSG, ISE), awaiting processing and publishing</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="78" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">auth48</field>
<field type="CharField" name="name">AUTH48</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Awaiting final author approval</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="77" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">auth</field>
<field type="CharField" name="name">AUTH</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Awaiting author action</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="80" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">iana-crd</field>
<field type="CharField" name="name">IANA</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">RFC-Editor/IANA Registration Coordination</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="81" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">iesg</field>
<field type="CharField" name="name">IESG</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Holding for IESG action</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="82" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">isr</field>
<field type="CharField" name="name">ISR</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Independent Submission Review by the ISE </field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="83" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">isr-auth</field>
<field type="CharField" name="name">ISR-AUTH</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Independent Submission awaiting author update, or in discussion between author and ISE</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="84" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">ref</field>
<field type="CharField" name="name">REF</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Holding for normative reference</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="85" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">rfc-edit</field>
<field type="CharField" name="name">RFC-EDITOR</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Awaiting final RFC Editor review before AUTH48</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="86" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">timeout</field>
<field type="CharField" name="name">TO</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Time-out period during which the IESG reviews document for conflict/concurrence with other IETF working group work</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="87" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-rfc</field>
<field type="SlugField" name="slug">missref</field>
<field type="CharField" name="name">MISSREF</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">Awaiting missing normative reference</field>
<field type="IntegerField" name="order">0</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="34" model="doc.state">
@ -1165,7 +1150,7 @@
Under normal conditions, it should not be possible for an I-D to be in the "WG Document" state in more than one WG at a time. This said, I-Ds may be transferred from one WG to another with the consent of the WG Chairs and the responsible ADs.</field>
<field type="IntegerField" name="order">4</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="28"></object><object pk="29"></object><object pk="30"></object><object pk="32"></object></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="28"></object><object pk="29"></object><object pk="30"></object><object pk="76"></object></field>
</object>
<object pk="28" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-stream-ietf</field>
@ -1214,7 +1199,7 @@
It is possible for one WGLC to lead into another WGLC for the same document. For example, an I-D that completed a WGLC as an "Informational" document may need another WGLC if a decision is taken to convert the I-D into a Standards Track document.</field>
<field type="IntegerField" name="order">7</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="27"></object><object pk="31"></object></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="27"></object><object pk="75"></object></field>
</object>
<object pk="31" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-stream-ietf</field>
@ -1225,6 +1210,19 @@
A WG Chair may wish to place an I-D that receives a lot of comments during a WGLC into the "Waiting for WG Chair Go-Ahead" state. This state describes an I-D that has undergone a WGLC; however, the Chair is not yet ready to call consensus on the document.
If comments from the WGLC need to be responded to, or a revision to the I-D is needed, the Chair may place an I-D into this state until all of the WGLC comments are adequately addressed and the (possibly revised) document is in the I-D repository.</field>
<field type="IntegerField" name="order">8</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="75" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-stream-ietf</field>
<field type="SlugField" name="slug">chair-w</field>
<field type="CharField" name="name">Waiting for WG Chair Go-Ahead</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">&lt;a href="http://tools.ietf.org/html/rfc6174#section-4.2.8" target="_blank"&gt;4.2.8. Waiting for WG Chair Go-Ahead&lt;/a&gt;
A WG Chair may wish to place an I-D that receives a lot of comments during a WGLC into the "Waiting for WG Chair Go-Ahead" state. This state describes an I-D that has undergone a WGLC; however, the Chair is not yet ready to call consensus on the document.
If comments from the WGLC need to be responded to, or a revision to the I-D is needed, the Chair may place an I-D into this state until all of the WGLC comments are adequately addressed and the (possibly revised) document is in the I-D repository.</field>
<field type="IntegerField" name="order">8</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="30"></object></field>
@ -1240,6 +1238,21 @@
A WG Chair may call consensus on an I-D without a formal WGLC and transition an I-D that was in the "WG Document" state directly into this state.
The name of this state includes the words "Waiting for Writeup" because a good document shepherd writeup takes time to prepare.</field>
<field type="IntegerField" name="order">9</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"></field>
</object>
<object pk="76" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-stream-ietf</field>
<field type="SlugField" name="slug">writeupw</field>
<field type="CharField" name="name">WG Consensus: Waiting for Write-Up</field>
<field type="BooleanField" name="used">1</field>
<field type="TextField" name="desc">&lt;a href="http://tools.ietf.org/html/rfc6174#section-4.2.9" target="_blank"&gt;4.2.9. WG Consensus: Waiting for Writeup&lt;/a&gt;
A document in the "WG Consensus: Waiting for Writeup" state has essentially completed its development within the working group, and is nearly ready to be sent to the IESG for publication. The last thing to be done is the preparation of a protocol writeup by a Document Shepherd. The IESG requires that a document shepherd writeup be completed before publication of the I-D is requested. The IETF document shepherding process and the role of a WG Document Shepherd is described in RFC 4858 [RFC4858]
A WG Chair may call consensus on an I-D without a formal WGLC and transition an I-D that was in the "WG Document" state directly into this state.
The name of this state includes the words "Waiting for Writeup" because a good document shepherd writeup takes time to prepare.</field>
<field type="IntegerField" name="order">9</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="27"></object><object pk="33"></object></field>
@ -1255,7 +1268,7 @@
An I-D in this state may be under review by the IESG, it may have been approved and be in the RFC Editor's queue, or it may have been published as an RFC. Other possibilities exist too. The document may be "Dead" (in the IESG state machine) or in a "Do Not Publish" state.</field>
<field type="IntegerField" name="order">10</field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="32"></object></field>
<field to="doc.state" name="next_states" rel="ManyToManyRel"><object pk="76"></object></field>
</object>
<object pk="44" model="doc.state">
<field to="doc.statetype" name="type" rel="ManyToOneRel">draft-stream-irtf</field>

View file

@ -29,22 +29,9 @@ class RoleName(NameModel):
"""AD, Chair"""
class DocStreamName(NameModel):
"""IETF, IAB, IRTF, ISE, Legacy"""
class DocStateName(NameModel):
"""Active, Expired, RFC, Replaced, Withdrawn"""
class DocRelationshipName(NameModel):
"""Updates, Replaces, Obsoletes, Reviews, ... The relationship is
always recorded in one direction.
"""
class IesgDocStateName(NameModel):
"""Pub Request, Ad Eval, Expert Review, Last Call Requested, In
Last Call, Waiting for Writeup, Waiting for AD Go-Ahead, IESG
Evaluation, Deferred, Approved, Announcement Sent, Do Not Publish,
Ad is watching, Dead """
class IanaDocStateName(NameModel):
""" """
class RfcDocStateName(NameModel):
"""Missref, Edit, RFC-Editor, Auth48, Auth, Published; ISR,
ISR-Auth, ISR-Timeout;"""
always recorded in one direction."""
class DocTypeName(NameModel):
"""Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email,
Review, Issue, Wiki"""
@ -60,7 +47,7 @@ class IntendedStdLevelName(NameModel):
class DocReminderTypeName(NameModel):
"Stream state"
class BallotPositionName(NameModel):
""" Yes, NoObjection, Abstain, Discuss, Recuse """
""" Yes, No Objection, Abstain, Discuss, Recuse """
class MeetingTypeName(NameModel):
"""IETF, Interim"""
class SessionStatusName(NameModel):
@ -71,31 +58,3 @@ class ConstraintName(NameModel):
"""Conflict"""
class LiaisonStatementPurposeName(NameModel):
"""For action, For comment, For information, In response, Other"""
def get_next_iesg_states(iesg_state):
if not iesg_state:
return ()
next = {
"pub-req": ("ad-eval", "watching", "dead"),
"ad-eval": ("watching", "lc-req", "review-e", "iesg-eva"),
"review-e": ("ad-eval", ),
"lc-req": ("lc", ),
"lc": ("writeupw", "goaheadw"),
"writeupw": ("goaheadw", ),
"goaheadw": ("iesg-eva", ),
"iesg-eva": ("nopubadw", "defer", "ann"),
"defer": ("iesg-eva", ),
"ann": ("approved", ),
"approved": ("rfcqueue", ),
"rfcqueue": ("pub", ),
"pub": ("dead", ),
"nopubadw": ("nopubanw", ),
"nopubanw": ("dead", ),
"watching": ("pub-req", ),
"dead": ("pub-req", ),
}
return IesgDocStateName.objects.filter(slug__in=next.get(iesg_state.slug, ()))

View file

@ -1,85 +1,6 @@
from redesign.proxy_utils import TranslatingManager
from models import *
class IDStatus(DocStateName):
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
#status_id = models.AutoField(primary_key=True)
#status = models.CharField(max_length=25, db_column='status_value')
@property
def status(self):
return self.name
def __unicode__(self):
return super(self.__class__, self).__unicode__()
class Meta:
proxy = True
class IDState(IesgDocStateName):
PUBLICATION_REQUESTED = 10
LAST_CALL_REQUESTED = 15
IN_LAST_CALL = 16
WAITING_FOR_WRITEUP = 18
WAITING_FOR_AD_GO_AHEAD = 19
IESG_EVALUATION = 20
IESG_EVALUATION_DEFER = 21
APPROVED_ANNOUNCEMENT_SENT = 30
AD_WATCHING = 42
DEAD = 99
DO_NOT_PUBLISH_STATES = (33, 34)
objects = TranslatingManager(dict(pk="order",
document_state_id="order",
document_state_id__in="order__in"))
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
#document_state_id = models.AutoField(primary_key=True)
@property
def document_state_id(self):
return self.order
#state = models.CharField(max_length=50, db_column='document_state_val')
@property
def state(self):
return self.name
#equiv_group_flag = models.IntegerField(null=True, blank=True) # unused
#description = models.TextField(blank=True, db_column='document_desc')
@property
def description(self):
return self.desc
@property
def nextstate(self):
# simulate related queryset
from name.models import get_next_iesg_states
return IDState.objects.filter(pk__in=[x.pk for x in get_next_iesg_states(self)])
@property
def next_state(self):
# simulate IDNextState
return self
def __str__(self):
return self.state
@staticmethod
def choices():
return [(state.slug, state.name) for state in IDState.objects.all()]
class Meta:
proxy = True
class IDSubStateManager(TranslatingManager):
def __init__(self, *args):
super(IDSubStateManager, self).__init__(*args)

View file

@ -63,7 +63,7 @@ class Person(PersonInfo):
def person(self): # little temporary wrapper to help porting to new schema
return self
class PersonHistory(PersonInfo):
person = models.ForeignKey(Person, related_name="history_set")
user = models.ForeignKey(User, blank=True, null=True)

View file

@ -12,6 +12,9 @@ def proxy_role_email(e):
e.person.email = lambda: (e.person.name, e.address)
return e
def chunks(l, n):
"""Split list l up in chunks of max size n."""
return (l[i:i+n] for i in range(0, len(l), n))
class TranslatingQuerySet(QuerySet):
def translated_args(self, args):
@ -42,10 +45,13 @@ class TranslatingQuerySet(QuerySet):
if k in trans:
t = trans[k]
if callable(t):
t, v = t(v)
ts = t(v)
else:
ts = (t, v)
if t:
res[t] = v
for t, v in chunks(ts, 2):
if t:
res[t] = v
else:
res[k] = v
return res