Skip to content

Commit 02a9da5

Browse files
committed
Manually moved the concepts forward. Reworked some presentation. Working enough to bring testers in at Sprint93
- Legacy-Id: 9717
1 parent 61474a4 commit 02a9da5

22 files changed

Lines changed: 519 additions & 150 deletions

ietf/doc/fields.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from django import forms
55
from django.core.urlresolvers import reverse as urlreverse
66

7+
import debug # pyflakes:ignore
8+
79
from ietf.doc.models import Document, DocAlias
810
from ietf.doc.utils import uppercase_std_abbreviated_name
911

ietf/doc/mails.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,26 @@ def email_stream_tags_changed(request, doc, added_tags, removed_tags, by, commen
488488
by=by,
489489
comment=comment))
490490

491+
def send_review_possibly_replaces_request(request, doc):
492+
to_email = []
493+
494+
if doc.stream_id == "ietf":
495+
to_email.extend(r.formatted_email() for r in Role.objects.filter(group=doc.group, name="chair").select_related("email", "person"))
496+
elif doc.stream_id == "iab":
497+
to_email.append("IAB Stream <iab-stream@iab.org>")
498+
elif doc.stream_id == "ise":
499+
to_email.append("Independent Submission Editor <rfc-ise@rfc-editor.org>")
500+
elif doc.stream_id == "irtf":
501+
to_email.append("IRSG <irsg@irtf.org>")
502+
503+
if not to_email:
504+
to_email.append("internet-drafts@ietf.org")
505+
506+
if to_email:
507+
send_mail(request, to_email, settings.DEFAULT_FROM_EMAIL,
508+
'Review of suggested possible replacements for %s-%s needed' % (doc.name, doc.rev),
509+
'doc/mail/review_possibly_replaces_request.txt', {
510+
'doc': doc,
511+
'possibly_replaces': doc.related_that_doc("possibly-replaces"),
512+
'review_url': settings.IDTRACKER_BASE_URL + urlreverse("doc_review_possibly_replaces", kwargs={ "name": doc.name }),
513+
})

ietf/doc/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ class DocReminder(models.Model):
654654
("completed_resurrect", "Completed resurrect"),
655655
("changed_consensus", "Changed consensus"),
656656
("published_rfc", "Published RFC"),
657+
("added_suggested_replaces", "Added suggested replacement relationships"),
658+
("reviewed_suggested_replaces", "Reviewed suggested replacement relationships"),
657659

658660
# WG events
659661
("changed_group", "Changed group"),

ietf/doc/tests_draft.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from ietf.doc.models import ( Document, DocAlias, DocReminder, DocumentAuthor, DocEvent,
1313
ConsensusDocEvent, LastCallDocEvent, RelatedDocument, State, TelechatDocEvent,
14-
WriteupDocEvent, BallotDocEvent)
14+
WriteupDocEvent, BallotDocEvent, DocRelationshipName)
1515
from ietf.doc.utils import get_tags_for_stream_id
1616
from ietf.name.models import StreamName, IntendedStdLevelName, DocTagName
1717
from ietf.group.models import Group
@@ -1255,11 +1255,14 @@ def test_change_replaces(self):
12551255
self.assertEqual(len(q('[type=submit]:contains("Save")')), 1)
12561256

12571257
# Post that says replacea replaces base a
1258+
RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias_set.first(),
1259+
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
12581260
self.assertEqual(self.basea.get_state().slug,'active')
12591261
r = self.client.post(url, dict(replaces=str(DocAlias.objects.get(name=self.basea.name).id)))
12601262
self.assertEqual(r.status_code, 302)
12611263
self.assertEqual(RelatedDocument.objects.filter(relationship__slug='replaces',source=self.replacea).count(),1)
12621264
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'repl')
1265+
self.assertTrue(not RelatedDocument.objects.filter(relationship='possibly-replaces', source=self.replacea))
12631266

12641267
# Post that says replaceboth replaces both base a and base b
12651268
url = urlreverse('doc_change_replaces', kwargs=dict(name=self.replaceboth.name))
@@ -1281,3 +1284,21 @@ def test_change_replaces(self):
12811284
self.assertEqual(r.status_code, 302)
12821285
self.assertEqual(Document.objects.get(name='draft-test-base-a').get_state().slug,'active')
12831286

1287+
def test_review_possibly_replaces(self):
1288+
replaced = self.basea.docalias_set.first()
1289+
RelatedDocument.objects.create(source=self.replacea, target=replaced,
1290+
relationship=DocRelationshipName.objects.get(slug="possibly-replaces"))
1291+
1292+
url = urlreverse('doc_review_possibly_replaces', kwargs=dict(name=self.replacea.name))
1293+
login_testing_unauthorized(self, "secretary", url)
1294+
1295+
r = self.client.get(url)
1296+
self.assertEquals(r.status_code, 200)
1297+
q = PyQuery(r.content)
1298+
self.assertEquals(len(q('form[name=review-suggested-replaces]')), 1)
1299+
1300+
r = self.client.post(url, dict(replaces=[replaced.pk]))
1301+
self.assertEquals(r.status_code, 302)
1302+
self.assertTrue(not self.replacea.related_that_doc("possibly-replaces"))
1303+
self.assertEqual(len(self.replacea.related_that_doc("replaces")), 1)
1304+
self.assertEquals(Document.objects.get(pk=self.basea.pk).get_state().slug, 'repl')

ietf/doc/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/stream/$', views_draft.change_stream, name='doc_change_stream'),
8080
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/replaces/$', views_draft.replaces, name='doc_change_replaces'),
8181
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/notify/$', views_doc.edit_notify, name='doc_change_notify'),
82+
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/suggested-replaces/$', views_draft.review_possibly_replaces, name='doc_review_possibly_replaces'),
8283
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/status/$', views_draft.change_intention, name='doc_change_intended_status'),
8384
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/telechat/$', views_doc.telechat_date, name='doc_change_telechat_date'),
8485
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/iesgnote/$', views_draft.edit_iesg_note, name='doc_change_iesg_note'),

ietf/doc/utils.py

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@
1010
from django.forms import ValidationError
1111
from django.utils.html import strip_tags, escape
1212

13-
from ietf.utils import markup_txt
14-
from ietf.doc.models import Document, DocHistory
13+
from ietf.doc.models import Document, DocHistory, State
1514
from ietf.doc.models import DocAlias, RelatedDocument, BallotType, DocReminder
1615
from ietf.doc.models import DocEvent, BallotDocEvent, NewRevisionDocEvent, StateDocEvent
1716
from ietf.doc.models import save_document_in_history, STATUSCHANGE_RELATIONS
1817
from ietf.name.models import DocReminderTypeName, DocRelationshipName
1918
from ietf.group.models import Role
2019
from ietf.person.models import Email
2120
from ietf.ietfauth.utils import has_role
22-
from ietf.utils import draft
21+
from ietf.utils import draft, markup_txt
2322
from ietf.utils.mail import send_mail
2423

2524
#FIXME - it would be better if this lived in ietf/doc/mails.py, but there's
@@ -314,9 +313,9 @@ def update_reminder(doc, reminder_type_slug, event, due_date):
314313
reminder.active = False
315314
reminder.save()
316315

317-
def prettify_std_name(n):
316+
def prettify_std_name(n, spacing=" "):
318317
if re.match(r"(rfc|bcp|fyi|std)[0-9]+", n):
319-
return n[:3].upper() + " " + n[3:]
318+
return n[:3].upper() + spacing + n[3:]
320319
else:
321320
return n
322321

@@ -459,6 +458,75 @@ def rebuild_reference_relations(doc,filename=None):
459458

460459
return ret
461460

461+
def collect_email_addresses(emails, doc):
462+
for author in doc.authors.all():
463+
if author.address not in emails:
464+
emails[author.address] = '"%s"' % (author.person.name)
465+
if doc.group and doc.group.acronym != 'none':
466+
for role in doc.group.role_set.filter(name='chair'):
467+
if role.email.address not in emails:
468+
emails[role.email.address] = '"%s"' % (role.person.name)
469+
if doc.group.type.slug == 'wg':
470+
address = '%s-ads@tools.ietf.org' % doc.group.acronym
471+
if address not in emails:
472+
emails[address] = '"%s-ads"' % (doc.group.acronym)
473+
elif doc.group.type.slug == 'rg':
474+
for role in doc.group.parent.role_set.filter(name='chair'):
475+
if role.email.address not in emails:
476+
emails[role.email.address] = '"%s"' % (role.person.name)
477+
if doc.shepherd and doc.shepherd.address not in emails:
478+
emails[doc.shepherd.address] = u'"%s"' % (doc.shepherd.person.name or "")
479+
480+
def set_replaces_for_document(request, doc, new_replaces, by, email_subject, email_comment=""):
481+
emails = {}
482+
collect_email_addresses(emails, doc)
483+
484+
relationship = DocRelationshipName.objects.get(slug='replaces')
485+
old_replaces = doc.related_that_doc("replaces")
486+
487+
for d in old_replaces:
488+
if d not in new_replaces:
489+
collect_email_addresses(emails, d.document)
490+
RelatedDocument.objects.filter(source=doc, target=d, relationship=relationship).delete()
491+
if not RelatedDocument.objects.filter(target=d, relationship=relationship):
492+
s = 'active' if d.document.expires > datetime.datetime.now() else 'expired'
493+
d.document.set_state(State.objects.get(type='draft', slug=s))
494+
495+
for d in new_replaces:
496+
if d not in old_replaces:
497+
collect_email_addresses(emails, d.document)
498+
RelatedDocument.objects.create(source=doc, target=d, relationship=relationship)
499+
d.document.set_state(State.objects.get(type='draft', slug='repl'))
500+
501+
e = DocEvent(doc=doc, by=by, type='changed_document')
502+
new_replaces_names = u", ".join(d.name for d in new_replaces) or u"None"
503+
old_replaces_names = u", ".join(d.name for d in old_replaces) or u"None"
504+
e.desc = u"This document now replaces <b>%s</b> instead of %s" % (new_replaces_names, old_replaces_names)
505+
e.save()
506+
507+
# make sure there are no lingering suggestions duplicating new replacements
508+
RelatedDocument.objects.filter(source=doc, target__in=new_replaces, relationship="possibly-replaces").delete()
509+
510+
email_desc = e.desc.replace(", ", "\n ")
511+
512+
if email_comment:
513+
email_desc += "\n" + email_comment
514+
515+
to = [
516+
u'%s <%s>' % (emails[email], email) if emails[email] else u'<%s>' % email
517+
for email in sorted(emails)
518+
]
519+
520+
from ietf.doc.mails import html_to_text
521+
522+
send_mail(request, to,
523+
"DraftTracker Mail System <iesg-secretary@ietf.org>",
524+
email_subject,
525+
"doc/mail/change_notice.txt",
526+
dict(text=html_to_text(email_desc),
527+
doc=doc,
528+
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
529+
462530
def check_common_doc_name_rules(name):
463531
"""Check common rules for document names for use in forms, throws
464532
ValidationError in case there's a problem."""

ietf/doc/views_doc.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ def document_main(request, name, rev=None):
345345

346346
replaces = [d.name for d in doc.related_that_doc("replaces")]
347347
replaced_by = [d.name for d in doc.related_that("replaces")]
348+
possibly_replaces = [d.name for d in doc.related_that_doc("possibly-replaces")]
349+
possibly_replaced_by = [d.name for d in doc.related_that("possibly-replaces")]
348350
published = doc.latest_event(type="published_rfc")
349351
started_iesg_process = doc.latest_event(type="started_iesg_process")
350352

@@ -355,6 +357,8 @@ def document_main(request, name, rev=None):
355357
table_rows = dict(doc=4, stream=2, iesg=4, iana=2, rfced=1)
356358
table_rows['doc'] += 1 if replaces or can_edit_stream_info else 0
357359
table_rows['doc'] += 1 if replaced_by else 0
360+
table_rows['doc'] += 1 if possibly_replaces else 0
361+
table_rows['doc'] += 1 if possibly_replaced_by else 0
358362
table_rows['doc'] += 1 if doc.get_state_slug() != "rfc" else 0
359363
table_rows['doc'] += 1 if conflict_reviews else 0
360364

@@ -396,6 +400,8 @@ def document_main(request, name, rev=None):
396400

397401
replaces=replaces,
398402
replaced_by=replaced_by,
403+
possibly_replaces=possibly_replaces,
404+
possibly_replaced_by=possibly_replaced_by,
399405
updates=[prettify_std_name(d.name) for d in doc.related_that_doc("updates")],
400406
updated_by=[prettify_std_name(d.document.canonical_name()) for d in doc.related_that("updates")],
401407
obsoletes=[prettify_std_name(d.name) for d in doc.related_that_doc("obs")],

0 commit comments

Comments
 (0)