diff --git a/ietf/idrfc/views_doc.py b/ietf/idrfc/views_doc.py index eb9be13e3..67b3a245c 100644 --- a/ietf/idrfc/views_doc.py +++ b/ietf/idrfc/views_doc.py @@ -217,17 +217,17 @@ def document_writeup(request, name): e = doc.latest_event(WriteupDocEvent, type="changed_review_announcement") writeups.append(("WG Review Announcement", e.text if e else "", - urlreverse("ietf.wgcharter.views_ballot.announcement_text", kwargs=dict(name=doc.group.acronym, ann="review")))) + urlreverse("ietf.wgcharter.views.announcement_text", kwargs=dict(name=doc.group.acronym, ann="review")))) e = doc.latest_event(WriteupDocEvent, type="changed_action_announcement") writeups.append(("WG Action Announcement", e.text if e else "", - urlreverse("ietf.wgcharter.views_ballot.announcement_text", kwargs=dict(name=doc.group.acronym, ann="action")))) + urlreverse("ietf.wgcharter.views.announcement_text", kwargs=dict(name=doc.group.acronym, ann="action")))) e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") writeups.append(("Ballot Announcement", e.text if e else "", - urlreverse("ietf.wgcharter.views_ballot.ballot_writeupnotes", kwargs=dict(name=doc.group.acronym)))) + urlreverse("ietf.wgcharter.views.ballot_writeupnotes", kwargs=dict(name=doc.group.acronym)))) if not writeups: raise Http404() diff --git a/ietf/templates/wgcharter/action_text.txt b/ietf/templates/wgcharter/action_text.txt index 0e9a18a0c..ae690fd4d 100644 --- a/ietf/templates/wgcharter/action_text.txt +++ b/ietf/templates/wgcharter/action_text.txt @@ -1,8 +1,8 @@ {% load ietf_filters %}{% autoescape off %}From: The IESG To: IETF-Announce -Subject: WG Action: {{ action_type }} {{ wg.name }} ({{wg.acronym}}) +Subject: WG Action: {{ action_type }} {{ wg.name }} ({{ wg.acronym }}) -{% filter wordwrap:73 %}{% ifequal action_type "Formed" %}A new IETF working group has been formed in the {{ wg.parent.name }}.{% endifequal %}{% ifequal action_type "Rechartered" %}The {{ wg.name }} ({{wg.acronym}}) working group in the {{ wg.parent.name }} of the IETF has been rechartered.{% endifequal %} For additional information please contact the Area Directors or the WG Chair. +{% filter wordwrap:73 %}{% ifequal action_type "Formed" %}A new IETF working group has been formed in the {{ wg.parent.name }}.{% endifequal %}{% ifequal action_type "Rechartered" %}The {{ wg.name }} ({{ wg.acronym }}) working group in the {{ wg.parent.name }} of the IETF has been rechartered.{% endifequal %} For additional information please contact the Area Directors or the WG Chair. {% include "wgcharter/wg_info.txt" %} diff --git a/ietf/templates/wgcharter/announcement_text.html b/ietf/templates/wgcharter/announcement_text.html index dda92b9f3..168d23c64 100644 --- a/ietf/templates/wgcharter/announcement_text.html +++ b/ietf/templates/wgcharter/announcement_text.html @@ -23,7 +23,7 @@ form #id_announcement_text { {% load ietf_filters %} -{% if user|in_group:"Secretariat" %} +{% if user|has_role:"Secretariat" %}
diff --git a/ietf/templates/wgcharter/ballot_issued.html b/ietf/templates/wgcharter/ballot_issued.html index 429961234..bf96c832c 100644 --- a/ietf/templates/wgcharter/ballot_issued.html +++ b/ietf/templates/wgcharter/ballot_issued.html @@ -1,13 +1,13 @@ {% extends "base.html" %} -{% block title %}Ballot for {{ charter.chartered_group }} issued{% endblock %} +{% block title %}Ballot for {{ doc.name }} issued{% endblock %} {% block content %} -

Ballot for {{ charter.chartered_group }} issued

+

Ballot for {{ doc.name }} issued

Ballot has been sent out.

{% endblock %} diff --git a/ietf/templates/wgcharter/ballot_writeupnotes.html b/ietf/templates/wgcharter/ballot_writeupnotes.html index be58ec788..ff6e041b3 100644 --- a/ietf/templates/wgcharter/ballot_writeupnotes.html +++ b/ietf/templates/wgcharter/ballot_writeupnotes.html @@ -20,7 +20,7 @@ form #id_ballot_writeup { {{ ballot_writeup_form.ballot_writeup }}
- Back + Back
diff --git a/ietf/templates/wgcharter/issue_ballot_mail.txt b/ietf/templates/wgcharter/issue_ballot_mail.txt index 3141ed79c..b901def38 100644 --- a/ietf/templates/wgcharter/issue_ballot_mail.txt +++ b/ietf/templates/wgcharter/issue_ballot_mail.txt @@ -1,9 +1,9 @@ {% autoescape off %}To: Internet Engineering Steering Group From: IESG Secretary Reply-To: IESG Secretary -Subject: Evaluation: {{ charter.chartered_group }} ({{ charter.chartered_group.acronym }}) +Subject: Evaluation: {{ doc.name }} -{% filter wordwrap:73 %}Evaluation for {{ charter.chartered_group }} ({{ charter.chartered_group.acronym }}) can be found at {{ charter_url }} +{% filter wordwrap:73 %}Evaluation for {{ doc.title }} can be found at {{ doc_url }} {% endfilter %} Please return the full line with your position. @@ -20,8 +20,8 @@ BLOCKING AND NON-BLOCKING COMMENTS ================================== {% filter wordwrap:79 %}{% for p in ad_feedback %}{{ p.ad }}: -{% if p.block_comment %}Blocking comment [{{ p.time }}]: -{{ p.block_comment }} +{% if p.discuss %}Blocking comment [{{ p.time }}]: +{{ p.discuss }} {% endif %}{% if p.comment %}Comment [{{ p.time }}]: {{ p.comment }} diff --git a/ietf/templates/wgcharter/review_text.txt b/ietf/templates/wgcharter/review_text.txt index 4611f2a5a..f56bbc4b2 100644 --- a/ietf/templates/wgcharter/review_text.txt +++ b/ietf/templates/wgcharter/review_text.txt @@ -1,8 +1,8 @@ {% load ietf_filters %}{% autoescape off %}From: The IESG To: IETF-Announce -Subject: WG Review: {{ wg.name }} ({{wg.acronym}}) +Subject: WG Review: {{ wg.name }} ({{ wg.acronym }}) -{% filter wordwrap:73 %}{% ifequal review_type "new" %}A new IETF working group has been proposed in the {{ wg.parent.name }}.{% endifequal %}{% ifequal review_type "recharter" %}The {{ wg.name }} ({{wg.acronym}}) working group in the {{ wg.parent.name }} of the IETF is undergoing rechartering.{% endifequal %} The IESG has not made any determination yet. The following draft charter was submitted, and is provided for informational purposes only. Please send your comments to the IESG mailing list (iesg at ietf.org) by {{ info.bydate }}. +{% filter wordwrap:73 %}{% ifequal review_type "new" %}A new IETF working group has been proposed in the {{ wg.parent.name }}.{% endifequal %}{% ifequal review_type "recharter" %}The {{ wg.name }} ({{wg.acronym}}) working group in the {{ wg.parent.name }} of the IETF is undergoing rechartering.{% endifequal %} The IESG has not made any determination yet. The following draft charter was submitted, and is provided for informational purposes only. Please send your comments to the IESG mailing list (iesg at ietf.org) by {{ review_date }}. {% include "wgcharter/wg_info.txt" %} diff --git a/ietf/templates/wgcharter/wg_info.txt b/ietf/templates/wgcharter/wg_info.txt index 11592bead..b25f6fdf6 100644 --- a/ietf/templates/wgcharter/wg_info.txt +++ b/ietf/templates/wgcharter/wg_info.txt @@ -3,22 +3,22 @@ Current Status: {{ wg.state.name }} Working Group Chairs: -{% for p in info.chairs %} {{ p.plain_name }} <{{p.email}}> +{% for r in chairs %} {{ r.person.plain_name }} <{{r.email.address}}> {% endfor %} Secretaries: -{% for p in info.secr %} {{ p.plain_name }} <{{p.email}}> +{% for r in secr %} {{ r.person.plain_name }} <{{r.email.address}}> {% endfor %} Technical advisors: -{% for p in info.techadv %} {{ p.plain_name }} <{{p.email}}> +{% for r in techadv %} {{ r.person.plain_name }} <{{r.email.address}}> {% endfor %} Assigned Area Director: - {{ info.ad.0.plain_name }} <{{ info.ad.0.email }}> +{% if wg.ad %} {{ wg.ad.plain_name }} <{{ ad_email }}>{% endif %} Mailing list: - Address: {{ info.list.0 }} - To Subscribe: {{ info.list_subscribe.0 }} - Archive: {{ info.list_archive.0 }} + Address: {{ wg.list_email }} + To Subscribe: {{ wg.list_subscribe }} + Archive: {{ wg.list_archive }} Charter: -{{ info.charter_txt }} +{{ charter_text }} diff --git a/ietf/wgcharter/mails.py b/ietf/wgcharter/mails.py index bc024310a..2e3d3d1d6 100644 --- a/ietf/wgcharter/mails.py +++ b/ietf/wgcharter/mails.py @@ -1,6 +1,6 @@ # generation of mails -import textwrap +import textwrap, datetime from django.template.loader import render_to_string from django.utils.html import strip_tags @@ -8,10 +8,10 @@ from django.conf import settings from django.core.urlresolvers import reverse as urlreverse from ietf.utils.mail import send_mail, send_mail_text -from ietf.idtracker.models import * from ietf.ipr.search import iprs_from_docs -from ietf.doc.models import WriteupDocEvent, DocAlias +from ietf.doc.models import WriteupDocEvent, DocAlias, BallotPositionDocEvent from ietf.person.models import Person +from ietf.wgcharter.utils import * def email_secretariat(request, wg, type, text): to = ["iesg-secretary@ietf.org"] @@ -48,14 +48,51 @@ def generate_ballot_writeup(request, doc): return e -def generate_issue_ballot_mail(request, charter): - raise NotImplemented +def default_action_text(wg, charter, user, action): + e = WriteupDocEvent(doc=charter, by=user) + e.by = user + e.type = "changed_action_announcement" + e.desc = "WG action text was changed" + e.text = render_to_string("wgcharter/action_text.txt", + dict(wg=wg, + charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), + charter_text=read_charter_text(charter), + chairs=wg.role_set.filter(name="chair"), + secr=wg.role_set.filter(name="secr"), + techadv=wg.role_set.filter(name="techadv"), + ad_email=wg.ad.role_email("ad") if wg.ad else None, + action_type=action, + )) + + e.save() + return e + +def default_review_text(wg, charter, user): + e = WriteupDocEvent(doc=charter, by=user) + e.by = user + e.type = "changed_review_announcement" + e.desc = "WG review text was changed" + e.text = render_to_string("wgcharter/review_text.txt", + dict(wg=wg, + charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), + charter_text=read_charter_text(charter), + chairs=wg.role_set.filter(name="chair"), + secr=wg.role_set.filter(name="secr"), + techadv=wg.role_set.filter(name="techadv"), + ad_email=wg.ad.role_email("ad") if wg.ad else None, + review_date=(datetime.date.today() + datetime.timedelta(weeks=1)).isoformat(), + review_type="new" if wg.state_id == "proposed" else "recharter", + ) + ) + e.save() + return e + +def generate_issue_ballot_mail(request, doc, ballot): active_ads = Person.objects.filter(email__role__name="ad", email__role__group__state="active").distinct() - e = charter.latest_event(type="started_iesg_process") seen = [] positions = [] - for p in GroupBallotPositionDocEvent.objects.filter(doc=charter, type="changed_ballot_position", time__gte=e.time).order_by("-time", '-id').select_related('ad'): + for p in BallotPositionDocEvent.objects.filter(doc=doc, type="changed_ballot_position", ballot=ballot).order_by("-time", '-id').select_related('ad'): if p.ad not in seen: positions.append(p) seen.append(p.ad) @@ -87,9 +124,9 @@ def generate_issue_ballot_mail(request, charter): if p.ad in active_ads: active_ad_positions.append(fmt) - if not p.pos_id == "block": - p.block_comment = "" - if p.comment or p.block_comment: + if not p.pos or not p.pos.blocking: + p.discuss = "" + if p.comment or p.discuss: ad_feedback.append(p) else: inactive_ad_positions.append(fmt) @@ -98,15 +135,15 @@ def generate_issue_ballot_mail(request, charter): inactive_ad_positions.sort() ad_feedback.sort(key=lambda p: p.ad.plain_name()) - e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") + e = doc.latest_event(WriteupDocEvent, type="changed_action_announcement") approval_text = e.text if e else "" - e = charter.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") + e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") ballot_writeup = e.text if e else "" return render_to_string("wgcharter/issue_ballot_mail.txt", - dict(charter=charter, - charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), + dict(doc=doc, + doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), active_ad_positions=active_ad_positions, inactive_ad_positions=inactive_ad_positions, ad_feedback=ad_feedback, diff --git a/ietf/wgcharter/tests.py b/ietf/wgcharter/tests.py index f156980ec..96f4d89b1 100644 --- a/ietf/wgcharter/tests.py +++ b/ietf/wgcharter/tests.py @@ -170,13 +170,14 @@ class CharterApproveBallotTestCase(django.test.TestCase): p = Person.objects.get(name="Aread Irector") - e = DocEvent() - e.type = "started_iesg_process" - e.by = p - e.doc = charter - e.desc = "IESG process started" - e.save() - + BallotDocEvent.objects.create( + type="created_ballot", + ballot_type=BallotType.objects.get(doc_type="charter", slug="approve"), + by=p, + doc=charter, + desc="Created ballot", + ) + charter.set_state(State.objects.get(type="charter", slug="iesgrev")) # normal get diff --git a/ietf/wgcharter/utils.py b/ietf/wgcharter/utils.py index ec9aa8a97..cdf2fe701 100644 --- a/ietf/wgcharter/utils.py +++ b/ietf/wgcharter/utils.py @@ -1,4 +1,4 @@ -import re, datetime +import re, datetime, os from django.conf import settings @@ -102,6 +102,14 @@ def next_approved_revision(rev): m = re.match(r"(?P[0-9][0-9])(-(?P[0-9][0-9]))?", rev) return "%#02d" % (int(m.group('major')) + 1) +def read_charter_text(doc): + filename = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev)) + try: + with open(filename, 'r') as f: + return f.read() + except IOError: + return "Error: couldn't read charter text" + def update_telechat(request, doc, by, new_telechat_date): # FIXME: fix auto-setting returning item problem and reuse # function in idrfc/utils.py instead of this one diff --git a/ietf/wgcharter/views.py b/ietf/wgcharter/views.py index d3fdb11b3..847fdd590 100644 --- a/ietf/wgcharter/views.py +++ b/ietf/wgcharter/views.py @@ -294,71 +294,6 @@ def submit(request, name): 'wg': wg}, context_instance=RequestContext(request)) -def default_action_text(wg, charter, user, action): - e = WriteupDocEvent(doc=charter, by=user) - e.by = user - e.type = "changed_action_announcement" - e.desc = "WG action text was changed" - - info = {} - info['chairs'] = [{ 'name': x.person.plain_name(), 'email': x.email.address} for x in wg.role_set.filter(name="Chair")] - info['secr'] = [{ 'name': x.person.plain_name(), 'email': x.email.address} for x in wg.role_set.filter(name="Secr")] - info['techadv'] = [{ 'name': x.person.plain_name(), 'email': x.email.address} for x in wg.role_set.filter(name="Techadv")] - info['ad'] = {'name': wg.ad.plain_name(), 'email': wg.ad.role_email("ad").address } if wg.ad else None, - info['list'] = wg.list_email if wg.list_email else None, - info['list_subscribe'] = str(wg.list_subscribe) if wg.list_subscribe else None, - info['list_archive'] = str(wg.list_archive) if wg.list_archive else None, - - filename = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (wg.charter.canonical_name(), wg.charter.rev)) - try: - charter_text = open(filename, 'r') - info['charter_txt'] = charter_text.read() - except IOError: - info['charter_txt'] = "Error: couldn't read charter text" - - e.text = render_to_string("wgcharter/action_text.txt", - dict(wg=wg, - charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), - action_type=action, - info=info, - )) - - e.save() - return e - -def default_review_text(wg, charter, user): - e = WriteupDocEvent(doc=charter, by=user) - e.by = user - e.type = "changed_review_announcement" - e.desc = "WG review text was changed" - info = {} - info['chairs'] = [{ 'name': x.person.plain_name(), 'email': x.email.address} for x in wg.role_set.filter(name="Chair")] - info['secr'] = [{ 'name': x.person.plain_name(), 'email': x.email.address} for x in wg.role_set.filter(name="Secr")] - info['techadv'] = [{ 'name': x.person.plain_name(), 'email': x.email.address} for x in wg.role_set.filter(name="Techadv")] - info['ad'] = {'name': wg.ad.plain_name(), 'email': wg.ad.role_email("ad").address } if wg.ad else None, - info['list'] = wg.list_email if wg.list_email else None, - info['list_subscribe'] = wg.list_subscribe if wg.list_subscribe else None, - info['list_archive'] = wg.list_archive if wg.list_archive else None, - - info['bydate'] = (date.today() + timedelta(weeks=1)).isoformat() - - filename = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (wg.charter.canonical_name(), wg.charter.rev)) - try: - charter_text = open(filename, 'r') - info['charter_txt'] = charter_text.read() - except IOError: - info['charter_txt'] = "Error: couldn't read charter text" - - e.text = render_to_string("wgcharter/review_text.txt", - dict(wg=wg, - charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), - info=info, - review_type="new" if wg.state_id == "proposed" else "recharter", - ) - ) - e.save() - return e - class AnnouncementTextForm(forms.Form): announcement_text = forms.CharField(widget=forms.Textarea, required=True) @@ -436,7 +371,7 @@ def announcement_text(request, name, ann): return render_to_response('wgcharter/announcement_text.html', dict(charter=charter, announcement=ann, - back_url=charter.get_absolute_url(), + back_url=urlreverse("doc_writeup", kwargs=dict(name=charter.name)), announcement_text_form=form, ), context_instance=RequestContext(request)) @@ -459,10 +394,10 @@ def ballot_writeupnotes(request, name): else: raise Http404 - charter = set_or_create_charter(wg) + charter = wg.charter - started_process = charter.latest_event(type="started_iesg_process") - if not started_process: + ballot = charter.latest_event(BallotDocEvent, type="created_ballot") + if not ballot: raise Http404() login = request.user.get_profile() @@ -477,7 +412,7 @@ def ballot_writeupnotes(request, name): form = BallotWriteupForm(initial=dict(ballot_writeup=existing.text)) - if request.method == 'POST' and "save_ballot_writeup" in request.POST or "issue_ballot" in request.POST: + if request.method == 'POST' and ("save_ballot_writeup" in request.POST or "issue_ballot" in request.POST): form = BallotWriteupForm(request.POST) if form.is_valid(): t = form.cleaned_data["ballot_writeup"] @@ -490,16 +425,16 @@ def ballot_writeupnotes(request, name): e.save() if "issue_ballot" in request.POST and approval: - if has_role(request.user, "Area Director") and not charter.latest_event(BallotPositionDocEvent, ad=login, time__gte=started_process.time): + if has_role(request.user, "Area Director") and not charter.latest_event(BallotPositionDocEvent, type="changed_ballot_position", ad=login, ballot=ballot): # sending the ballot counts as a yes - pos = GroupBallotPositionDocEvent(doc=charter, by=login) + pos = BallotPositionDocEvent(doc=charter, by=login) pos.type = "changed_ballot_position" pos.ad = login pos.pos_id = "yes" pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.plain_name()) pos.save() - msg = generate_issue_ballot_mail(request, charter) + msg = generate_issue_ballot_mail(request, charter, ballot) send_mail_preformatted(request, msg) e = DocEvent(doc=charter, by=login) @@ -509,14 +444,13 @@ def ballot_writeupnotes(request, name): e.save() return render_to_response('wgcharter/ballot_issued.html', - dict(charter=charter, - back_url=charter.get_absolute_url()), + dict(doc=charter, + ), context_instance=RequestContext(request)) return render_to_response('wgcharter/ballot_writeupnotes.html', dict(charter=charter, - back_url=charter.get_absolute_url(), ballot_issued=bool(charter.latest_event(type="sent_ballot_announcement")), ballot_writeup_form=form, reissue=reissue,