%s
" % self.desc + + class Meta: + proxy = True diff --git a/redesign/group/admin.py b/redesign/group/admin.py index 286f64b0d..3665fbd9a 100644 --- a/redesign/group/admin.py +++ b/redesign/group/admin.py @@ -17,7 +17,7 @@ class GroupAdmin(admin.ModelAdmin): list_display = ["acronym", "name", "type", "role_list"] list_display_links = ["acronym", "name"] list_filter = ["type"] - search_fields = ["name"] + search_fields = ["acronym", "name"] ordering = ["name"] raw_id_fields = ["charter", "parent", "ad"] diff --git a/redesign/group/models.py b/redesign/group/models.py index 8ae2e1c23..13434745e 100644 --- a/redesign/group/models.py +++ b/redesign/group/models.py @@ -19,6 +19,10 @@ class GroupInfo(models.Model): list_subscribe = models.CharField(max_length=255, blank=True) list_archive = models.CharField(max_length=255, blank=True) comments = models.TextField(blank=True) + + unused_states = models.ManyToManyField('doc.State', help_text="Document states that have been disabled for the group") + unused_tags = models.ManyToManyField(DocTagName, help_text="Document tags that have been disabled for the group") + def __unicode__(self): return self.name @@ -62,6 +66,13 @@ class GroupMilestone(models.Model): class Meta: ordering = ['expected_due_date'] +class GroupStateTransitions(models.Model): + """Captures that a group has overriden the default available + document state transitions for a certain state.""" + group = models.ForeignKey(Group) + state = models.ForeignKey('doc.State', help_text="State for which the next states should be overridden") + next_states = models.ManyToManyField('doc.State', related_name='previous_groupstatetransitions_states') + GROUP_EVENT_CHOICES = [("proposed", "Proposed group"), ("started", "Started group"), ("concluded", "Concluded group"), @@ -101,3 +112,6 @@ class RoleHistory(models.Model): email = models.ForeignKey(Email, help_text="Email address used by person for this role") def __unicode__(self): return u"%s is %s in %s" % (self.email.get_name(), self.name.name, self.group.acronym) + + class Meta: + verbose_name_plural = "role histories" diff --git a/redesign/group/proxy.py b/redesign/group/proxy.py index c0f929a48..cf87bc0e2 100644 --- a/redesign/group/proxy.py +++ b/redesign/group/proxy.py @@ -98,6 +98,7 @@ class IETFWG(Group): objects = TranslatingManager(dict(group_acronym="id", group_acronym__acronym="acronym", group_acronym__acronym__in="acronym__in", + group_acronym__acronym__contains="acronym__contains", email_archive__startswith="list_archive__startswith", group_type=lambda v: ("type", { 1: "wg" }[int(v)]), status=lambda v: ("state", { 1: "active" }[int(v)]), diff --git a/redesign/importing/import-all.sh b/redesign/importing/import-all.sh index 9ff0f3894..cc15c7c0e 100755 --- a/redesign/importing/import-all.sh +++ b/redesign/importing/import-all.sh @@ -3,6 +3,7 @@ # basic dependencies set -e python import-persons.py +python import-states.py python import-groups.py python import-roles.py diff --git a/redesign/importing/import-document-state.py b/redesign/importing/import-document-state.py index 76207a0a0..ac1239905 100755 --- a/redesign/importing/import-document-state.py +++ b/redesign/importing/import-document-state.py @@ -11,7 +11,10 @@ settings.USE_DB_REDESIGN_PROXY_CLASSES = False from django.core import management management.setup_environ(settings) +from django.template.defaultfilters import pluralize + from redesign.doc.models import * +from redesign.doc.utils import get_tags_for_stream_id from redesign.group.models import * from redesign.name.models import * from redesign.importing.utils import old_person_to_person, person_name @@ -19,8 +22,9 @@ from redesign.name.utils import name from ietf.idtracker.models import InternetDraft, IDInternal, IESGLogin, DocumentComment, PersonOrOrgInfo, Rfc, IESGComment, IESGDiscuss, BallotInfo, Position from ietf.idrfc.models import RfcIndex, DraftVersions from ietf.idrfc.mirror_rfc_index import get_std_level_mapping, get_stream_mapping -#from ietf.ietfworkflows.utils import get_state_for_draft - +from ietf.ietfworkflows.models import StreamedID, AnnotationTag, ContentType, ObjectHistoryEntry, ObjectWorkflowHistoryEntry, ObjectAnnotationTagHistoryEntry, ObjectStreamHistoryEntry, StateObjectRelationMetadata +import workflows.utils +from ietf.wgchairs.models import ProtoWriteUp document_name_to_import = None if len(sys.argv) > 1: @@ -28,13 +32,14 @@ if len(sys.argv) > 1: # prevent memory from leaking when settings.DEBUG=True from django.db import connection -class DummyQueries(object): +class DontSaveQueries(object): def append(self, x): pass -connection.queries = DummyQueries() +connection.queries = DontSaveQueries() # assumptions: +# - states have been imported # - groups have been imported # - IESG login emails/roles have been imported # - IDAuthor emails/persons have been imported @@ -44,7 +49,7 @@ connection.queries = DummyQueries() # imports InternetDraft, IDInternal, BallotInfo, Position, # IESGComment, IESGDiscuss, DocumentComment, IDAuthor, idrfc.RfcIndex, -# idrfc.DraftVersions +# idrfc.DraftVersions, StreamedID def alias_doc(name, doc): @@ -55,6 +60,7 @@ def alias_doc(name, doc): type_draft = name(DocTypeName, "draft", "Draft") stream_mapping = get_stream_mapping() +stream_mapping["ISE"] = stream_mapping["INDEPENDENT"] relationship_replaces = name(DocRelationshipName, "replaces", "Replaces") relationship_updates = name(DocRelationshipName, "updates", "Updates") @@ -108,13 +114,14 @@ iesg_state_mapping = { None: None, # FIXME: consider introducing the ID-exists state } + ballot_position_mapping = { 'No Objection': name(BallotPositionName, 'noobj', 'No Objection'), 'Yes': name(BallotPositionName, 'yes', 'Yes'), 'Abstain': name(BallotPositionName, 'abstain', 'Abstain'), 'Discuss': name(BallotPositionName, 'discuss', 'Discuss'), 'Recuse': name(BallotPositionName, 'recuse', 'Recuse'), - 'No Record': name(BallotPositionName, 'norecord', 'No record'), + 'No Record': name(BallotPositionName, 'norecord', 'No Record'), } ballot_position_mapping["no"] = ballot_position_mapping['No Objection'] ballot_position_mapping["yes"] = ballot_position_mapping['Yes'] @@ -124,26 +131,49 @@ ballot_position_mapping["recuse"] = ballot_position_mapping['Recuse'] ballot_position_mapping[None] = ballot_position_mapping["No Record"] ballot_position_mapping["Undefined"] = ballot_position_mapping["No Record"] +# tags substate_mapping = { - "External Party": name(DocInfoTagName, 'extpty', "External Party", 'The document is awaiting review or input from an external party (i.e, someone other than the shepherding AD, the authors, or the WG). See the "note" field for more details on who has the action.', 3), - "Revised ID Needed": name(DocInfoTagName, 'need-rev', "Revised ID Needed", 'An updated ID is needed to address the issues that have been raised.', 5), - "AD Followup": name(DocInfoTagName, 'ad-f-up', "AD Followup", """A generic substate indicating that the shepherding AD has the action item to determine appropriate next steps. In particular, the appropriate steps (and the corresponding next state or substate) depend entirely on the nature of the issues that were raised and can only be decided with active involvement of the shepherding AD. Examples include: + "External Party": name(DocTagName, 'extpty', "External Party", 'The document is awaiting review or input from an external party (i.e, someone other than the shepherding AD, the authors, or the WG). See the "note" field for more details on who has the action.', 3), + "Revised ID Needed": name(DocTagName, 'need-rev', "Revised ID Needed", 'An updated ID is needed to address the issues that have been raised.', 5), + "AD Followup": name(DocTagName, 'ad-f-up', "AD Followup", """A generic substate indicating that the shepherding AD has the action item to determine appropriate next steps. In particular, the appropriate steps (and the corresponding next state or substate) depend entirely on the nature of the issues that were raised and can only be decided with active involvement of the shepherding AD. Examples include: - if another AD raises an issue, the shepherding AD may first iterate with the other AD to get a better understanding of the exact issue. Or, the shepherding AD may attempt to argue that the issue is not serious enough to bring to the attention of the authors/WG. - if a documented issue is forwarded to a WG, some further iteration may be needed before it can be determined whether a new revision is needed or whether the WG response to an issue clarifies the issue sufficiently. - when a new revision appears, the shepherding AD will first look at the changes to determine whether they believe all outstanding issues have been raised satisfactorily, prior to asking the ADs who raised the original issues to verify the changes.""", 2), - "Point Raised - writeup needed": name(DocInfoTagName, 'point', "Point Raised - writeup needed", 'IESG discussions on the document have raised some issues that need to be brought to the attention of the authors/WG, but those issues have not been written down yet. (It is common for discussions during a telechat to result in such situations. An AD may raise a possible issue during a telechat and only decide as a result of that discussion whether the issue is worth formally writing up and bringing to the attention of the authors/WG). A document stays in the "Point Raised - Writeup Needed" state until *ALL* IESG comments that have been raised have been documented.', 1) + "Point Raised - writeup needed": name(DocTagName, 'point', "Point Raised - writeup needed", 'IESG discussions on the document have raised some issues that need to be brought to the attention of the authors/WG, but those issues have not been written down yet. (It is common for discussions during a telechat to result in such situations. An AD may raise a possible issue during a telechat and only decide as a result of that discussion whether the issue is worth formally writing up and bringing to the attention of the authors/WG). A document stays in the "Point Raised - Writeup Needed" state until *ALL* IESG comments that have been raised have been documented.', 1) } -#wg_state_mapping = dict([(s.slug, s) for s in WGDocStateName.objects.all()] + [(None, None)]) +tag_review_by_rfc_editor = name(DocTagName, 'rfc-rev', "Review by RFC Editor") +tag_via_rfc_editor = name(DocTagName, 'via-rfc', "Via RFC Editor") +tag_expired_tombstone = name(DocTagName, 'exp-tomb', "Expired tombstone") +tag_approved_in_minute = name(DocTagName, 'app-min', "Approved in minute") +tag_has_errata = name(DocTagName, 'errata', "Has errata") + +name(DocTagName, "w-expert", "Awaiting Expert Review/Resolution of Issues Raised", order=1) +name(DocTagName, "w-extern", "Awaiting External Review/Resolution of Issues Raised", order=2) +name(DocTagName, "w-merge", "Awaiting Merge with Other Document", order=3) +name(DocTagName, "need-aut", "Author or Editor Needed", order=4) +name(DocTagName, "w-refdoc", "Waiting for Referenced Document", order=5) +name(DocTagName, "w-refing", "Waiting for Referencing Document", order=6) +name(DocTagName, "rev-wglc", "Revised I-D Needed - Issue raised by WGLC", order=7) +name(DocTagName, "rev-ad", "Revised I-D Needed - Issue raised by AD", order=8) +name(DocTagName, "rev-iesg", "Revised I-D Needed - Issue raised by IESG", order=9) +name(DocTagName, "sheph-u", "Doc Shepherd Follow-up Underway", order=10) +name(DocTagName, "other", "Other - see Comment Log", order=11) +name(DocTagName, "need-ed", "Editor Needed", order=1) +name(DocTagName, "w-part", "Waiting for Partner Feedback", order=2) +name(DocTagName, "w-review", "Awaiting Reviews", order=3) +name(DocTagName, "sh-f-up", "Document Shepherd Followup", order=4) +name(DocTagName, "need-sh", "Shepherd Needed") +name(DocTagName, "w-dep", "Waiting for Dependency on Other Document") +name(DocTagName, "iesg-com", "IESG Review Completed") + +stream_state_reminder_type = name(DocReminderTypeName, "stream-s", "Stream state should change") + +#tag_mapping = dict((t.name, t) for t in DocTagName.objects.all()) -tag_review_by_rfc_editor = name(DocInfoTagName, 'rfc-rev', "Review by RFC Editor") -tag_via_rfc_editor = name(DocInfoTagName, 'via-rfc', "Via RFC Editor") -tag_expired_tombstone = name(DocInfoTagName, 'exp-tomb', "Expired tombstone") -tag_approved_in_minute = name(DocInfoTagName, 'app-min', "Approved in minute") -tag_has_errata = name(DocInfoTagName, 'errata', "Has errata") # helpers def save_docevent(doc, event, comment): @@ -770,6 +800,8 @@ for index, o in enumerate(all_drafts.iterator()): d.title = o.title d.state = state_mapping[o.status.status] d.group = Group.objects.get(acronym=o.group.acronym) + + # try guess stream to have a default for old submissions if o.filename.startswith("draft-iab-"): d.stream = stream_mapping["IAB"] elif o.filename.startswith("draft-irtf-"): @@ -778,10 +810,25 @@ for index, o in enumerate(all_drafts.iterator()): d.stream = stream_mapping["INDEPENDENT"] else: d.stream = stream_mapping["IETF"] - d.wg_state = None #wg_state_mapping[get_state_for_draft(o)] + + try: + d.stream = stream_mapping[StreamedID.objects.get(draft=o).stream.name] + except StreamedID.DoesNotExist: + pass + d.iesg_state = iesg_state_mapping[None] d.iana_state = None d.rfc_state = None + s = workflows.utils.get_state(o) + if s: + try: + # there may be a mismatch between the stream type and the + # state because of a bug in the ietfworkflows code so try + # first without type constraint + d.set_state(State.objects.get(name=s.name)) + except State.MultipleObjectsReturned: + d.set_state(State.objects.get(type="draft-stream-%s" % d.stream_id, name=s.name)) + d.rev = o.revision d.abstract = o.abstract d.pages = o.txt_page_count @@ -836,7 +883,79 @@ for index, o in enumerate(all_drafts.iterator()): e.desc = "New version available" e.save() known_revisions.add(v.revision) - + + # ietfworkflows history entries + ctype = ContentType.objects.get_for_model(o) + for h in ObjectHistoryEntry.objects.filter(content_type=ctype, content_id=o.pk).order_by('date', 'id'): + e = DocEvent(type="changed_document") + e.time = h.date + e.by = old_person_to_person(h.person) + e.doc = d + r = h.get_real_instance() + if r: + if isinstance(r, ObjectWorkflowHistoryEntry): + s = State.objects.filter(type="draft-stream-%s" % d.stream_id, name=r.to_state) + if not s: + s = State.objects.filter(name=r.to_state) + start = "State changed" + if s: + start = "%s changed" % s[0].type.label + + e.desc = u"%s to %s from %s" % (start, r.to_state, r.from_state) + elif isinstance(r, ObjectAnnotationTagHistoryEntry): + l = [] + if r.setted: + s = r.setted.split(",") + l.append(u"Annotation tag%s %s set." % (pluralize(s), ", ".join(s))) + if r.unsetted: + s = r.unsetted.split(",") + l.append(u"Annotation tag%s %s cleared." % (pluralize(s), ", ".join(s))) + e.desc = " ".join(l) + elif isinstance(r, ObjectStreamHistoryEntry): + e.type = "changed_stream" + e.desc = u"Stream changed to %s from %s" % (r.to_stream, r.from_stream) + else: + raise Exception("Unknown ObjectHistoryEntry type: %s" % type(r)) + e.save() + + if r and isinstance(r, ObjectWorkflowHistoryEntry): + # may need to add reminder + try: + metadata = StateObjectRelationMetadata.objects.get(relation__state__name=r.to_state, + relation__content_id=o.pk, + relation__content_type=ContentType.objects.get_for_model(o)) + if metadata.estimated_date: + try: + reminder = DocReminder.objects.get(event__doc=d, type=stream_state_reminder_type) + except DocReminder.DoesNotExist: + reminder = DocReminder(type=stream_state_reminder_type) + + reminder.event = e + reminder.due = metadata.estimated_date + reminder.active = metadata.estimated_date > datetime.datetime.now() + reminder.save() + except StateObjectRelationMetadata.DoesNotExist: + pass + + if h.comment and h.comment.strip() and not d.docevent_set.filter(type="added_comment", desc=h.comment.strip(), time=h.date): + e = DocEvent(type="added_comment") + e.time = h.date + e.by = old_person_to_person(h.person) + e.doc = d + e.desc = h.comment.strip() + e.save() + + + # wgchairs protocol writeups + for w in ProtoWriteUp.objects.filter(draft=o).order_by('date'): + e = WriteupDocEvent(type="changed_protocol_writeup") + e.time = w.date + e.by = old_person_to_person(w.person) + e.doc = d + e.desc = e.get_type_display() + e.text = w.writeup + e.save() + # import events that might be missing, we can't be sure who did # them or when but if we don't generate them, we'll be missing the # information completely @@ -871,6 +990,15 @@ for index, o in enumerate(all_drafts.iterator()): sync_tag(d, o.review_by_rfc_editor, tag_review_by_rfc_editor) sync_tag(d, o.expired_tombstone, tag_expired_tombstone) + ctype = ContentType.objects.get_for_model(o) + used_tags = AnnotationTag.objects.filter(annotationtagobjectrelation__content_type=ctype, annotationtagobjectrelation__content_id=o.pk).values_list('name', flat=True) + possible_tags = get_tags_for_stream_id(d.stream_id) + for name in possible_tags: + if name == "need-rev" and o.idinternal and o.idinternal.cur_sub_state and o.idinternal.cur_sub_state.sub_state == "Revised ID Needed": + continue # don't overwrite tag from IESG substate + + sync_tag(d, name in used_tags, name) + # replacements if o.replaced_by: replacement, _ = Document.objects.get_or_create(name=o.replaced_by.filename, defaults=dict(time=datetime.datetime(1970, 1, 1, 0, 0, 0))) diff --git a/redesign/importing/import-groups.py b/redesign/importing/import-groups.py index 503b6c099..8b19f93fe 100755 --- a/redesign/importing/import-groups.py +++ b/redesign/importing/import-groups.py @@ -14,16 +14,19 @@ management.setup_environ(settings) from redesign.group.models import * from redesign.name.models import * +from redesign.doc.models import State, StateType +from redesign.doc.utils import get_tags_for_stream_id from redesign.name.utils import name from redesign.importing.utils import old_person_to_person from ietf.idtracker.models import AreaGroup, IETFWG, Area, AreaGroup, Acronym, AreaWGURL, IRTF, ChairsHistory, Role, AreaDirector from ietf.liaisons.models import SDOs +import workflows.utils # imports IETFWG, Area, AreaGroup, Acronym, IRTF, AreaWGURL, SDOs # also creates nomcom groups -# assumptions: persons have been imported +# assumptions: persons and states have been imported state_names = dict( bof=name(GroupStateName, slug="bof", name="BOF"), @@ -91,7 +94,6 @@ iab_group.save() system = Person.objects.get(name="(System)") - # NomCom for o in ChairsHistory.objects.filter(chair_type=Role.NOMCOM_CHAIR).order_by("start_year"): print "importing ChairsHistory/Nomcom", o.pk, "nomcom%s" % o.start_year @@ -300,7 +302,28 @@ for o in IETFWG.objects.all().order_by("pk"): milestone.done_date = m.done_date milestone.time = datetime.datetime.combine(m.last_modified_date, datetime.time(12, 0, 0)) milestone.save() - + + # import workflow states and transitions + w = workflows.utils.get_workflow_for_object(o) + if w: + try: + w = w.wgworkflow + except WGWorkflow.DoesNotExist: + w = None + if w: + w.unused_states = State.objects.filter(type="draft-stream-ietf").exclude(name__in=[x.name for x in w.selected_states.all()]) + w.unused_tags = DocTagName.objects.filter(slug__in=get_tags_for_stream_id("draft-stream-ietf")).exclude(name__in=[x.name for x in w.selected_tags.all()]) + + # custom transitions + states = dict((s.name, s) for s in State.objects.filter(type="draft-stream-ietf")) + old_states = dict((s.name, s) for s in w.states.filter(name__in=[name for name in states]).select_related('transitions')) + for name in old_states: + s = states[name] + o = old_states[name] + n = [states[t.destination.name] for t in o.transitions.filter(workflow=workflow)] + if set(s.next_states) != set(n): + g, _ = GroupStateTransitions.objects.get_or_create(group=group, state=s) + g.next_states = n # import events group.groupevent_set.all().delete() diff --git a/redesign/importing/import-states.py b/redesign/importing/import-states.py new file mode 100755 index 000000000..f382c835b --- /dev/null +++ b/redesign/importing/import-states.py @@ -0,0 +1,110 @@ +#!/usr/bin/python + +import sys, os, datetime + +basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) +sys.path = [ basedir ] + sys.path + +from ietf import settings +settings.USE_DB_REDESIGN_PROXY_CLASSES = False + +from django.core import management +management.setup_environ(settings) + + +import workflows.models +from ietf.ietfworkflows.models import StateDescription +from redesign.doc.models import * + +# import states for documents 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") + +# WG states, we can get them from the state descriptions +wg_doc_state_slug = { + "Call For Adoption By WG Issued": 'c-adopt', + "Adopted by a WG": 'adopt-wg', + "Adopted for WG Info Only": 'info', + "WG Document": 'wg-doc', + "Parked WG Document": 'parked', + "Dead WG Document": 'dead', + "In WG Last Call": 'wg-lc', + "Waiting for WG Chair Go-Ahead": 'chair-w', + "WG Consensus: Waiting for Write-Up": 'writeupw', + "Submitted to IESG for Publication": 'sub-pub', + } + +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.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) + +# 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) + +# 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) + +# 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")), + ] + +for state_type, workflow in workflows: + states = dict((s.name, s) for s in State.objects.filter(type=state_type)) + old_states = dict((s.name, s) for s in workflow.states.filter(name__in=[name for name in states]).select_related('transitions')) + for name in states: + print "importing workflow transitions", workflow.name, name + s = states[name] + try: + o = old_states[name] + except KeyError: + print "MISSING state", name, "in workflow", workflow.name + continue + s.next_states = [states[t.destination.name] for t in o.transitions.filter(workflow=workflow)]
(in weeks)
+ Jump to the next state: + {% for state in next_states %} + + {% endfor %} + {% endif %} +
+ {% endwith %} + +