Skip to content

Commit f3685e7

Browse files
committed
Turn expiration into an explicit expires attribute on document, set
that on submission of new revision and resurrection - Legacy-Id: 3801
1 parent 31aef86 commit f3685e7

10 files changed

Lines changed: 40 additions & 50 deletions

File tree

ietf/idrfc/expire.py

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
from redesign.person.models import Person, Email
1515
from ietf.meeting.models import Meeting
1616

17-
INTERNET_DRAFT_DAYS_TO_EXPIRE = 185
18-
1917
def in_id_expire_freeze(when=None):
2018
if when == None:
2119
when = datetime.datetime.now()
@@ -35,13 +33,6 @@ def in_id_expire_freeze(when=None):
3533

3634
return second_cut_off <= when < ietf_monday
3735

38-
def document_expires(doc):
39-
e = doc.latest_event(type__in=("completed_resurrect", "new_revision"))
40-
if e:
41-
return e.time + datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE)
42-
else:
43-
return None
44-
4536
def expirable_documents():
4637
d = Document.objects.filter(states__type="draft", states__slug="active").exclude(tags="rfc-rev")
4738
# we need to get those that either don't have a state or have a
@@ -62,8 +53,7 @@ def get_soon_to_expire_idsREDESIGN(days):
6253
end_date = start_date + datetime.timedelta(days - 1)
6354

6455
for d in expirable_documents():
65-
t = document_expires(d)
66-
if t and start_date <= t.date() <= end_date:
56+
if d.expires and start_date <= d.expires.date() <= end_date:
6757
yield d
6858

6959
def get_expired_ids():
@@ -79,8 +69,7 @@ def get_expired_idsREDESIGN():
7969
today = datetime.date.today()
8070

8171
for d in expirable_documents():
82-
t = document_expires(d)
83-
if t and t.date() <= today:
72+
if d.expires and d.expires.date() <= today:
8473
yield d
8574

8675
def send_expire_warning_for_id(doc):
@@ -108,7 +97,7 @@ def send_expire_warning_for_id(doc):
10897
cc_addrs)
10998

11099
def send_expire_warning_for_idREDESIGN(doc):
111-
expiration = document_expires(doc).date()
100+
expiration = doc.expires.date()
112101

113102
to = [e.formatted_email() for e in doc.authors.all() if not e.address.startswith("unknown-email")]
114103
cc = None
@@ -225,7 +214,7 @@ def move_file(f):
225214
new_file.write(txt)
226215
new_file.close()
227216

228-
# now change the states
217+
# now change the state
229218

230219
save_document_in_history(doc)
231220
if doc.latest_event(type='started_iesg_process'):
@@ -243,7 +232,7 @@ def move_file(f):
243232
e.type = "expired_document"
244233
e.desc = "Document has expired"
245234
e.save()
246-
235+
247236
doc.rev = new_revision # FIXME: incrementing the revision like this is messed up
248237
doc.set_state(State.objects.get(type="draft", slug="expired"))
249238
doc.time = datetime.datetime.now()
@@ -311,7 +300,7 @@ def move_file_to(subdir):
311300

312301
def clean_up_id_filesREDESIGN():
313302
"""Move unidentified and old files out of the Internet Draft directory."""
314-
cut_off = datetime.date.today() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE)
303+
cut_off = datetime.date.today() - datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
315304

316305
pattern = os.path.join(settings.IDSUBMIT_REPOSITORY_PATH, "draft-*.*")
317306
files = []
@@ -355,10 +344,7 @@ def move_file_to(subdir):
355344
if ext != ".txt":
356345
move_file_to("unknown_ids")
357346
elif doc.get_state_slug() in ("expired", "repl", "auth-rm", "ietf-rm"):
358-
e = doc.latest_event(type__in=('expired_document', 'new_revision', "completed_resurrect"))
359-
expiration_date = e.time.date() if e and e.type == "expired_document" else None
360-
361-
if expiration_date and expiration_date < cut_off:
347+
if doc.expires and doc.expires.date() < cut_off:
362348
# Expired, Withdrawn by Author, Replaced, Withdrawn by IETF,
363349
# and expired more than DAYS_TO_EXPIRE ago
364350
if os.path.getsize(path) < 1500:

ietf/idrfc/testsREDESIGN.py

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ def test_resurrect(self):
349349
q = PyQuery(r.content)
350350
self.assertEquals(len(q('form input[type=submit]')), 1)
351351

352-
# request resurrect
352+
# complete resurrect
353353
events_before = draft.docevent_set.count()
354354
mailbox_before = len(outbox)
355355

@@ -360,6 +360,7 @@ def test_resurrect(self):
360360
self.assertEquals(draft.docevent_set.count(), events_before + 1)
361361
self.assertEquals(draft.latest_event().type, "completed_resurrect")
362362
self.assertEquals(draft.get_state_slug(), "active")
363+
self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1))
363364
self.assertEquals(len(outbox), mailbox_before + 1)
364365

365366
class AddCommentTestCase(django.test.TestCase):
@@ -858,7 +859,7 @@ def test_in_id_expire_freeze(self):
858859
self.assertTrue(not in_id_expire_freeze(datetime.datetime.combine(ietf_monday, time(0, 0, 0))))
859860

860861
def test_warn_expirable_ids(self):
861-
from ietf.idrfc.expire import get_soon_to_expire_ids, send_expire_warning_for_id, INTERNET_DRAFT_DAYS_TO_EXPIRE
862+
from ietf.idrfc.expire import get_soon_to_expire_ids, send_expire_warning_for_id
862863

863864
draft = make_test_data()
864865

@@ -867,15 +868,6 @@ def test_warn_expirable_ids(self):
867868
# hack into expirable state
868869
draft.unset_state("draft-iesg")
869870

870-
NewRevisionDocEvent.objects.create(
871-
type="new_revision",
872-
by=Person.objects.get(name="Aread Irector"),
873-
doc=draft,
874-
desc="New revision",
875-
time=datetime.datetime.now() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE - 7),
876-
rev="01"
877-
)
878-
879871
self.assertEquals(len(list(get_soon_to_expire_ids(14))), 1)
880872

881873
# test send warning
@@ -888,30 +880,27 @@ def test_warn_expirable_ids(self):
888880
self.assertTrue("wgchairman@ietf.org" in str(outbox[-1]))
889881

890882
def test_expire_ids(self):
891-
from ietf.idrfc.expire import get_expired_ids, send_expire_notice_for_id, expire_id, INTERNET_DRAFT_DAYS_TO_EXPIRE
883+
from ietf.idrfc.expire import get_expired_ids, send_expire_notice_for_id, expire_id
892884

893885
draft = make_test_data()
894886

895887
self.assertEquals(len(list(get_expired_ids())), 0)
896888

897889
# hack into expirable state
898890
draft.unset_state("draft-iesg")
899-
900-
NewRevisionDocEvent.objects.create(
901-
type="new_revision",
902-
by=Person.objects.get(name="Aread Irector"),
903-
doc=draft,
904-
desc="New revision",
905-
time=datetime.datetime.now() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE + 1),
906-
rev="01"
907-
)
891+
draft.expires = datetime.datetime.now()
892+
draft.save()
908893

909894
self.assertEquals(len(list(get_expired_ids())), 1)
910895

911896
draft.set_state(State.objects.get(type="draft-iesg", slug="watching"))
912897

913898
self.assertEquals(len(list(get_expired_ids())), 1)
914899

900+
draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva"))
901+
902+
self.assertEquals(len(list(get_expired_ids())), 0)
903+
915904
# test notice
916905
mailbox_before = len(outbox)
917906

@@ -941,7 +930,7 @@ def test_expire_ids(self):
941930
def test_clean_up_id_files(self):
942931
draft = make_test_data()
943932

944-
from ietf.idrfc.expire import clean_up_id_files, INTERNET_DRAFT_DAYS_TO_EXPIRE
933+
from ietf.idrfc.expire import clean_up_id_files
945934

946935
# put unknown file
947936
unknown = "draft-i-am-unknown-01.txt"
@@ -983,14 +972,15 @@ def test_clean_up_id_files(self):
983972

984973
# expire draft
985974
draft.set_state(State.objects.get(type="draft", slug="expired"))
975+
draft.expires = datetime.datetime.now()
986976
draft.save()
987977

988978
e = DocEvent()
989979
e.doc = draft
990980
e.by = Person.objects.get(name="(System)")
991981
e.type = "expired_document"
992982
e.text = "Document has expired"
993-
e.time = datetime.date.today() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE + 1)
983+
e.time = draft.expires
994984
e.save()
995985

996986
# expired without tombstone

ietf/idrfc/views_edit.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ def resurrectREDESIGN(request, name):
727727
e.save()
728728

729729
doc.set_state(State.objects.get(type="draft", slug="active"))
730+
doc.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
730731
doc.time = datetime.datetime.now()
731732
doc.save()
732733
return HttpResponseRedirect(doc.get_absolute_url())

ietf/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@
236236
SUBMISSION_CUTOFF_DAYS = 33
237237
SUBMISSION_CORRECTION_DAYS = 59
238238

239+
INTERNET_DRAFT_DAYS_TO_EXPIRE = 185
240+
239241
IDSUBMIT_REPOSITORY_PATH = INTERNET_DRAFT_PATH
240242
IDSUBMIT_STAGING_PATH = '/a/www/www6s/staging/'
241243
IDSUBMIT_STAGING_URL = 'http://www.ietf.org/staging/'

ietf/submit/tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def test_submit_new(self):
136136
self.assertTrue(os.path.exists(os.path.join(self.repository_dir, u"%s-%s.txt" % (name, rev))))
137137
self.assertEquals(draft.type_id, "draft")
138138
self.assertEquals(draft.stream_id, "ietf")
139+
self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1))
139140
self.assertEquals(draft.get_state("draft-stream-%s" % draft.stream_id).slug, "wg-doc")
140141
self.assertEquals(draft.authors.count(), 1)
141142
self.assertEquals(draft.authors.all()[0].get_name(), "Test Name")

ietf/submit/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ def perform_postREDESIGN(request, submission):
120120
stream_slug = "ietf"
121121

122122
draft.stream = StreamName.objects.get(slug=stream_slug)
123+
draft.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)
123124
draft.save()
124125

125126
draft.set_state(State.objects.get(type="draft", slug="active"))

ietf/utils/test_data.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.conf import settings
12
from django.contrib.auth.models import User
23

34
from ietf.iesg.models import TelechatDate, WGAction
@@ -51,7 +52,7 @@ def make_test_data():
5152
type_id="individ",
5253
parent=None)
5354
# mars WG
54-
group = Group.objects.create(
55+
mars_wg = group = Group.objects.create(
5556
name="Martian Special Interest Group",
5657
acronym="mars",
5758
state_id="active",
@@ -190,7 +191,7 @@ def make_test_data():
190191
person=p)
191192
Role.objects.create(
192193
name_id="chair",
193-
group=group,
194+
group=mars_wg,
194195
person=p,
195196
email=wgchair,
196197
)
@@ -207,7 +208,7 @@ def make_test_data():
207208
person=p)
208209
Role.objects.create(
209210
name_id="delegate",
210-
group=group,
211+
group=mars_wg,
211212
person=p,
212213
email=email,
213214
)
@@ -235,13 +236,14 @@ def make_test_data():
235236
type_id="draft",
236237
title="Optimizing Martian Network Topologies",
237238
stream_id="ietf",
238-
group=group,
239+
group=mars_wg,
239240
abstract="Techniques for achieving near-optimal Martian networks.",
240241
rev="01",
241242
pages=2,
242243
intended_std_level_id="ps",
243244
shepherd=plainman,
244245
ad=ad,
246+
expires=datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE),
245247
notify="aliens@example.mars",
246248
note="",
247249
)

redesign/doc/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class DocumentInfo(models.Model):
5454
std_level = models.ForeignKey(StdLevelName, blank=True, null=True)
5555
ad = models.ForeignKey(Person, verbose_name="area director", related_name='ad_%(class)s_set', blank=True, null=True)
5656
shepherd = models.ForeignKey(Person, related_name='shepherd_%(class)s_set', blank=True, null=True)
57+
expires = models.DateTimeField(blank=True, null=True)
5758
notify = models.CharField(max_length=255, blank=True)
5859
external_url = models.URLField(blank=True) # Should be set for documents with type 'External'.
5960
note = models.TextField(blank=True)

redesign/doc/proxy.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,7 @@ def revision_display(self):
243243
r = max(r - 1, 0)
244244
return "%02d" % r
245245
def expiration(self):
246-
e = self.latest_event(type__in=("completed_resurrect", "new_revision"))
247-
return e.time.date() + datetime.timedelta(days=self.DAYS_TO_EXPIRE)
246+
return self.expires.date()
248247
def can_expire(self):
249248
# Copying the logic from expire-ids-1 without thinking
250249
# much about it.

redesign/importing/import-docs.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,13 @@ def import_from_idinternal(d, idinternal):
982982

983983
# import other attributes
984984

985+
# when to expire
986+
e = d.latest_event(type__in=("completed_resurrect", "new_revision"))
987+
if e:
988+
d.expires = e.time + datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE)
989+
else:
990+
d.expires = None
991+
985992
# tags
986993
sync_tag(d, o.review_by_rfc_editor, tag_review_by_rfc_editor)
987994
sync_tag(d, o.expired_tombstone, tag_expired_tombstone)

0 commit comments

Comments
 (0)