From d70fb9b4b1af625648a57c2d42b8826deddd04c0 Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Thu, 4 Apr 2013 13:22:08 +0000 Subject: [PATCH 01/18] Delete dead code, rename id-something to draft-something, make the "is this eligible for expiration" logic clearer - Legacy-Id: 5606 --- ietf/bin/expire-ids | 13 +- ietf/bin/notify-expirations | 8 +- ietf/idrfc/expire.py | 247 +++++++----------------------------- ietf/idrfc/tests.py | 70 +++++----- 4 files changed, 89 insertions(+), 249 deletions(-) diff --git a/ietf/bin/expire-ids b/ietf/bin/expire-ids index c95b46365..8f9486ce7 100755 --- a/ietf/bin/expire-ids +++ b/ietf/bin/expire-ids @@ -11,10 +11,11 @@ syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_LOCAL0) from ietf.idrfc.expire import * -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.pk, " in the ID Tracker" if doc.latest_event(type="started_iesg_process") else "")) +if not in_draft_expire_freeze(): + for doc in get_expired_drafts(): + send_expire_notice_for_draft(doc) + expire_draft(doc) + syslog.syslog("Expired draft %s-%s" % (doc.name, doc.rev)) -clean_up_id_files() +syslog.syslog("Cleaning up draft files") +clean_up_draft_files() diff --git a/ietf/bin/notify-expirations b/ietf/bin/notify-expirations index 030d0611c..71de766f6 100755 --- a/ietf/bin/notify-expirations +++ b/ietf/bin/notify-expirations @@ -6,11 +6,11 @@ from ietf import settings from django.core import management management.setup_environ(settings) -from ietf.idrfc.expire import get_soon_to_expire_ids, send_expire_warning_for_id +from ietf.idrfc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft # notify about documents that expire within the next 2 weeks -notify_days = 14 +notify_days = 14 -for doc in get_soon_to_expire_ids(notify_days): - send_expire_warning_for_id(doc) +for doc in get_soon_to_expire_drafts(notify_days): + send_expire_warning_for_draft(doc) diff --git a/ietf/idrfc/expire.py b/ietf/idrfc/expire.py index 1faf135c9..e729837d4 100644 --- a/ietf/idrfc/expire.py +++ b/ietf/idrfc/expire.py @@ -6,105 +6,64 @@ from django.db.models import Q import datetime, os, shutil, glob, re, itertools -from ietf.idtracker.models import InternetDraft, IDDates, IDStatus, IDState, DocumentComment, IDAuthor, WGChair from ietf.utils.mail import send_mail, send_mail_subj -from ietf.idrfc.utils import log_state_changed, add_document_comment -from ietf.doc.models import Document, DocEvent, save_document_in_history, State -from ietf.name.models import DocTagName +from ietf.idrfc.utils import log_state_changed +from ietf.doc.models import Document, DocEvent, State, save_document_in_history, IESG_SUBSTATE_TAGS from ietf.person.models import Person, Email from ietf.meeting.models import Meeting -def in_id_expire_freeze(when=None): - if when == None: - when = datetime.datetime.now() +def expirable_draft(draft): + """Return whether draft is in an expirable state or not. This is + the single draft version of the logic in expirable_drafts. These + two functions need to be kept in sync.""" + return (draft.expires and draft.get_state_slug() == "active" + and draft.get_state_slug("draft-iesg") in (None, "watching", "dead") + and draft.get_state_slug("draft-stream-%s" % draft.stream_id) not in ("rfc-edit", "pub") + and not draft.tags.filter(slug="rfc-rev")) - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - d = Meeting.get_second_cut_off() - else: - d = IDDates.objects.get(id=IDDates.SECOND_CUT_OFF).date - # for some reason, the old Perl code started at 9 am - second_cut_off = datetime.datetime.combine(d, datetime.time(9, 0)) - - if settings.USE_DB_REDESIGN_PROXY_CLASSES: - d = Meeting.get_ietf_monday() - else: - d = IDDates.objects.get(id=IDDates.IETF_MONDAY).date - ietf_monday = datetime.datetime.combine(d, datetime.time(0, 0)) - - return second_cut_off <= when < ietf_monday - -def expirable_documents(): +def expirable_drafts(): + """Return a queryset with expirable drafts.""" # the general rule is that each active draft is expirable, unless # it's in a state where we shouldn't touch it - - d = Document.objects.filter(states__type="draft", states__slug="active").exclude(tags="rfc-rev") + d = Document.objects.filter(states__type="draft", states__slug="active").exclude(expires=None) nonexpirable_states = [] # all IESG states except AD Watching and Dead block expiry nonexpirable_states += list(State.objects.filter(type="draft-iesg").exclude(slug__in=("watching", "dead"))) - # Sent to RFC Editor and RFC Published block expiry (the latter + # sent to RFC Editor and RFC Published block expiry (the latter # shouldn't be possible for an active draft, though) nonexpirable_states += list(State.objects.filter(type__in=("draft-stream-iab", "draft-stream-irtf", "draft-stream-ise"), slug__in=("rfc-edit", "pub"))) - return d.exclude(states__in=nonexpirable_states).distinct() + d = d.exclude(states__in=nonexpirable_states) -def get_soon_to_expire_ids(days): - start_date = datetime.date.today() - datetime.timedelta(InternetDraft.DAYS_TO_EXPIRE - 1) - end_date = start_date + datetime.timedelta(days - 1) - - for d in InternetDraft.objects.filter(revision_date__gte=start_date,revision_date__lte=end_date,status__status='Active'): - if d.can_expire(): - yield d + # under review by the RFC Editor blocks expiry + d = d.exclude(tags="rfc-rev") -def get_soon_to_expire_idsREDESIGN(days): + return d.distinct() + +def get_soon_to_expire_drafts(days_of_warning): start_date = datetime.date.today() - datetime.timedelta(1) - end_date = start_date + datetime.timedelta(days - 1) + end_date = start_date + datetime.timedelta(days_of_warning) + + return expirable_drafts().filter(expires__gte=start_date, expires__lt=end_date) + +def get_expired_drafts(): + return expirable_drafts().filter(expires__lt=datetime.date.today() + datetime.timedelta(1)) + +def in_draft_expire_freeze(when=None): + if when == None: + when = datetime.datetime.now() + + d = Meeting.get_second_cut_off() + # for some reason, the old Perl code started at 9 am + second_cut_off = datetime.datetime.combine(d, datetime.time(9, 0)) - for d in expirable_documents(): - if d.expires and start_date <= d.expires.date() <= end_date: - yield d - -def get_expired_ids(): - cut_off = datetime.date.today() - datetime.timedelta(days=InternetDraft.DAYS_TO_EXPIRE) - - return InternetDraft.objects.filter( - revision_date__lte=cut_off, - status__status="Active", - review_by_rfc_editor=0).filter( - Q(idinternal=None) | Q(idinternal__cur_state__document_state_id__gte=42)) - -def get_expired_idsREDESIGN(): - today = datetime.date.today() - - for d in expirable_documents(): - if d.expires and d.expires.date() <= today: - yield d - -def send_expire_warning_for_id(doc): - expiration = doc.expiration() - # Todo: - #second_cutoff = IDDates.objects.get(date_id=2) - #ietf_monday = IDDates.objects.get(date_id=3) - #freeze_delta = ietf_monday - second_cutoff - # # The I-D expiration job doesn't run while submissions are frozen. - # if ietf_monday > expiration > second_cutoff: - # expiration += freeze_delta + d = Meeting.get_ietf_monday() + ietf_monday = datetime.datetime.combine(d, datetime.time(0, 0)) - authors = doc.authors.all() - to_addrs = [author.email() for author in authors if author.email()] - cc_addrs = None - if doc.group.acronym != 'none': - cc_addrs = [chair.person.email() for chair in WGChair.objects.filter(group_acronym=doc.group)] + return second_cut_off <= when < ietf_monday - if to_addrs or cc_addrs: - send_mail_subj(None, to_addrs, None, 'notify_expirations/subject.txt', 'notify_expirations/body.txt', - { - 'draft':doc, - 'expiration':expiration, - }, - cc_addrs) - -def send_expire_warning_for_idREDESIGN(doc): +def send_expire_warning_for_draft(doc): if doc.get_state_slug("draft-iesg") == "dead": return # don't warn about dead documents @@ -130,23 +89,7 @@ def send_expire_warning_for_idREDESIGN(doc): ), cc=cc) -def send_expire_notice_for_id(doc): - doc.dunn_sent_date = datetime.date.today() - doc.save() - - if not doc.idinternal: - return - - request = None - to = u"%s <%s>" % doc.idinternal.job_owner.person.email() - send_mail(request, to, - "I-D Expiring System ", - u"I-D was expired %s" % doc.file_tag(), - "idrfc/id_expired_email.txt", - dict(doc=doc, - state=doc.idstate())) - -def send_expire_notice_for_idREDESIGN(doc): +def send_expire_notice_for_draft(doc): if not doc.ad or doc.get_state_slug("draft-iesg") == "dead": return @@ -163,42 +106,6 @@ def send_expire_notice_for_idREDESIGN(doc): state=state, )) -def expire_id(doc): - 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) - - move_file("%s-%s.txt" % (doc.filename, doc.revision_display())) - move_file("%s-%s.txt.p7s" % (doc.filename, doc.revision_display())) - move_file("%s-%s.ps" % (doc.filename, doc.revision_display())) - move_file("%s-%s.pdf" % (doc.filename, doc.revision_display())) - - new_revision = "%02d" % (int(doc.revision) + 1) - - new_file = open(os.path.join(settings.INTERNET_DRAFT_PATH, "%s-%s.txt" % (doc.filename, new_revision)), 'w') - txt = render_to_string("idrfc/expire_text.txt", - dict(doc=doc, - authors=[a.person.email() for a in doc.authors.all()], - expire_days=InternetDraft.DAYS_TO_EXPIRE)) - new_file.write(txt) - new_file.close() - - doc.revision = new_revision - doc.expiration_date = datetime.date.today() - doc.last_modified_date = datetime.date.today() - doc.status = IDStatus.objects.get(status="Expired") - doc.save() - - if doc.idinternal: - if doc.idinternal.cur_state_id != IDState.DEAD: - doc.idinternal.change_state(IDState.objects.get(document_state_id=IDState.DEAD), None) - log_state_changed(None, doc, "system") - - add_document_comment(None, doc, "Document is expired by system") - def move_draft_files_to_archive(doc, rev): def move_file(f): src = os.path.join(settings.INTERNET_DRAFT_PATH, f) @@ -211,7 +118,7 @@ def move_draft_files_to_archive(doc, rev): for t in file_types: move_file("%s-%s.%s" % (doc.name, rev, t)) -def expire_idREDESIGN(doc): +def expire_draft(doc): # clean up files move_draft_files_to_archive(doc, doc.rev) @@ -222,7 +129,7 @@ def expire_idREDESIGN(doc): if doc.latest_event(type='started_iesg_process'): dead_state = State.objects.get(type="draft-iesg", slug="dead") prev = doc.get_state("draft-iesg") - prev_tag = doc.tags.filter(slug__in=('point', 'ad-f-up', 'need-rev', 'extpty')) + prev_tag = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS) prev_tag = prev_tag[0] if prev_tag else None if prev != dead_state: doc.set_state(dead_state) @@ -239,67 +146,7 @@ def expire_idREDESIGN(doc): 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) - - pattern = os.path.join(settings.INTERNET_DRAFT_PATH, "draft-*.*") - files = [] - filename_re = re.compile('^(.*)-(\d\d)$') - - def splitext(fn): - """ - Split the pathname path into a pair (root, ext) such that root + ext - == path, and ext is empty or begins with a period and contains all - periods in the last path component. - - This differs from os.path.splitext in the number of periods in the ext - parts when the final path component containt more than one period. - """ - s = fn.rfind("/") - if s == -1: - s = 0 - i = fn[s:].find(".") - if i == -1: - return fn, '' - else: - return fn[:s+i], fn[s+i:] - - for path in glob.glob(pattern): - basename = os.path.basename(path) - stem, ext = 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 = InternetDraft.objects.get(filename=filename, revision=revision) - - if doc.status_id == 3: # RFC - if ext != ".txt": - move_file_to("unknown_ids") - elif doc.status_id in (2, 4, 5, 6) and doc.expiration_date and doc.expiration_date < cut_off: - # Expired, Withdrawn by Auth, Replaced, Withdrawn by IETF, - # and expired more than DAYS_TO_EXPIRE ago - if os.path.getsize(path) < 1500: - move_file_to("deleted_tombstones") - # revert version after having deleted tombstone - doc.revision = "%02d" % (int(revision) - 1) - doc.expired_tombstone = True - doc.save() - else: - move_file_to("expired_without_tombstone") - - except InternetDraft.DoesNotExist: - move_file_to("unknown_ids") - -def clean_up_id_filesREDESIGN(): +def clean_up_draft_files(): """Move unidentified and old files out of the Internet Draft directory.""" cut_off = datetime.date.today() @@ -314,7 +161,7 @@ def clean_up_id_filesREDESIGN(): periods in the last path component. This differs from os.path.splitext in the number of periods in the ext - parts when the final path component containt more than one period. + parts when the final path component contains more than one period. """ s = fn.rfind("/") if s == -1: @@ -357,11 +204,3 @@ def clean_up_id_filesREDESIGN(): except Document.DoesNotExist: move_file_to("unknown_ids") - -if settings.USE_DB_REDESIGN_PROXY_CLASSES: - get_soon_to_expire_ids = get_soon_to_expire_idsREDESIGN - get_expired_ids = get_expired_idsREDESIGN - send_expire_warning_for_id = send_expire_warning_for_idREDESIGN - send_expire_notice_for_id = send_expire_notice_for_idREDESIGN - expire_id = expire_idREDESIGN - clean_up_id_files = clean_up_id_filesREDESIGN diff --git a/ietf/idrfc/tests.py b/ietf/idrfc/tests.py index 218927383..c0748d5a0 100644 --- a/ietf/idrfc/tests.py +++ b/ietf/idrfc/tests.py @@ -1011,13 +1011,13 @@ class ExpireIDsTestCase(django.test.TestCase): shutil.rmtree(self.id_dir) shutil.rmtree(self.archive_dir) - def write_id_file(self, name, size): + def write_draft_file(self, name, size): f = open(os.path.join(self.id_dir, name), 'w') f.write("a" * size) f.close() - def test_in_id_expire_freeze(self): - from ietf.idrfc.expire import in_id_expire_freeze + def test_in_draft_expire_freeze(self): + from ietf.idrfc.expire import in_draft_expire_freeze Meeting.objects.create(number="123", type=MeetingTypeName.objects.get(slug="ietf"), @@ -1025,70 +1025,70 @@ class ExpireIDsTestCase(django.test.TestCase): second_cut_off = Meeting.get_second_cut_off() ietf_monday = Meeting.get_ietf_monday() - self.assertTrue(not in_id_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), time(0, 0, 0)))) - self.assertTrue(not in_id_expire_freeze(datetime.datetime.combine(second_cut_off, time(0, 0, 0)))) - self.assertTrue(in_id_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), time(0, 0, 0)))) - self.assertTrue(in_id_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), time(0, 0, 0)))) - self.assertTrue(not in_id_expire_freeze(datetime.datetime.combine(ietf_monday, time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, time(0, 0, 0)))) + self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), time(0, 0, 0)))) + self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), time(0, 0, 0)))) + self.assertTrue(not in_draft_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 + def test_warn_expirable_drafts(self): + from ietf.idrfc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft draft = make_test_data() - self.assertEquals(len(list(get_soon_to_expire_ids(14))), 0) + self.assertEquals(len(list(get_soon_to_expire_drafts(14))), 0) # hack into expirable state draft.unset_state("draft-iesg") draft.expires = datetime.datetime.now() + datetime.timedelta(days=10) draft.save() - self.assertEquals(len(list(get_soon_to_expire_ids(14))), 1) + self.assertEquals(len(list(get_soon_to_expire_drafts(14))), 1) # test send warning mailbox_before = len(outbox) - send_expire_warning_for_id(draft) + send_expire_warning_for_draft(draft) self.assertEquals(len(outbox), mailbox_before + 1) self.assertTrue("aread@ietf.org" in str(outbox[-1])) # author 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 + def test_expire_drafts(self): + from ietf.idrfc.expire import get_expired_drafts, send_expire_notice_for_draft, expire_draft draft = make_test_data() - self.assertEquals(len(list(get_expired_ids())), 0) + self.assertEquals(len(list(get_expired_drafts())), 0) # hack into expirable state draft.unset_state("draft-iesg") draft.expires = datetime.datetime.now() draft.save() - self.assertEquals(len(list(get_expired_ids())), 1) + self.assertEquals(len(list(get_expired_drafts())), 1) draft.set_state(State.objects.get(type="draft-iesg", slug="watching")) - self.assertEquals(len(list(get_expired_ids())), 1) + self.assertEquals(len(list(get_expired_drafts())), 1) draft.set_state(State.objects.get(type="draft-iesg", slug="iesg-eva")) - self.assertEquals(len(list(get_expired_ids())), 0) + self.assertEquals(len(list(get_expired_drafts())), 0) # test notice mailbox_before = len(outbox) - send_expire_notice_for_id(draft) + send_expire_notice_for_draft(draft) self.assertEquals(len(outbox), mailbox_before + 1) self.assertTrue("expired" in outbox[-1]["Subject"]) # test expiry txt = "%s-%s.txt" % (draft.name, draft.rev) - self.write_id_file(txt, 5000) + self.write_draft_file(txt, 5000) - expire_id(draft) + expire_draft(draft) draft = Document.objects.get(name=draft.name) self.assertEquals(draft.get_state_slug(), "expired") @@ -1097,16 +1097,16 @@ class ExpireIDsTestCase(django.test.TestCase): 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))) - def test_clean_up_id_files(self): + def test_clean_up_draft_files(self): draft = make_test_data() - from ietf.idrfc.expire import clean_up_id_files + from ietf.idrfc.expire import clean_up_draft_files # put unknown file unknown = "draft-i-am-unknown-01.txt" - self.write_id_file(unknown, 5000) + self.write_draft_file(unknown, 5000) - clean_up_id_files() + clean_up_draft_files() self.assertTrue(not os.path.exists(os.path.join(self.id_dir, unknown))) self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "unknown_ids", unknown))) @@ -1114,9 +1114,9 @@ class ExpireIDsTestCase(django.test.TestCase): # put file with malformed name (no revision) malformed = draft.name + ".txt" - self.write_id_file(malformed, 5000) + self.write_draft_file(malformed, 5000) - clean_up_id_files() + clean_up_draft_files() self.assertTrue(not os.path.exists(os.path.join(self.id_dir, malformed))) self.assertTrue(os.path.exists(os.path.join(self.archive_dir, "unknown_ids", malformed))) @@ -1127,11 +1127,11 @@ class ExpireIDsTestCase(django.test.TestCase): draft.save() txt = "%s-%s.txt" % (draft.name, draft.rev) - self.write_id_file(txt, 5000) + self.write_draft_file(txt, 5000) pdf = "%s-%s.pdf" % (draft.name, draft.rev) - self.write_id_file(pdf, 5000) + self.write_draft_file(pdf, 5000) - clean_up_id_files() + clean_up_draft_files() # txt files shouldn't be moved (for some reason) self.assertTrue(os.path.exists(os.path.join(self.id_dir, txt))) @@ -1155,9 +1155,9 @@ class ExpireIDsTestCase(django.test.TestCase): # expired without tombstone txt = "%s-%s.txt" % (draft.name, draft.rev) - self.write_id_file(txt, 5000) + self.write_draft_file(txt, 5000) - clean_up_id_files() + clean_up_draft_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, "expired_without_tombstone", txt))) @@ -1167,9 +1167,9 @@ class ExpireIDsTestCase(django.test.TestCase): revision_before = draft.rev txt = "%s-%s.txt" % (draft.name, draft.rev) - self.write_id_file(txt, 1000) # < 1500 means tombstone + self.write_draft_file(txt, 1000) # < 1500 means tombstone - clean_up_id_files() + clean_up_draft_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))) From 9f4db554c92147431d785ffa04301472cb44dcf7 Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Thu, 4 Apr 2013 13:22:58 +0000 Subject: [PATCH 02/18] Delete some of the dead code in IPR models - Legacy-Id: 5607 --- ietf/ipr/models.py | 139 ++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 89 deletions(-) diff --git a/ietf/ipr/models.py b/ietf/ipr/models.py index 65ec0d41d..d5e23ec48 100644 --- a/ietf/ipr/models.py +++ b/ietf/ipr/models.py @@ -139,9 +139,6 @@ class IprDetail(models.Model): return None except IprContact.MultipleObjectsReturned: return self.contact.filter(contact_type=3)[0] - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'ipr_detail' class IprContact(models.Model): TYPE_CHOICES = ( @@ -162,20 +159,8 @@ class IprContact(models.Model): email = models.EmailField(max_length=255) def __str__(self): return self.name or '' - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'ipr_contacts' -class IprDraft(models.Model): - ipr = models.ForeignKey(IprDetail, related_name='drafts_old' if settings.USE_DB_REDESIGN_PROXY_CLASSES else 'drafts') - document = models.ForeignKey(InternetDraft, db_column='id_document_tag', related_name="ipr_draft_old" if settings.USE_DB_REDESIGN_PROXY_CLASSES else "ipr") - revision = models.CharField(max_length=2) - def __str__(self): - return "%s which applies to %s-%s" % ( self.ipr, self.document, self.revision ) - class Meta: - db_table = 'ipr_ids' - class IprNotification(models.Model): ipr = models.ForeignKey(IprDetail) notification = models.TextField(blank=True) @@ -183,94 +168,70 @@ class IprNotification(models.Model): time_sent = models.CharField(blank=True, max_length=25) def __str__(self): return "IPR notification for %s sent %s %s" % (self.ipr, self.date_sent, self.time_sent) - class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'ipr_notifications' - -class IprRfc(models.Model): - ipr = models.ForeignKey(IprDetail, related_name='rfcs_old' if settings.USE_DB_REDESIGN_PROXY_CLASSES else 'rfcs') - document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr_rfc_old" if settings.USE_DB_REDESIGN_PROXY_CLASSES else "ipr") - def __str__(self): - return "%s applies to RFC%04d" % ( self.ipr, self.document_id ) - class Meta: - db_table = 'ipr_rfcs' class IprUpdate(models.Model): ipr = models.ForeignKey(IprDetail, related_name='updates') updated = models.ForeignKey(IprDetail, db_column='updated', related_name='updated_by') status_to_be = models.IntegerField(null=True, blank=True) processed = models.IntegerField(null=True, blank=True) + + +from ietf.doc.models import DocAlias + +class IprDocAlias(models.Model): + ipr = models.ForeignKey(IprDetail, related_name='documents') + doc_alias = models.ForeignKey(DocAlias) + rev = models.CharField(max_length=2, blank=True) + def __unicode__(self): + if self.rev: + return u"%s which applies to %s-%s" % (self.ipr, self.doc_alias.name, self.rev) + else: + return u"%s which applies to %s" % (self.ipr, self.doc_alias.name) + class Meta: - if not settings.USE_DB_REDESIGN_PROXY_CLASSES: - db_table = 'ipr_updates' + verbose_name = "IPR document alias" + verbose_name_plural = "IPR document aliases" +# proxy stuff -if settings.USE_DB_REDESIGN_PROXY_CLASSES or hasattr(settings, "IMPORTING_IPR"): - from ietf.doc.models import DocAlias - - class IprDocAlias(models.Model): - ipr = models.ForeignKey(IprDetail, related_name='documents') - doc_alias = models.ForeignKey(DocAlias) - rev = models.CharField(max_length=2, blank=True) - def __unicode__(self): - if self.rev: - return u"%s which applies to %s-%s" % (self.ipr, self.doc_alias.name, self.rev) - else: - return u"%s which applies to %s" % (self.ipr, self.doc_alias.name) +from ietf.utils.proxy import TranslatingManager - class Meta: - verbose_name = "IPR document alias" - verbose_name_plural = "IPR document aliases" +class IprDraftProxy(IprDocAlias): + objects = TranslatingManager(dict(document="doc_alias__name")) - # proxy stuff - IprDraftOld = IprDraft - IprRfcOld = IprRfc + # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") + # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") + @property + def document(self): + from ietf.doc.proxy import DraftLikeDocAlias + return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) - from ietf.utils.proxy import TranslatingManager - - class IprDraftProxy(IprDocAlias): - objects = TranslatingManager(dict(document="doc_alias__name")) - - # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") - # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") - @property - def document(self): - from ietf.doc.proxy import DraftLikeDocAlias - return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) - - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - - class Meta: - proxy = True + #revision = models.CharField(max_length=2) + @property + def revision(self): + return self.rev - IprDraft = IprDraftProxy + class Meta: + proxy = True - class IprRfcProxy(IprDocAlias): - objects = TranslatingManager(dict(document=lambda v: ("doc_alias__name", "rfc%s" % v))) - - # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") - # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") - @property - def document(self): - from ietf.doc.proxy import DraftLikeDocAlias - return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) - - #revision = models.CharField(max_length=2) - @property - def revision(self): - return self.rev - - class Meta: - proxy = True +IprDraft = IprDraftProxy - IprRfc = IprRfcProxy - +class IprRfcProxy(IprDocAlias): + objects = TranslatingManager(dict(document=lambda v: ("doc_alias__name", "rfc%s" % v))) + # document = models.ForeignKey(InternetDraft, db_column='id_document_tag', "ipr") + # document = models.ForeignKey(Rfc, db_column='rfc_number', related_name="ipr") + @property + def document(self): + from ietf.doc.proxy import DraftLikeDocAlias + return DraftLikeDocAlias.objects.get(pk=self.doc_alias_id) -# changes done by convert-096.py:changed maxlength to max_length -# removed core -# removed edit_inline -# removed raw_id_admin + #revision = models.CharField(max_length=2) + @property + def revision(self): + return self.rev + + class Meta: + proxy = True + +IprRfc = IprRfcProxy From 2497b53ea396caf582e2503f524b11a00e38c0f2 Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Thu, 4 Apr 2013 13:23:18 +0000 Subject: [PATCH 03/18] Add name for IPR search URL - Legacy-Id: 5608 --- ietf/ipr/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ietf/ipr/urls.py b/ietf/ipr/urls.py index 77a00f9a1..43ad3749f 100644 --- a/ietf/ipr/urls.py +++ b/ietf/ipr/urls.py @@ -15,7 +15,7 @@ urlpatterns = patterns('', (r'^new-(?Pspecific)/$', new.new), (r'^new-(?Pgeneric)/$', new.new), (r'^new-(?Pthird-party)/$', new.new), - (r'^search/$', search.search), + url(r'^search/$', search.search, name="ipr_search"), ) From 5a1a2b4f656f5a767a115179b04eb3a126bc6b0b Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Thu, 4 Apr 2013 13:26:08 +0000 Subject: [PATCH 04/18] Revamp the ballot popup view - Legacy-Id: 5609 --- ietf/doc/tests.py | 2 +- ietf/doc/views_doc.py | 18 ++++++++++++------ ietf/templates/doc/ballot_popup.html | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 ietf/templates/doc/ballot_popup.html diff --git a/ietf/doc/tests.py b/ietf/doc/tests.py index a4a7cff17..29624496e 100644 --- a/ietf/doc/tests.py +++ b/ietf/doc/tests.py @@ -134,7 +134,7 @@ class DocTestCase(django.test.TestCase): self.assertEqual(r.status_code, 200) # test popup too while we're at it - r = self.client.get(urlreverse("ietf.doc.views_doc.ballot_for_popup", kwargs=dict(name=doc.name))) + r = self.client.get(urlreverse("ietf.doc.views_doc.ballot_popup", kwargs=dict(name=doc.name, ballot_id=ballot.pk))) self.assertEqual(r.status_code, 200) def test_document_json(self): diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index 49cc295cd..650f0df57 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -220,7 +220,7 @@ def document_main(request, name, rev=None): # ballot ballot_summary = None - if iesg_state and iesg_state.slug in ("lc", "writeupw", "goaheadw", "iesg-eva", "defer"): + if iesg_state and iesg_state.slug in IESG_BALLOT_ACTIVE_STATES: active_ballot = doc.active_ballot() if active_ballot: ballot_summary = needed_ballot_positions(doc, active_ballot.active_ad_positions().values()) @@ -588,6 +588,17 @@ def document_ballot(request, name, ballot_id=None): ), context_instance=RequestContext(request)) +def ballot_popup(request, name, ballot_id): + doc = get_object_or_404(Document, docalias__name=name) + c = document_ballot_content(request, doc, ballot_id=ballot_id, editable=False) + return render_to_response("doc/ballot_popup.html", + dict(doc=doc, + ballot_content=c, + ballot_id=ballot_id, + ), + context_instance=RequestContext(request)) + + def document_json(request, name): doc = get_object_or_404(Document, docalias__name=name) @@ -634,11 +645,6 @@ def document_json(request, name): return HttpResponse(json.dumps(data, indent=2), mimetype='text/plain') -def ballot_for_popup(request, name): - doc = get_object_or_404(Document, docalias__name=name) - return HttpResponse(document_ballot_content(request, doc, ballot_id=None, editable=False)) - - def ballot_json(request, name): # REDESIGN: this view needs to be deleted or updated def get_ballot(name): diff --git a/ietf/templates/doc/ballot_popup.html b/ietf/templates/doc/ballot_popup.html new file mode 100644 index 000000000..16faf4d1a --- /dev/null +++ b/ietf/templates/doc/ballot_popup.html @@ -0,0 +1,14 @@ +{% load ietf_filters %} +
+
+ {{ ballot_content }} +
+
+ + {% if request.user|has_role:"Area Director" %} + Edit Position + {% endif %} + + Close +
+
From bb7d037b3e908b7956cc1e979ad1e87f3456fbae Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Thu, 4 Apr 2013 13:27:34 +0000 Subject: [PATCH 05/18] URL reverse the IPR search link instead of hardcoding it - Legacy-Id: 5610 --- ietf/templates/doc/document_draft.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ietf/templates/doc/document_draft.html b/ietf/templates/doc/document_draft.html index 878e71d2b..e40952a1d 100644 --- a/ietf/templates/doc/document_draft.html +++ b/ietf/templates/doc/document_draft.html @@ -224,7 +224,7 @@