diff --git a/ietf/idrfc/expire.py b/ietf/idrfc/expire.py index 54b811293..21fe8bf9f 100644 --- a/ietf/idrfc/expire.py +++ b/ietf/idrfc/expire.py @@ -14,8 +14,6 @@ from redesign.name.models import DocTagName from redesign.person.models import Person, Email from ietf.meeting.models import Meeting -INTERNET_DRAFT_DAYS_TO_EXPIRE = 185 - def in_id_expire_freeze(when=None): if when == None: when = datetime.datetime.now() @@ -35,13 +33,6 @@ def in_id_expire_freeze(when=None): return second_cut_off <= when < ietf_monday -def document_expires(doc): - e = doc.latest_event(type__in=("completed_resurrect", "new_revision")) - if e: - return e.time + datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE) - else: - return None - def expirable_documents(): d = Document.objects.filter(states__type="draft", states__slug="active").exclude(tags="rfc-rev") # we need to get those that either don't have a state or have a @@ -62,8 +53,7 @@ def get_soon_to_expire_idsREDESIGN(days): end_date = start_date + datetime.timedelta(days - 1) for d in expirable_documents(): - t = document_expires(d) - if t and start_date <= t.date() <= end_date: + if d.expires and start_date <= d.expires.date() <= end_date: yield d def get_expired_ids(): @@ -79,8 +69,7 @@ def get_expired_idsREDESIGN(): today = datetime.date.today() for d in expirable_documents(): - t = document_expires(d) - if t and t.date() <= today: + if d.expires and d.expires.date() <= today: yield d def send_expire_warning_for_id(doc): @@ -108,7 +97,7 @@ def send_expire_warning_for_id(doc): cc_addrs) def send_expire_warning_for_idREDESIGN(doc): - expiration = document_expires(doc).date() + expiration = doc.expires.date() to = [e.formatted_email() for e in doc.authors.all() if not e.address.startswith("unknown-email")] cc = None @@ -225,7 +214,7 @@ def expire_idREDESIGN(doc): new_file.write(txt) new_file.close() - # now change the states + # now change the state save_document_in_history(doc) if doc.latest_event(type='started_iesg_process'): @@ -243,7 +232,7 @@ def expire_idREDESIGN(doc): 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.set_state(State.objects.get(type="draft", slug="expired")) doc.time = datetime.datetime.now() @@ -311,7 +300,7 @@ def clean_up_id_files(): 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) + cut_off = datetime.date.today() - datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) pattern = os.path.join(settings.IDSUBMIT_REPOSITORY_PATH, "draft-*.*") files = [] @@ -355,10 +344,7 @@ def clean_up_id_filesREDESIGN(): if ext != ".txt": move_file_to("unknown_ids") elif doc.get_state_slug() in ("expired", "repl", "auth-rm", "ietf-rm"): - e = doc.latest_event(type__in=('expired_document', 'new_revision', "completed_resurrect")) - expiration_date = e.time.date() if e and e.type == "expired_document" else None - - if expiration_date and expiration_date < cut_off: + if doc.expires and doc.expires.date() < cut_off: # Expired, Withdrawn by Author, Replaced, Withdrawn by IETF, # and expired more than DAYS_TO_EXPIRE ago if os.path.getsize(path) < 1500: diff --git a/ietf/idrfc/testsREDESIGN.py b/ietf/idrfc/testsREDESIGN.py index 2b311eadd..0378342a6 100644 --- a/ietf/idrfc/testsREDESIGN.py +++ b/ietf/idrfc/testsREDESIGN.py @@ -349,7 +349,7 @@ class ResurrectTestCase(django.test.TestCase): q = PyQuery(r.content) self.assertEquals(len(q('form input[type=submit]')), 1) - # request resurrect + # complete resurrect events_before = draft.docevent_set.count() mailbox_before = len(outbox) @@ -360,6 +360,7 @@ class ResurrectTestCase(django.test.TestCase): self.assertEquals(draft.docevent_set.count(), events_before + 1) self.assertEquals(draft.latest_event().type, "completed_resurrect") self.assertEquals(draft.get_state_slug(), "active") + self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) self.assertEquals(len(outbox), mailbox_before + 1) class AddCommentTestCase(django.test.TestCase): @@ -858,7 +859,7 @@ class ExpireIDsTestCase(django.test.TestCase): self.assertTrue(not in_id_expire_freeze(datetime.datetime.combine(ietf_monday, time(0, 0, 0)))) def test_warn_expirable_ids(self): - from ietf.idrfc.expire import get_soon_to_expire_ids, send_expire_warning_for_id, INTERNET_DRAFT_DAYS_TO_EXPIRE + from ietf.idrfc.expire import get_soon_to_expire_ids, send_expire_warning_for_id draft = make_test_data() @@ -867,15 +868,6 @@ class ExpireIDsTestCase(django.test.TestCase): # hack into expirable state draft.unset_state("draft-iesg") - NewRevisionDocEvent.objects.create( - type="new_revision", - by=Person.objects.get(name="Aread Irector"), - doc=draft, - desc="New revision", - time=datetime.datetime.now() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE - 7), - rev="01" - ) - self.assertEquals(len(list(get_soon_to_expire_ids(14))), 1) # test send warning @@ -888,7 +880,7 @@ class ExpireIDsTestCase(django.test.TestCase): self.assertTrue("wgchairman@ietf.org" in str(outbox[-1])) def test_expire_ids(self): - from ietf.idrfc.expire import get_expired_ids, send_expire_notice_for_id, expire_id, INTERNET_DRAFT_DAYS_TO_EXPIRE + from ietf.idrfc.expire import get_expired_ids, send_expire_notice_for_id, expire_id draft = make_test_data() @@ -896,15 +888,8 @@ class ExpireIDsTestCase(django.test.TestCase): # hack into expirable state draft.unset_state("draft-iesg") - - NewRevisionDocEvent.objects.create( - type="new_revision", - by=Person.objects.get(name="Aread Irector"), - doc=draft, - desc="New revision", - time=datetime.datetime.now() - datetime.timedelta(days=INTERNET_DRAFT_DAYS_TO_EXPIRE + 1), - rev="01" - ) + draft.expires = datetime.datetime.now() + draft.save() self.assertEquals(len(list(get_expired_ids())), 1) @@ -912,6 +897,10 @@ class ExpireIDsTestCase(django.test.TestCase): self.assertEquals(len(list(get_expired_ids())), 1) + draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) + + self.assertEquals(len(list(get_expired_ids())), 0) + # test notice mailbox_before = len(outbox) @@ -941,7 +930,7 @@ class ExpireIDsTestCase(django.test.TestCase): def test_clean_up_id_files(self): draft = make_test_data() - from ietf.idrfc.expire import clean_up_id_files, INTERNET_DRAFT_DAYS_TO_EXPIRE + from ietf.idrfc.expire import clean_up_id_files # put unknown file unknown = "draft-i-am-unknown-01.txt" @@ -983,6 +972,7 @@ class ExpireIDsTestCase(django.test.TestCase): # expire draft draft.set_state(State.objects.get(type="draft", slug="expired")) + draft.expires = datetime.datetime.now() draft.save() e = DocEvent() @@ -990,7 +980,7 @@ class ExpireIDsTestCase(django.test.TestCase): e.by = Person.objects.get(name="(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.time = draft.expires e.save() # expired without tombstone diff --git a/ietf/idrfc/views_edit.py b/ietf/idrfc/views_edit.py index ac581841e..10ee199e3 100644 --- a/ietf/idrfc/views_edit.py +++ b/ietf/idrfc/views_edit.py @@ -727,6 +727,7 @@ def resurrectREDESIGN(request, name): e.save() doc.set_state(State.objects.get(type="draft", slug="active")) + doc.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) doc.time = datetime.datetime.now() doc.save() return HttpResponseRedirect(doc.get_absolute_url()) diff --git a/ietf/settings.py b/ietf/settings.py index e0c04dec3..7debaa9cb 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -236,6 +236,8 @@ SUBMISSION_START_DAYS = -90 SUBMISSION_CUTOFF_DAYS = 33 SUBMISSION_CORRECTION_DAYS = 59 +INTERNET_DRAFT_DAYS_TO_EXPIRE = 185 + IDSUBMIT_REPOSITORY_PATH = INTERNET_DRAFT_PATH IDSUBMIT_STAGING_PATH = '/a/www/www6s/staging/' IDSUBMIT_STAGING_URL = 'http://www.ietf.org/staging/' diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 31d00c6c7..6fc3ac009 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -136,6 +136,7 @@ class SubmitTestCase(django.test.TestCase): self.assertTrue(os.path.exists(os.path.join(self.repository_dir, u"%s-%s.txt" % (name, rev)))) self.assertEquals(draft.type_id, "draft") self.assertEquals(draft.stream_id, "ietf") + self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) self.assertEquals(draft.get_state("draft-stream-%s" % draft.stream_id).slug, "wg-doc") self.assertEquals(draft.authors.count(), 1) self.assertEquals(draft.authors.all()[0].get_name(), "Test Name") diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py index 048049733..f3a1c773e 100644 --- a/ietf/submit/utils.py +++ b/ietf/submit/utils.py @@ -120,6 +120,7 @@ def perform_postREDESIGN(request, submission): stream_slug = "ietf" draft.stream = StreamName.objects.get(slug=stream_slug) + draft.expires = datetime.datetime.now() + datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) draft.save() draft.set_state(State.objects.get(type="draft", slug="active")) diff --git a/ietf/utils/test_data.py b/ietf/utils/test_data.py index 2e1f78d41..ecd78c334 100644 --- a/ietf/utils/test_data.py +++ b/ietf/utils/test_data.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.contrib.auth.models import User from ietf.iesg.models import TelechatDate, WGAction @@ -51,7 +52,7 @@ def make_test_data(): type_id="individ", parent=None) # mars WG - group = Group.objects.create( + mars_wg = group = Group.objects.create( name="Martian Special Interest Group", acronym="mars", state_id="active", @@ -190,7 +191,7 @@ def make_test_data(): person=p) Role.objects.create( name_id="chair", - group=group, + group=mars_wg, person=p, email=wgchair, ) @@ -207,7 +208,7 @@ def make_test_data(): person=p) Role.objects.create( name_id="delegate", - group=group, + group=mars_wg, person=p, email=email, ) @@ -235,13 +236,14 @@ def make_test_data(): type_id="draft", title="Optimizing Martian Network Topologies", stream_id="ietf", - group=group, + group=mars_wg, abstract="Techniques for achieving near-optimal Martian networks.", rev="01", pages=2, intended_std_level_id="ps", shepherd=plainman, ad=ad, + expires=datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), notify="aliens@example.mars", note="", ) diff --git a/redesign/doc/models.py b/redesign/doc/models.py index b17d02c43..9f299b530 100644 --- a/redesign/doc/models.py +++ b/redesign/doc/models.py @@ -54,6 +54,7 @@ class DocumentInfo(models.Model): std_level = models.ForeignKey(StdLevelName, blank=True, null=True) ad = models.ForeignKey(Person, verbose_name="area director", related_name='ad_%(class)s_set', blank=True, null=True) shepherd = models.ForeignKey(Person, related_name='shepherd_%(class)s_set', blank=True, null=True) + expires = models.DateTimeField(blank=True, null=True) notify = models.CharField(max_length=255, blank=True) external_url = models.URLField(blank=True) # Should be set for documents with type 'External'. note = models.TextField(blank=True) diff --git a/redesign/doc/proxy.py b/redesign/doc/proxy.py index 64dda48ed..84641b195 100644 --- a/redesign/doc/proxy.py +++ b/redesign/doc/proxy.py @@ -243,8 +243,7 @@ class InternetDraft(Document): r = max(r - 1, 0) return "%02d" % r def expiration(self): - e = self.latest_event(type__in=("completed_resurrect", "new_revision")) - return e.time.date() + datetime.timedelta(days=self.DAYS_TO_EXPIRE) + return self.expires.date() def can_expire(self): # Copying the logic from expire-ids-1 without thinking # much about it. diff --git a/redesign/importing/import-docs.py b/redesign/importing/import-docs.py index 0e1051dd3..71cac5902 100755 --- a/redesign/importing/import-docs.py +++ b/redesign/importing/import-docs.py @@ -982,6 +982,13 @@ for index, o in enumerate(all_drafts.iterator()): # import other attributes + # when to expire + e = d.latest_event(type__in=("completed_resurrect", "new_revision")) + if e: + d.expires = e.time + datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE) + else: + d.expires = None + # tags sync_tag(d, o.review_by_rfc_editor, tag_review_by_rfc_editor) sync_tag(d, o.expired_tombstone, tag_expired_tombstone)