Ported last call and expire scripts with tests to new schema
- Legacy-Id: 2878
This commit is contained in:
parent
3ecd539f7b
commit
bb2e2b10c5
|
@ -15,6 +15,6 @@ if not in_id_expire_freeze():
|
|||
for doc in get_expired_ids():
|
||||
send_expire_notice_for_id(doc)
|
||||
expire_id(doc)
|
||||
syslog.syslog("Expired %s (id=%s)%s" % (doc.file_tag(), doc.id_document_tag, " in the ID Tracker" if doc.idinternal else ""))
|
||||
syslog.syslog("Expired %s (id=%s)%s" % (doc.file_tag(), doc.pk, " in the ID Tracker" if doc.latest_event(type="started_iesg_process") else ""))
|
||||
|
||||
clean_up_id_files()
|
||||
|
|
|
@ -14,4 +14,4 @@ from ietf.idrfc.lastcall import *
|
|||
drafts = get_expired_last_calls()
|
||||
for doc in drafts:
|
||||
expire_last_call(doc)
|
||||
syslog.syslog("Expired last call for %s (id=%s)" % (doc.file_tag(), doc.id_document_tag))
|
||||
syslog.syslog("Expired last call for %s (id=%s)" % (doc.file_tag(), doc.pk))
|
||||
|
|
|
@ -9,6 +9,11 @@ import datetime, os, shutil, glob, re
|
|||
from ietf.idtracker.models import InternetDraft, IDDates, IDStatus, IDState, DocumentComment
|
||||
from ietf.utils.mail import send_mail
|
||||
from ietf.idrfc.utils import log_state_changed, add_document_comment
|
||||
from doc.models import Document, Event, save_document_in_history
|
||||
from name.models import IesgDocStateName, DocStateName, DocInfoTagName
|
||||
from person.models import Email
|
||||
|
||||
INTERNET_DRAFT_DAYS_TO_EXPIRE = 185
|
||||
|
||||
def in_id_expire_freeze(when=None):
|
||||
if when == None:
|
||||
|
@ -32,6 +37,15 @@ def get_expired_ids():
|
|||
review_by_rfc_editor=0).filter(
|
||||
Q(idinternal=None) | Q(idinternal__cur_state__document_state_id__gte=42))
|
||||
|
||||
def get_expired_idsREDESIGN():
|
||||
cut_off = datetime.date.today() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE)
|
||||
|
||||
docs = Document.objects.filter(state="active").exclude(tags="rfc-rev").filter(Q(iesg_state=None) | Q(iesg_state__order__gte=42))
|
||||
for d in docs:
|
||||
e = d.latest_event(type="new_revision")
|
||||
if e and e.time.date() <= cut_off:
|
||||
yield d
|
||||
|
||||
def send_expire_notice_for_id(doc):
|
||||
doc.dunn_sent_date = datetime.date.today()
|
||||
doc.save()
|
||||
|
@ -45,7 +59,24 @@ def send_expire_notice_for_id(doc):
|
|||
"I-D Expiring System <ietf-secretariat-reply@ietf.org>",
|
||||
u"I-D was expired %s" % doc.file_tag(),
|
||||
"idrfc/id_expired_email.txt",
|
||||
dict(doc=doc))
|
||||
dict(doc=doc,
|
||||
state=doc.idstate()))
|
||||
|
||||
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"
|
||||
|
||||
request = None
|
||||
to = doc.ad.formatted_email()
|
||||
send_mail(request, to,
|
||||
"I-D Expiring System <ietf-secretariat-reply@ietf.org>",
|
||||
u"I-D was expired %s" % doc.file_tag(),
|
||||
"idrfc/id_expired_email.txt",
|
||||
dict(doc=doc,
|
||||
state=state,
|
||||
))
|
||||
|
||||
def expire_id(doc):
|
||||
def move_file(f):
|
||||
|
@ -82,6 +113,52 @@ def expire_id(doc):
|
|||
|
||||
add_document_comment(None, doc, "Document is expired by system")
|
||||
|
||||
def expire_idREDESIGN(doc):
|
||||
system_email = Email.objects.get(address="(System)")
|
||||
|
||||
# clean up files
|
||||
def move_file(f):
|
||||
src = os.path.join(settings.INTERNET_DRAFT_PATH, f)
|
||||
dst = os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, f)
|
||||
|
||||
if os.path.exists(src):
|
||||
shutil.move(src, dst)
|
||||
|
||||
file_types = ['txt', 'ps', 'pdf']
|
||||
for t in file_types:
|
||||
move_file("%s-%s.%s" % (doc.name, doc.rev, t))
|
||||
|
||||
# make tombstone
|
||||
new_revision = "%02d" % (int(doc.rev) + 1)
|
||||
|
||||
new_file = open(os.path.join(settings.INTERNET_DRAFT_PATH, "%s-%s.txt" % (doc.name, new_revision)), 'w')
|
||||
txt = render_to_string("idrfc/expire_textREDESIGN.txt",
|
||||
dict(doc=doc,
|
||||
authors=[(e.get_name(), e.address) for e in doc.authors.all()],
|
||||
expire_days=InternetDraft.DAYS_TO_EXPIRE))
|
||||
new_file.write(txt)
|
||||
new_file.close()
|
||||
|
||||
# now change the states
|
||||
|
||||
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
|
||||
log_state_changed(None, doc, system_email, prev)
|
||||
|
||||
e = Event(doc=doc, by=system_email)
|
||||
e.type = "expired_document"
|
||||
e.desc = "Document has expired"
|
||||
e.save()
|
||||
|
||||
doc.rev = new_revision # FIXME: incrementing the revision like this is messed up
|
||||
doc.state = DocStateName.objects.get(slug="expired")
|
||||
doc.time = datetime.datetime.now()
|
||||
doc.save()
|
||||
|
||||
def clean_up_id_files():
|
||||
"""Move unidentified and old files out of the Internet Draft directory."""
|
||||
cut_off = datetime.date.today() - datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE)
|
||||
|
@ -120,3 +197,52 @@ def clean_up_id_files():
|
|||
|
||||
except InternetDraft.DoesNotExist:
|
||||
move_file_to("unknown_ids")
|
||||
|
||||
def clean_up_id_filesREDESIGN():
|
||||
"""Move unidentified and old files out of the Internet Draft directory."""
|
||||
cut_off = datetime.date.today() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE)
|
||||
|
||||
pattern = os.path.join(settings.INTERNET_DRAFT_PATH, "draft-*.*")
|
||||
files = []
|
||||
filename_re = re.compile('^(.*)-(\d+)$')
|
||||
for path in glob.glob(pattern):
|
||||
basename = os.path.basename(path)
|
||||
stem, ext = os.path.splitext(basename)
|
||||
match = filename_re.search(stem)
|
||||
if not match:
|
||||
filename, revision = ("UNKNOWN", "00")
|
||||
else:
|
||||
filename, revision = match.groups()
|
||||
|
||||
def move_file_to(subdir):
|
||||
shutil.move(path,
|
||||
os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, subdir, basename))
|
||||
|
||||
try:
|
||||
doc = Document.objects.get(name=filename, rev=revision)
|
||||
|
||||
if doc.state_id == "rfc":
|
||||
if ext != ".txt":
|
||||
move_file_to("unknown_ids")
|
||||
elif doc.state_id in ("expired", "auth-rm", "repl", "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
|
||||
|
||||
if expiration_date and expiration_date < cut_off:
|
||||
if os.path.getsize(path) < 1500:
|
||||
move_file_to("deleted_tombstones")
|
||||
# revert version after having deleted tombstone
|
||||
doc.rev = "%02d" % (int(revision) - 1) # FIXME: messed up
|
||||
doc.save()
|
||||
doc.tags.add(DocInfoTagName.objects.get(slug='exp-tomb'))
|
||||
else:
|
||||
move_file_to("expired_without_tombstone")
|
||||
|
||||
except Document.DoesNotExist:
|
||||
move_file_to("unknown_ids")
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
get_expired_ids = get_expired_idsREDESIGN
|
||||
send_expire_notice_for_id = send_expire_notice_for_idREDESIGN
|
||||
expire_id = expire_idREDESIGN
|
||||
clean_up_id_files = clean_up_id_filesREDESIGN
|
||||
|
|
|
@ -4,46 +4,55 @@
|
|||
<field type="CharField" name="name">Yes</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="noobj" model="name.ballotpositionname">
|
||||
<field type="CharField" name="name">No Objection</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="abstain" model="name.ballotpositionname">
|
||||
<field type="CharField" name="name">Abstain</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="discuss" model="name.ballotpositionname">
|
||||
<field type="CharField" name="name">Discuss</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="recuse" model="name.ballotpositionname">
|
||||
<field type="CharField" name="name">Recuse</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="norecord" model="name.ballotpositionname">
|
||||
<field type="CharField" name="name">No record</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="extpty" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">External Party</field>
|
||||
<field type="TextField" name="desc">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.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="need-rev" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">Revised ID Needed</field>
|
||||
<field type="TextField" name="desc">An updated ID is needed to address the issues that have been raised.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="iana-crd" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">IANA-coord</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ad-f-up" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">AD Followup</field>
|
||||
|
@ -55,365 +64,444 @@
|
|||
|
||||
- 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.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="point" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">Point Raised - writeup needed</field>
|
||||
<field type="TextField" name="desc">IESG discussions on the document have raised some issues that need to be brought to the attention of the authors/WG, but those issues have not been written down yet. (It is common for discussions during a telechat to result in such situations. An AD may raise a possible issue during a telechat and only decide as a result of that discussion whether the issue is worth formally writing up and bringing to the attention of the authors/WG). A document stays in the "Point Raised - Writeup Needed" state until *ALL* IESG comments that have been raised have been documented.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="missref" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">MissingRef</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="fasttrac" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">FastTrack</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="rfc-rev" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">Review by RFC Editor</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="via-rfc" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">Via RFC Editor</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="exp-tomb" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">Expired tombstone</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="app-min" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">Approved in minute</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="errata" model="name.docinfotagname">
|
||||
<field type="CharField" name="name">Has errata</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="updates" model="name.docrelationshipname">
|
||||
<field type="CharField" name="name">Updates</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="replaces" model="name.docrelationshipname">
|
||||
<field type="CharField" name="name">Replaces</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="obs" model="name.docrelationshipname">
|
||||
<field type="CharField" name="name">Obsoletes</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="reviews" model="name.docrelationshipname">
|
||||
<field type="CharField" name="name">Reviews</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="refs" model="name.docrelationshipname">
|
||||
<field type="CharField" name="name">References</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="rfc" model="name.docstatename">
|
||||
<field type="CharField" name="name">RFC</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="expired" model="name.docstatename">
|
||||
<field type="CharField" name="name">Expired</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="repl" model="name.docstatename">
|
||||
<field type="CharField" name="name">Replaced</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="active" model="name.docstatename">
|
||||
<field type="CharField" name="name">Active</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="auth-rm" model="name.docstatename">
|
||||
<field type="CharField" name="name">Withdrawn by Submitter</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ietf-rm" model="name.docstatename">
|
||||
<field type="CharField" name="name">Withdrawn by IETF</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ietf" model="name.docstreamname">
|
||||
<field type="CharField" name="name">IETF</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="indie" model="name.docstreamname">
|
||||
<field type="CharField" name="name">Independent Submission</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="legacy" model="name.docstreamname">
|
||||
<field type="CharField" name="name">Legacy</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="iab" model="name.docstreamname">
|
||||
<field type="CharField" name="name">IAB</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="irtf" model="name.docstreamname">
|
||||
<field type="CharField" name="name">IRTF</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="draft" model="name.doctypename">
|
||||
<field type="CharField" name="name">Draft</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ext" model="name.doctypename">
|
||||
<field type="CharField" name="name">External</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="bof" model="name.groupstatename">
|
||||
<field type="CharField" name="name">BOF</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="proposed" model="name.groupstatename">
|
||||
<field type="CharField" name="name">Proposed</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="active" model="name.groupstatename">
|
||||
<field type="CharField" name="name">Active</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="dormant" model="name.groupstatename">
|
||||
<field type="CharField" name="name">Dormant</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="conclude" model="name.groupstatename">
|
||||
<field type="CharField" name="name">Concluded</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="unknown" model="name.groupstatename">
|
||||
<field type="CharField" name="name">Unknown</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ietf" model="name.grouptypename">
|
||||
<field type="CharField" name="name">IETF</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="area" model="name.grouptypename">
|
||||
<field type="CharField" name="name">Area</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="wg" model="name.grouptypename">
|
||||
<field type="CharField" name="name">WG</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="rg" model="name.grouptypename">
|
||||
<field type="CharField" name="name">RG</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="team" model="name.grouptypename">
|
||||
<field type="CharField" name="name">Team</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="individ" model="name.grouptypename">
|
||||
<field type="CharField" name="name">Individual</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="pub" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">RFC Published</field>
|
||||
<field type="TextField" name="desc">The ID has been published as an RFC.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="dead" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Dead</field>
|
||||
<field type="TextField" name="desc">Document is "dead" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.)</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="ann" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Approved-announcement sent</field>
|
||||
<field type="TextField" name="desc">The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="watching" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">AD is watching</field>
|
||||
<field type="TextField" name="desc">An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and "I-D Exists" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD's own reasons).</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="iesg-eva" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">IESG Evaluation</field>
|
||||
<field type="TextField" name="desc">The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as "discuss" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="ad-eval" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">AD Evaluation</field>
|
||||
<field type="TextField" name="desc">A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="lc" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">In Last Call</field>
|
||||
<field type="TextField" name="desc">The document is currently waiting for IETF Last Call to complete. Last Calls for WG documents typically last 2 weeks, those for individual submissions last 4 weeks.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="pub-req" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Publication Requested</field>
|
||||
<field type="TextField" name="desc">A formal request has been made to advance/publish the document, following the procedures in Section 7.5 of RFC 2418. The request could be from a WG chair, from an individual through the RFC Editor, etc. (The Secretariat (iesg-secretary@ietf.org) is copied on these requests to ensure that the request makes it into the ID tracker.) A document in this state has not (yet) been reviewed by an AD nor has any official action been taken on it yet (other than to note that its publication has been requested.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">10</field>
|
||||
</object>
|
||||
<object pk="rfcqueue" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">RFC Ed Queue</field>
|
||||
<field type="TextField" name="desc">The document is in the RFC editor Queue (as confirmed by http://www.rfc-editor.org/queue.html).</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="defer" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">IESG Evaluation - Defer</field>
|
||||
<field type="TextField" name="desc">During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="writeupw" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Waiting for Writeup</field>
|
||||
<field type="TextField" name="desc">Before a standards-track or BCP document is formally considered by the entire IESG, the AD must write up a protocol action. The protocol action is included in the approval message that the Secretariat sends out when the document is approved for publication as an RFC.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="goaheadw" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Waiting for AD Go-Ahead</field>
|
||||
<field type="TextField" name="desc">As a result of the IETF Last Call, comments may need to be responded to and a revision of the ID may be needed as well. The AD is responsible for verifying that all Last Call comments have been adequately addressed and that the (possibly revised) document is in the ID directory and ready for consideration by the IESG as a whole.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="approved" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Approved-announcement to be sent</field>
|
||||
<field type="TextField" name="desc">The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message.</field>
|
||||
<object pk="ad-eval" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">AD Evaluation</field>
|
||||
<field type="TextField" name="desc">A specific AD (e.g., the Area Advisor for the WG) has begun reviewing the document to verify that it is ready for advancement. The shepherding AD is responsible for doing any necessary review before starting an IETF Last Call or sending the document directly to the IESG as a whole.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">11</field>
|
||||
</object>
|
||||
<object pk="review-e" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Expert Review</field>
|
||||
<field type="TextField" name="desc">An AD sometimes asks for an external review by an outside party as part of evaluating whether a document is ready for advancement. MIBs, for example, are reviewed by the "MIB doctors". Other types of reviews may also be requested (e.g., security, operations impact, etc.). Documents stay in this state until the review is complete and possibly until the issues raised in the review are addressed. See the "note" field for specific details on the nature of the review.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
</object>
|
||||
<object pk="nopubadw" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">DNP-waiting for AD note</field>
|
||||
<field type="TextField" name="desc">Do Not Publish: The IESG recommends against publishing the document, but the writeup explaining its reasoning has not yet been produced. DNPs apply primarily to individual submissions received through the RFC editor. See the "note" field for more details on who has the action item.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">12</field>
|
||||
</object>
|
||||
<object pk="lc-req" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Last Call requested</field>
|
||||
<field type="TextField" name="desc">The AD has requested that the Secretariat start an IETF Last Call, but the the actual Last Call message has not been sent yet.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">15</field>
|
||||
</object>
|
||||
<object pk="lc" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">In Last Call</field>
|
||||
<field type="TextField" name="desc">The document is currently waiting for IETF Last Call to complete. Last Calls for WG documents typically last 2 weeks, those for individual submissions last 4 weeks.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">16</field>
|
||||
</object>
|
||||
<object pk="writeupw" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Waiting for Writeup</field>
|
||||
<field type="TextField" name="desc">Before a standards-track or BCP document is formally considered by the entire IESG, the AD must write up a protocol action. The protocol action is included in the approval message that the Secretariat sends out when the document is approved for publication as an RFC.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">18</field>
|
||||
</object>
|
||||
<object pk="goaheadw" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Waiting for AD Go-Ahead</field>
|
||||
<field type="TextField" name="desc">As a result of the IETF Last Call, comments may need to be responded to and a revision of the ID may be needed as well. The AD is responsible for verifying that all Last Call comments have been adequately addressed and that the (possibly revised) document is in the ID directory and ready for consideration by the IESG as a whole.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">19</field>
|
||||
</object>
|
||||
<object pk="iesg-eva" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">IESG Evaluation</field>
|
||||
<field type="TextField" name="desc">The document is now (finally!) being formally reviewed by the entire IESG. Documents are discussed in email or during a bi-weekly IESG telechat. In this phase, each AD reviews the document and airs any issues they may have. Unresolvable issues are documented as "discuss" comments that can be forwarded to the authors/WG. See the description of substates for additional details about the current state of the IESG discussion.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">20</field>
|
||||
</object>
|
||||
<object pk="defer" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">IESG Evaluation - Defer</field>
|
||||
<field type="TextField" name="desc">During a telechat, one or more ADs requested an additional 2 weeks to review the document. A defer is designed to be an exception mechanism, and can only be invoked once, the first time the document comes up for discussion during a telechat.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">21</field>
|
||||
</object>
|
||||
<object pk="approved" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Approved-announcement to be sent</field>
|
||||
<field type="TextField" name="desc">The IESG has approved the document for publication, but the Secretariat has not yet sent out on official approval message.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">27</field>
|
||||
</object>
|
||||
<object pk="ann" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Approved-announcement sent</field>
|
||||
<field type="TextField" name="desc">The IESG has approved the document for publication, and the Secretariat has sent out the official approval message to the RFC editor.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">30</field>
|
||||
</object>
|
||||
<object pk="rfcqueue" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">RFC Ed Queue</field>
|
||||
<field type="TextField" name="desc">The document is in the RFC editor Queue (as confirmed by http://www.rfc-editor.org/queue.html).</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">31</field>
|
||||
</object>
|
||||
<object pk="pub" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">RFC Published</field>
|
||||
<field type="TextField" name="desc">The ID has been published as an RFC.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">32</field>
|
||||
</object>
|
||||
<object pk="nopubadw" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">DNP-waiting for AD note</field>
|
||||
<field type="TextField" name="desc">Do Not Publish: The IESG recommends against publishing the document, but the writeup explaining its reasoning has not yet been produced. DNPs apply primarily to individual submissions received through the RFC editor. See the "note" field for more details on who has the action item.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">33</field>
|
||||
</object>
|
||||
<object pk="nopubanw" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">DNP-announcement to be sent</field>
|
||||
<field type="TextField" name="desc">The IESG recommends against publishing the document, the writeup explaining its reasoning has been produced, but the Secretariat has not yet sent out the official "do not publish" recommendation message.</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">34</field>
|
||||
</object>
|
||||
<object pk="watching" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">AD is watching</field>
|
||||
<field type="TextField" name="desc">An AD is aware of the document and has chosen to place the document in a separate state in order to keep a closer eye on it (for whatever reason). Documents in this state are still not being actively tracked in the sense that no formal request has been made to publish or advance the document. The sole difference between this state and "I-D Exists" is that an AD has chosen to put it in a separate state, to make it easier to keep track of (for the AD's own reasons).</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">42</field>
|
||||
</object>
|
||||
<object pk="dead" model="name.iesgdocstatename">
|
||||
<field type="CharField" name="name">Dead</field>
|
||||
<field type="TextField" name="desc">Document is "dead" and is no longer being tracked. (E.g., it has been replaced by another document with a different name, it has been withdrawn, etc.)</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">99</field>
|
||||
</object>
|
||||
<object pk="bcp" model="name.intendedstdlevelname">
|
||||
<field type="CharField" name="name">Best Current Practice</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ds" model="name.intendedstdlevelname">
|
||||
<field type="CharField" name="name">Draft Standard</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="exp" model="name.intendedstdlevelname">
|
||||
<field type="CharField" name="name">Experimental</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="hist" model="name.intendedstdlevelname">
|
||||
<field type="CharField" name="name">Historic</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="inf" model="name.intendedstdlevelname">
|
||||
<field type="CharField" name="name">Informational</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ps" model="name.intendedstdlevelname">
|
||||
<field type="CharField" name="name">Proposed Standard</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="std" model="name.intendedstdlevelname">
|
||||
<field type="CharField" name="name">Standard</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ad" model="name.rolename">
|
||||
<field type="CharField" name="name">Area Director</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ex-ad" model="name.rolename">
|
||||
<field type="CharField" name="name">Ex-Area Director</field>
|
||||
<field type="TextField" name="desc">In-active Area Director</field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="wgeditor" model="name.rolename">
|
||||
<field type="CharField" name="name">Working Group Editor</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="std" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Standard</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ds" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Draft Standard</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="ps" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Proposed Standard</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="inf" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Informational</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="exp" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Experimental</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="bcp" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Best Current Practice</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="hist" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Historic</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
<object pk="unkn" model="name.stdlevelname">
|
||||
<field type="CharField" name="name">Unknown</field>
|
||||
<field type="TextField" name="desc"></field>
|
||||
<field type="BooleanField" name="used">1</field>
|
||||
<field type="IntegerField" name="order">0</field>
|
||||
</object>
|
||||
</django-objects>
|
|
@ -7,7 +7,10 @@ from django.conf import settings
|
|||
from ietf.idtracker.models import InternetDraft, DocumentComment, BallotInfo, IESGLogin
|
||||
from ietf.idrfc.mails import *
|
||||
from ietf.idrfc.utils import *
|
||||
from doc.models import Event
|
||||
|
||||
from doc.models import Document, Event, LastCallEvent, WriteupEvent, save_document_in_history
|
||||
from name.models import IesgDocStateName
|
||||
from person.models import Email
|
||||
|
||||
def request_last_call(request, doc):
|
||||
try:
|
||||
|
@ -42,6 +45,13 @@ def get_expired_last_calls():
|
|||
return InternetDraft.objects.filter(lc_expiration_date__lte=datetime.date.today(),
|
||||
idinternal__cur_state__document_state_id=IDState.IN_LAST_CALL)
|
||||
|
||||
def get_expired_last_callsREDESIGN():
|
||||
today = datetime.date.today()
|
||||
for d in Document.objects.filter(iesg_state="lc"):
|
||||
e = d.latest_event(LastCallEvent, type="sent_last_call")
|
||||
if e and e.expires.date() <= today:
|
||||
yield d
|
||||
|
||||
def expire_last_call(doc):
|
||||
state = IDState.WAITING_FOR_WRITEUP
|
||||
|
||||
|
@ -59,3 +69,28 @@ def expire_last_call(doc):
|
|||
log_state_changed(None, doc, by="system", email_watch_list=False)
|
||||
|
||||
email_last_call_expired(doc)
|
||||
|
||||
def expire_last_callREDESIGN(doc):
|
||||
state = IesgDocStateName.objects.get(slug="writeupw")
|
||||
|
||||
e = doc.latest_event(WriteupEvent, 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
|
||||
# write-up has been written
|
||||
state = IesgDocStateName.objects.get(slug="goaheadw")
|
||||
|
||||
save_document_in_history(doc)
|
||||
|
||||
prev = doc.iesg_state
|
||||
doc.iesg_state = state
|
||||
e = log_state_changed(None, doc, Email.objects.get(address="(System)"), prev)
|
||||
|
||||
doc.time = e.time
|
||||
doc.save()
|
||||
|
||||
email_last_call_expired(doc)
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
get_expired_last_calls = get_expired_last_callsREDESIGN
|
||||
expire_last_call = expire_last_callREDESIGN
|
||||
|
||||
|
|
|
@ -593,3 +593,19 @@ def email_last_call_expired(doc):
|
|||
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()),
|
||||
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
|
||||
|
||||
send_mail(None,
|
||||
"iesg@ietf.org",
|
||||
"DraftTracker Mail System <iesg-secretary@ietf.org>",
|
||||
"Last Call Expired: %s" % doc.file_tag(),
|
||||
"idrfc/change_notice.txt",
|
||||
dict(text=text,
|
||||
doc=doc,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()),
|
||||
cc="iesg-secretary@ietf.org")
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
email_last_call_expired = email_last_call_expiredREDESIGN
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ from django.conf import settings
|
|||
from pyquery import PyQuery
|
||||
|
||||
#from ietf.idrfc.models import *
|
||||
from ietf.idtracker.models import IESGLogin, PersonOrOrgInfo, EmailAddress
|
||||
from ietf.idtracker.models import IESGLogin, PersonOrOrgInfo, EmailAddress, IDDates
|
||||
from doc.models import *
|
||||
from name.models import *
|
||||
from group.models import *
|
||||
|
@ -73,6 +73,8 @@ def make_test_data():
|
|||
)
|
||||
|
||||
# persons
|
||||
Email.objects.get_or_create(address="(System)")
|
||||
|
||||
p = Person.objects.create(
|
||||
name="Aread Irector",
|
||||
ascii="Aread Irector",
|
||||
|
@ -163,7 +165,7 @@ def make_test_data():
|
|||
|
||||
# draft
|
||||
draft = Document.objects.create(
|
||||
name="ietf-test",
|
||||
name="draft-ietf-test",
|
||||
time=datetime.datetime.now(),
|
||||
type_id="draft",
|
||||
title="Optimizing Martian Network Topologies",
|
||||
|
@ -193,14 +195,15 @@ def make_test_data():
|
|||
desc="Added draft",
|
||||
)
|
||||
|
||||
# telechat dates
|
||||
t = datetime.date.today()
|
||||
dates = TelechatDates(date1=t,
|
||||
date2=t + datetime.timedelta(days=7),
|
||||
date3=t + datetime.timedelta(days=14),
|
||||
date4=t + datetime.timedelta(days=21),
|
||||
)
|
||||
super(dates.__class__, dates).save(force_insert=True)
|
||||
|
||||
super(dates.__class__, dates).save(force_insert=True) # work-around hard-coded save block
|
||||
|
||||
return draft
|
||||
|
||||
class ChangeStateTestCase(django.test.TestCase):
|
||||
|
@ -364,8 +367,6 @@ class EditInfoTestCase(django.test.TestCase):
|
|||
note="",
|
||||
)
|
||||
|
||||
from ietf.iesg.models import TelechatDates
|
||||
|
||||
# add to telechat
|
||||
self.assertTrue(not draft.latest_event(TelechatEvent, "scheduled_for_telechat"))
|
||||
data["telechat_date"] = TelechatDates.objects.all()[0].date1.isoformat()
|
||||
|
@ -965,7 +966,7 @@ class MakeLastCallTestCase(django.test.TestCase):
|
|||
self.assertTrue("Last Call" in mail_outbox[-3]['Subject'])
|
||||
|
||||
class ExpireIDsTestCase(django.test.TestCase):
|
||||
fixtures = ['base', 'draft']
|
||||
fixtures = ['names']
|
||||
|
||||
def setUp(self):
|
||||
self.id_dir = os.path.abspath("tmp-id-dir")
|
||||
|
@ -991,6 +992,10 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
def test_in_id_expire_freeze(self):
|
||||
from ietf.idrfc.expire import in_id_expire_freeze
|
||||
|
||||
# dummy id dates
|
||||
IDDates.objects.create(id=IDDates.SECOND_CUT_OFF, date=datetime.date(2010, 7, 12), description="", f_name="")
|
||||
IDDates.objects.create(id=IDDates.IETF_MONDAY, date=datetime.date(2010, 7, 26), description="", f_name="")
|
||||
|
||||
self.assertTrue(not in_id_expire_freeze(datetime.datetime(2010, 7, 11, 0, 0)))
|
||||
self.assertTrue(not in_id_expire_freeze(datetime.datetime(2010, 7, 12, 8, 0)))
|
||||
self.assertTrue(in_id_expire_freeze(datetime.datetime(2010, 7, 12, 10, 0)))
|
||||
|
@ -998,57 +1003,62 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
self.assertTrue(not in_id_expire_freeze(datetime.datetime(2010, 7, 26, 0, 0)))
|
||||
|
||||
def test_expire_ids(self):
|
||||
from ietf.idrfc.expire import get_expired_ids, send_expire_notice_for_id, expire_id
|
||||
from ietf.idrfc.expire import get_expired_ids, send_expire_notice_for_id, expire_id, INTERNET_DRAFT_DAYS_TO_EXPIRE
|
||||
|
||||
draft = make_test_data()
|
||||
|
||||
self.assertEquals(len(list(get_expired_ids())), 0)
|
||||
|
||||
# hack into expirable state
|
||||
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
draft.status = IDStatus.objects.get(status="Active")
|
||||
draft.review_by_rfc_editor = 0
|
||||
draft.revision_date = datetime.date.today() - datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE + 1)
|
||||
draft.idinternal.cur_state_id = IDState.AD_WATCHING
|
||||
draft.idinternal.save()
|
||||
draft.iesg_state = None
|
||||
draft.save()
|
||||
|
||||
draft = InternetDraft.objects.get(filename="draft-ah-rfc2141bis-urn")
|
||||
self.assertTrue(draft.idinternal == None)
|
||||
draft.status = IDStatus.objects.get(status="Active")
|
||||
draft.review_by_rfc_editor = 0
|
||||
draft.revision_date = datetime.date.today() - datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE + 1)
|
||||
NewRevisionEvent.objects.create(
|
||||
type="new_revision",
|
||||
by=Email.objects.get(address="aread@ietf.org"),
|
||||
doc=draft,
|
||||
desc="New revision",
|
||||
time=datetime.datetime.now() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE + 1),
|
||||
rev="01"
|
||||
)
|
||||
|
||||
self.assertEquals(len(list(get_expired_ids())), 1)
|
||||
|
||||
draft.iesg_state = IesgDocStateName.objects.get(slug="watching")
|
||||
draft.save()
|
||||
|
||||
self.assertEquals(len(list(get_expired_ids())), 1)
|
||||
|
||||
# test query
|
||||
documents = get_expired_ids()
|
||||
self.assertEquals(len(documents), 2)
|
||||
# test notice
|
||||
mailbox_before = len(mail_outbox)
|
||||
|
||||
for d in documents:
|
||||
# test notice
|
||||
mailbox_before = len(mail_outbox)
|
||||
send_expire_notice_for_id(draft)
|
||||
|
||||
send_expire_notice_for_id(d)
|
||||
self.assertEquals(len(mail_outbox), mailbox_before + 1)
|
||||
self.assertTrue("expired" in mail_outbox[-1]["Subject"])
|
||||
|
||||
self.assertEquals(InternetDraft.objects.get(filename=d.filename).dunn_sent_date, datetime.date.today())
|
||||
if d.idinternal:
|
||||
self.assertEquals(len(mail_outbox), mailbox_before + 1)
|
||||
self.assertTrue("expired" in mail_outbox[-1]["Subject"])
|
||||
# test expiry
|
||||
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
||||
self.write_id_file(txt, 5000)
|
||||
|
||||
# test expiry
|
||||
txt = "%s-%s.txt" % (d.filename, d.revision_display())
|
||||
self.write_id_file(txt, 5000)
|
||||
revision_before = draft.rev
|
||||
|
||||
revision_before = d.revision
|
||||
|
||||
expire_id(d)
|
||||
expire_id(draft)
|
||||
|
||||
draft = InternetDraft.objects.get(filename=d.filename)
|
||||
self.assertEquals(draft.status.status, "Expired")
|
||||
self.assertEquals(int(draft.revision), int(revision_before) + 1)
|
||||
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)))
|
||||
new_txt = "%s-%s.txt" % (draft.name, draft.revision)
|
||||
self.assertTrue(os.path.exists(os.path.join(self.id_dir, new_txt)))
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.state_id, "expired")
|
||||
self.assertEquals(int(draft.rev), int(revision_before) + 1)
|
||||
self.assertEquals(draft.iesg_state_id, "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)))
|
||||
new_txt = "%s-%s.txt" % (draft.name, draft.rev)
|
||||
self.assertTrue(os.path.exists(os.path.join(self.id_dir, new_txt)))
|
||||
|
||||
def test_clean_up_id_files(self):
|
||||
from ietf.idrfc.expire import clean_up_id_files
|
||||
draft = make_test_data()
|
||||
|
||||
from ietf.idrfc.expire import clean_up_id_files, INTERNET_DRAFT_DAYS_TO_EXPIRE
|
||||
|
||||
# put unknown file
|
||||
unknown = "draft-i-am-unknown-01.txt"
|
||||
|
@ -1061,7 +1071,7 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
|
||||
|
||||
# put file with malformed name (no revision)
|
||||
malformed = "draft-ietf-mipshop-pfmipv6.txt"
|
||||
malformed = draft.name + ".txt"
|
||||
self.write_id_file(malformed, 5000)
|
||||
|
||||
clean_up_id_files()
|
||||
|
@ -1071,13 +1081,12 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
|
||||
|
||||
# RFC draft
|
||||
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
draft.status_id = 3
|
||||
draft.state = DocStateName.objects.get(slug="rfc")
|
||||
draft.save()
|
||||
|
||||
txt = "%s-%s.txt" % (draft.name, draft.revision)
|
||||
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
||||
self.write_id_file(txt, 5000)
|
||||
pdf = "%s-%s.pdf" % (draft.name, draft.revision)
|
||||
pdf = "%s-%s.pdf" % (draft.name, draft.rev)
|
||||
self.write_id_file(pdf, 5000)
|
||||
|
||||
clean_up_id_files()
|
||||
|
@ -1089,13 +1098,20 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "unknown_ids", pdf)))
|
||||
|
||||
|
||||
# expired without tombstone
|
||||
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
draft.status_id = 2
|
||||
draft.expiration_date = datetime.date.today() - datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE + 1)
|
||||
# expire draft
|
||||
draft.state = DocStateName.objects.get(slug="expired")
|
||||
draft.save()
|
||||
|
||||
txt = "%s-%s.txt" % (draft.name, draft.revision)
|
||||
e = Event()
|
||||
e.doc = draft
|
||||
e.by = Email.objects.get(address="(System)")
|
||||
e.type = "expired_document"
|
||||
e.text = "Document has expired"
|
||||
e.time = datetime.date.today() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE + 1)
|
||||
e.save()
|
||||
|
||||
# expired without tombstone
|
||||
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
||||
self.write_id_file(txt, 5000)
|
||||
|
||||
clean_up_id_files()
|
||||
|
@ -1105,62 +1121,64 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
|
||||
|
||||
# expired with tombstone
|
||||
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
draft.status_id = 2
|
||||
draft.expiration_date = datetime.date.today() - datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE + 1)
|
||||
draft.expired_tombstone = False
|
||||
draft.save()
|
||||
revision_before = draft.rev
|
||||
|
||||
revision_before = draft.revision
|
||||
|
||||
txt = "%s-%s.txt" % (draft.name, draft.revision)
|
||||
self.write_id_file(txt, 1000)
|
||||
txt = "%s-%s.txt" % (draft.name, draft.rev)
|
||||
self.write_id_file(txt, 1000) # < 1500 means tombstone
|
||||
|
||||
clean_up_id_files()
|
||||
|
||||
self.assertTrue(not os.path.exists(os.path.join(self.id_dir, txt)))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "deleted_tombstones", txt)))
|
||||
|
||||
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
self.assertEquals(int(draft.revision), int(revision_before) - 1)
|
||||
self.assertTrue(draft.expired_tombstone)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(int(draft.rev), int(revision_before) - 1)
|
||||
self.assertTrue(draft.tags.filter(slug="exp-tomb"))
|
||||
|
||||
class ExpireLastCallTestCase(django.test.TestCase):
|
||||
fixtures = ['base', 'draft']
|
||||
fixtures = ['names']
|
||||
|
||||
def test_expire_last_call(self):
|
||||
from ietf.idrfc.lastcall import get_expired_last_calls, expire_last_call
|
||||
|
||||
# check that not expired drafts aren't expired
|
||||
# check that non-expirable drafts aren't expired
|
||||
|
||||
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
draft.idinternal.cur_state = IDState.objects.get(document_state_id=IDState.IN_LAST_CALL)
|
||||
draft.idinternal.cur_substate = None
|
||||
draft.idinternal.save()
|
||||
draft.lc_expiration_date = datetime.date.today() + datetime.timedelta(days=2)
|
||||
draft.save()
|
||||
|
||||
self.assertEquals(len(get_expired_last_calls()), 0)
|
||||
|
||||
draft.lc_expiration_date = None
|
||||
draft = make_test_data()
|
||||
draft.iesg_state_id = "lc"
|
||||
draft.save()
|
||||
|
||||
self.assertEquals(len(get_expired_last_calls()), 0)
|
||||
self.assertEquals(len(list(get_expired_last_calls())), 0)
|
||||
|
||||
e = LastCallEvent()
|
||||
e.doc = draft
|
||||
e.by = Email.objects.get(address="sec.retary@ietf.org")
|
||||
e.type = "sent_last_call"
|
||||
e.text = "Last call sent"
|
||||
e.expires = datetime.datetime.now() + datetime.timedelta(days=14)
|
||||
e.save()
|
||||
|
||||
self.assertEquals(len(list(get_expired_last_calls())), 0)
|
||||
|
||||
# test expired
|
||||
draft.lc_expiration_date = datetime.date.today()
|
||||
draft.save()
|
||||
e = LastCallEvent()
|
||||
e.doc = draft
|
||||
e.by = Email.objects.get(address="sec.retary@ietf.org")
|
||||
e.type = "sent_last_call"
|
||||
e.text = "Last call sent"
|
||||
e.expires = datetime.datetime.now()
|
||||
e.save()
|
||||
|
||||
drafts = get_expired_last_calls()
|
||||
drafts = list(get_expired_last_calls())
|
||||
self.assertEquals(len(drafts), 1)
|
||||
|
||||
# expire it
|
||||
mailbox_before = len(mail_outbox)
|
||||
events_before = draft.event_set.count()
|
||||
|
||||
expire_last_call(drafts[0])
|
||||
|
||||
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
self.assertEquals(draft.idinternal.cur_state.document_state_id, IDState.WAITING_FOR_WRITEUP)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.iesg_state.slug, "writeupw")
|
||||
self.assertEquals(draft.event_set.count(), events_before + 1)
|
||||
self.assertEquals(len(mail_outbox), mailbox_before + 1)
|
||||
self.assertTrue("Last Call Expired" in mail_outbox[-1]["Subject"])
|
||||
|
|
|
@ -196,7 +196,7 @@ LIAISON_ATTACH_PATH = '/a/www/ietf-datatracker/documents/LIAISON/'
|
|||
LIAISON_ATTACH_URL = '/documents/LIAISON/'
|
||||
|
||||
# DB redesign
|
||||
USE_DB_REDESIGN_PROXY_CLASSES=True
|
||||
USE_DB_REDESIGN_PROXY_CLASSES = True
|
||||
|
||||
# Put SECRET_KEY in here, or any other sensitive or site-specific
|
||||
# changes. DO NOT commit settings_local.py to svn.
|
||||
|
|
7
ietf/templates/idrfc/expire_textREDESIGN.txt
Normal file
7
ietf/templates/idrfc/expire_textREDESIGN.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% filter wordwrap:73 %}This Internet-Draft, {{ doc.name }}-{{ doc.rev }}.txt, has expired, and has been deleted from the Internet-Drafts directory. An Internet-Draft expires {{ expire_days }} days from the date that it is posted unless it is replaced by an updated version, or the Secretariat has been notified that the document is under official review by the IESG or has been passed to the RFC Editor for review and/or publication as an RFC. This Internet-Draft was not published as an RFC.
|
||||
|
||||
Internet-Drafts are not archival documents, and copies of Internet-Drafts that have been deleted from the directory are not available. The Secretariat does not have any information regarding the future plans of the author{{ authors|pluralize}} or working group, if applicable, with respect to this deleted Internet-Draft. For more information, or to request a copy of the document, please contact the author{{ authors|pluralize}} directly.{% endfilter %}
|
||||
|
||||
Draft Author{{ authors|pluralize}}:
|
||||
{% for name, email in authors %}{{ name }}<{{ email }}>
|
||||
{% endfor %}
|
|
@ -1,5 +1,5 @@
|
|||
{{ doc.file_tag|safe }} was just expired.
|
||||
This draft is in the state {{ doc.idstate }} in ID Tracker.
|
||||
This draft is in the state "{{ state }}" in the ID Tracker.
|
||||
|
||||
|
||||
Thanks,
|
||||
|
|
|
@ -201,7 +201,6 @@ EVENT_TYPES = [
|
|||
|
||||
# misc document events
|
||||
("added_comment", "Added comment"),
|
||||
("added_tombstone", "Added tombstone"),
|
||||
("expired_document", "Expired document"),
|
||||
("requested_resurrect", "Requested resurrect"),
|
||||
("completed_resurrect", "Completed resurrect"),
|
||||
|
|
|
@ -76,7 +76,8 @@ class InternetDraft(Document):
|
|||
#expiration_date = models.DateField()
|
||||
@property
|
||||
def expiration_date(self):
|
||||
return self.expiration()
|
||||
e = self.latest_event(type__in=('expired_document', 'new_revision', "completed_resurrect"))
|
||||
return e.time.date() if e and e.type == "expired_document" else None
|
||||
#abstract = models.TextField() # same name
|
||||
#dunn_sent_date = models.DateField(null=True, blank=True) # unused
|
||||
#extension_date = models.DateField(null=True, blank=True) # unused
|
||||
|
|
Loading…
Reference in a new issue