diff --git a/ietf/idrfc/expire.py b/ietf/idrfc/expire.py
index 884a91cc1..fc3a36e9f 100644
--- a/ietf/idrfc/expire.py
+++ b/ietf/idrfc/expire.py
@@ -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
diff --git a/ietf/idrfc/idrfc_wrapper.py b/ietf/idrfc/idrfc_wrapper.py
index ee7a39567..7479c3ace 100644
--- a/ietf/idrfc/idrfc_wrapper.py
+++ b/ietf/idrfc/idrfc_wrapper.py
@@ -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
diff --git a/ietf/idrfc/lastcall.py b/ietf/idrfc/lastcall.py
index 7b9723370..bcddb9e62 100644
--- a/ietf/idrfc/lastcall.py
+++ b/ietf/idrfc/lastcall.py
@@ -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
diff --git a/ietf/idrfc/mails.py b/ietf/idrfc/mails.py
index e01b111f4..3a77ffa46 100644
--- a/ietf/idrfc/mails.py
+++ b/ietf/idrfc/mails.py
@@ -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",
diff --git a/ietf/idrfc/mirror_rfc_editor_queue.py b/ietf/idrfc/mirror_rfc_editor_queue.py
index d63834b65..50399f0b8 100644
--- a/ietf/idrfc/mirror_rfc_editor_queue.py
+++ b/ietf/idrfc/mirror_rfc_editor_queue.py
@@ -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:]:
diff --git a/ietf/idrfc/mirror_rfc_index.py b/ietf/idrfc/mirror_rfc_index.py
index 41a0be9d0..0f8cc62b7 100644
--- a/ietf/idrfc/mirror_rfc_index.py
+++ b/ietf/idrfc/mirror_rfc_index.py
@@ -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]:
diff --git a/ietf/idrfc/testsREDESIGN.py b/ietf/idrfc/testsREDESIGN.py
index 8fb0633d9..806bae77d 100644
--- a/ietf/idrfc/testsREDESIGN.py
+++ b/ietf/idrfc/testsREDESIGN.py
@@ -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"])
diff --git a/ietf/idrfc/utils.py b/ietf/idrfc/utils.py
index c19629081..e2b699810 100644
--- a/ietf/idrfc/utils.py
+++ b/ietf/idrfc/utils.py
@@ -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 %s 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 += " %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 += "
The following Last Call Announcement was sent out:
"
e.desc += writeup.text.replace("\n", "
")
diff --git a/ietf/idrfc/views_ballot.py b/ietf/idrfc/views_ballot.py
index 3ca0dee83..205ad3776 100644
--- a/ietf/idrfc/views_ballot.py
+++ b/ietf/idrfc/views_ballot.py
@@ -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 IESG Evaluation - Defer")
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)
diff --git a/ietf/idrfc/views_edit.py b/ietf/idrfc/views_edit.py
index 363dba609..e2cdf6793 100644
--- a/ietf/idrfc/views_edit.py
+++ b/ietf/idrfc/views_edit.py
@@ -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 %s" % doc.iesg_state.name
+ e.desc = "IESG process started in state %s" % 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()
diff --git a/ietf/idrfc/views_search.py b/ietf/idrfc/views_search.py
index 05cdab68a..6f6502b75 100644
--- a/ietf/idrfc/views_search.py
+++ b/ietf/idrfc/views_search.py
@@ -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")
diff --git a/ietf/idtracker/feeds.py b/ietf/idtracker/feeds.py
index 00bf8fff5..4b4a5f678 100644
--- a/ietf/idtracker/feeds.py
+++ b/ietf/idtracker/feeds.py
@@ -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()))
diff --git a/ietf/idtracker/models.py b/ietf/idtracker/models.py
index 607c0674c..611881a57 100644
--- a/ietf/idtracker/models.py
+++ b/ietf/idtracker/models.py
@@ -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
diff --git a/ietf/idtracker/views.py b/ietf/idtracker/views.py
index d525274d8..a8dcbe562 100644
--- a/ietf/idtracker/views.py
+++ b/ietf/idtracker/views.py
@@ -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))
diff --git a/ietf/iesg/views.py b/ietf/iesg/views.py
index 1867a8bf1..fee0d080f 100644
--- a/ietf/iesg/views.py
+++ b/ietf/iesg/views.py
@@ -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:
diff --git a/ietf/ietfworkflows/tests.py b/ietf/ietfworkflows/tests.py
index 46fd61953..3632a1831 100644
--- a/ietf/ietfworkflows/tests.py
+++ b/ietf/ietfworkflows/tests.py
@@ -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))
diff --git a/ietf/ietfworkflows/utils.py b/ietf/ietfworkflows/utils.py
index 17e0efdcb..ac3bab79a 100644
--- a/ietf/ietfworkflows/utils.py
+++ b/ietf/ietfworkflows/utils.py
@@ -328,18 +328,25 @@ def update_state(doc, comment, person, to_state, estimated_date=None, extra_noti
e.desc = u"%s changed to %s 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,
diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py
index ee05d79a9..053d23913 100644
--- a/ietf/submit/tests.py
+++ b/ietf/submit/tests.py
@@ -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
diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py
index bc6031854..0853f324a 100644
--- a/ietf/submit/utils.py
+++ b/ietf/submit/utils.py
@@ -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)
diff --git a/ietf/utils/test_data.py b/ietf/utils/test_data.py
index 05344b8b5..fe5125359 100644
--- a/ietf/utils/test_data.py
+++ b/ietf/utils/test_data.py
@@ -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",
diff --git a/ietf/wgchairs/tests.py b/ietf/wgchairs/tests.py
index 721b3bb9f..ce46ccffe 100644
--- a/ietf/wgchairs/tests.py
+++ b/ietf/wgchairs/tests.py
@@ -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)
diff --git a/ietf/wgchairs/views.py b/ietf/wgchairs/views.py
index 62a1c994f..6172b7de8 100644
--- a/ietf/wgchairs/views.py
+++ b/ietf/wgchairs/views.py
@@ -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'})
diff --git a/redesign/doc/admin.py b/redesign/doc/admin.py
index ede87d30c..df59432be 100644
--- a/redesign/doc/admin.py
+++ b/redesign/doc/admin.py
@@ -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):
diff --git a/redesign/doc/models.py b/redesign/doc/models.py
index 824c0cfa8..fb71c6057 100644
--- a/redesign/doc/models.py
+++ b/redesign/doc/models.py
@@ -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
diff --git a/redesign/doc/proxy.py b/redesign/doc/proxy.py
index 7d93031cc..64a92fcba 100644
--- a/redesign/doc/proxy.py
+++ b/redesign/doc/proxy.py
@@ -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
+
+
diff --git a/redesign/group/proxy.py b/redesign/group/proxy.py
index cf87bc0e2..562fc4a68 100644
--- a/redesign/group/proxy.py
+++ b/redesign/group/proxy.py
@@ -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)
diff --git a/redesign/importing/import-document-state.py b/redesign/importing/import-document-state.py
index ac1239905..1011c2f71 100755
--- a/redesign/importing/import-document-state.py
+++ b/redesign/importing/import-document-state.py
@@ -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(' ', '\n').strip().replace('\n', ' ')
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)
diff --git a/redesign/importing/import-states.py b/redesign/importing/import-states.py
index f382c835b..a113479da 100755
--- a/redesign/importing/import-states.py
+++ b/redesign/importing/import-states.py
@@ -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:
diff --git a/redesign/name/admin.py b/redesign/name/admin.py
index fccd2be08..d2ff40147 100644
--- a/redesign/name/admin.py
+++ b/redesign/name/admin.py
@@ -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)
diff --git a/redesign/name/fixtures/names.xml b/redesign/name/fixtures/names.xml
index 84b2b07aa..43aec0224 100644
--- a/redesign/name/fixtures/names.xml
+++ b/redesign/name/fixtures/names.xml
@@ -78,42 +78,6 @@
10
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-