diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py index d8caa8446..b3e63d7a7 100644 --- a/ietf/doc/utils.py +++ b/ietf/doc/utils.py @@ -59,7 +59,7 @@ def needed_ballot_positions(doc, active_positions): recuse = [p for p in active_positions if p and p.pos_id == "recuse"] answer = [] - if yes < 1: + if len(yes) < 1: answer.append("Needs a YES.") if blocking: if blocking: @@ -143,6 +143,28 @@ def get_chartering_type(doc): return chartering +def augment_events_with_revision(doc, events): + """Take a set of events for doc and add a .rev attribute with the + revision they refer to by checking NewRevisionDocEvents.""" + + event_revisions = list(NewRevisionDocEvent.objects.filter(doc=doc).order_by('time', 'id').values('id', 'rev', 'time')) + + cur_rev = doc.rev + if doc.get_state_slug() == "rfc": + cur_rev = "RFC" + + for e in sorted(events, key=lambda e: (e.time, e.id), reverse=True): + while event_revisions and (e.time, e.id) < (event_revisions[-1]["time"], event_revisions[-1]["id"]): + event_revisions.pop() + + if event_revisions: + cur_rev = event_revisions[-1]["rev"] + else: + cur_rev = "00" + + e.rev = cur_rev + + def augment_with_telechat_date(docs): """Add a telechat_date attribute to each document with the scheduled telechat or None if it's not scheduled.""" diff --git a/ietf/idrfc/views_doc.py b/ietf/idrfc/views_doc.py index d4f84c5fe..5bbb0e4ad 100644 --- a/ietf/idrfc/views_doc.py +++ b/ietf/idrfc/views_doc.py @@ -50,7 +50,7 @@ from ietf.idrfc.models import RfcIndex, DraftVersions from ietf.idrfc.idrfc_wrapper import BallotWrapper, IdWrapper, RfcWrapper from ietf.ietfworkflows.utils import get_full_info_for_draft from ietf.doc.models import * -from ietf.doc.utils import get_chartering_type, needed_ballot_positions, active_ballot_positions +from ietf.doc.utils import * from ietf.utils.history import find_history_active_at from ietf.ietfauth.decorators import has_role @@ -96,10 +96,12 @@ def document_main(request, name, rev=None): group = doc.group print group - revisions = [ doc.rev ] - for h in doc.history_set.order_by("-time"): + revisions = [] + for h in doc.history_set.order_by("time", "id"): if h.rev and not h.rev in revisions: revisions.append(h.rev) + if not doc.rev in revisions: + revisions.append(doc.rev) snapshot = False @@ -192,23 +194,7 @@ def document_history(request, name): # grab event history events = doc.docevent_set.all().order_by("-time", "-id").select_related("by") - # fill in revision numbers - event_revisions = list(NewRevisionDocEvent.objects.filter(doc=doc).order_by('time', 'id').values('rev', 'time')) - - cur_rev = doc.rev - if doc.get_state_slug() == "rfc": - cur_rev = "RFC" - - for e in events: - while event_revisions and e.time < event_revisions[-1]["time"]: - event_revisions.pop() - - if event_revisions: - cur_rev = event_revisions[-1]["rev"] - else: - cur_rev = "00" - - e.rev = cur_rev + augment_events_with_revision(doc, events) return render_to_response("idrfc/document_history.html", dict(doc=doc, @@ -257,13 +243,21 @@ def document_writeup(request, name): def document_ballot_content(request, doc, ballot_id, editable=True): """Render HTML string with content of ballot page.""" + all_ballots = list(BallotDocEvent.objects.filter(doc=doc, type="created_ballot").order_by("time")) + augment_events_with_revision(doc, all_ballots) + + ballot = None if ballot_id != None: - ballot = doc.latest_event(BallotDocEvent, type="created_ballot", pk=ballot_id) - else: - ballot = doc.latest_event(BallotDocEvent, type="created_ballot") + ballot_id = int(ballot_id) + for b in all_ballots: + if b.id == ballot_id: + ballot = b + break + elif all_ballots: + ballot = all_ballots[-1] if not ballot: - raise Http404() + raise Http404 deferred = None if doc.type_id == "draft" and doc.get_state_slug("draft-iesg") == "defer": @@ -316,7 +310,12 @@ def document_ballot_content(request, doc, ballot_id, editable=True): text_positions = [p for p in positions if p.discuss or p.comment] text_positions.sort(key=lambda p: (p.old_ad, p.ad.plain_name())) - all_ballots = BallotDocEvent.objects.filter(doc=doc, type="created_ballot") + ballot_open = not BallotDocEvent.objects.filter(doc=doc, + type__in=("closed_ballot", "created_ballot"), + time__gt=ballot.time, + ballot_type=ballot.ballot_type) + if not ballot_open: + editable = False return render_to_string("idrfc/document_ballot_content.html", dict(doc=doc, @@ -324,6 +323,7 @@ def document_ballot_content(request, doc, ballot_id, editable=True): position_groups=position_groups, text_positions=text_positions, editable=editable, + ballot_open=ballot_open, deferred=deferred, summary=summary, all_ballots=all_ballots, diff --git a/ietf/templates/idrfc/document_ballot_content.html b/ietf/templates/idrfc/document_ballot_content.html index 673cafa8c..d30d6ef3a 100644 --- a/ietf/templates/idrfc/document_ballot_content.html +++ b/ietf/templates/idrfc/document_ballot_content.html @@ -39,15 +39,19 @@ {% if all_ballots and all_ballots|length > 1 %}
Note: This ballot was opened for revision {{ ballot.rev }} and is now closed.
+{% endif %} +Summary: {{ summary }}
{% for p in text_positions %} diff --git a/ietf/templates/idrfc/document_charter.html b/ietf/templates/idrfc/document_charter.html index 89478ba42..4d8836362 100644 --- a/ietf/templates/idrfc/document_charter.html +++ b/ietf/templates/idrfc/document_charter.html @@ -15,7 +15,7 @@ Snapshots: {% for rev in revisions %} - {{ rev }} + {{ rev }} {% endfor %} diff --git a/ietf/wgcharter/views.py b/ietf/wgcharter/views.py index c843f86c0..bfe172c07 100644 --- a/ietf/wgcharter/views.py +++ b/ietf/wgcharter/views.py @@ -245,9 +245,10 @@ def submit(request, name): not_uploaded_yet = charter.rev.endswith("-00") and not os.path.exists(os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (charter.canonical_name(), charter.rev))) if not_uploaded_yet: + # this case is special - we recently chartered or rechartered and have no file yet next_rev = charter.rev else: - # Search history for possible collisions with abandoned efforts + # search history for possible collisions with abandoned efforts prev_revs = list(charter.history_set.order_by('-time').values_list('rev', flat=True)) next_rev = next_revision(charter.rev) while next_rev in prev_revs: @@ -276,7 +277,17 @@ def submit(request, name): return HttpResponseRedirect(reverse('doc_view', kwargs={'name': charter.name})) else: init = { "content": ""} - filename = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (charter.canonical_name(), charter.rev)) + c = charter + + if not_uploaded_yet: + # use text from last approved revision + last_approved = charter.rev.split("-")[0] + h = charter.history_set.filter(rev=last_approved).order_by("-time", "-id") + if h: + c = h[0] + + filename = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (c.canonical_name(), c.rev)) + try: with open(filename, 'r') as f: init["content"] = f.read() @@ -491,8 +502,8 @@ def approve(request, name): raise Http404("Charter text %s" % filename) e = NewRevisionDocEvent(doc=charter, by=login, type="new_revision") - e.desc = "New version available: %s-%s.txt" % (charter.canonical_name(), charter.rev) e.rev = next_approved_revision(charter.rev) + e.desc = "New version available: %s-%s.txt" % (charter.canonical_name(), e.rev) e.save() charter.rev = e.rev diff --git a/ietf/wginfo/edit.py b/ietf/wginfo/edit.py index 6ae1319fb..79ee29389 100644 --- a/ietf/wginfo/edit.py +++ b/ietf/wginfo/edit.py @@ -21,7 +21,7 @@ from ietf.person.forms import EmailsField class WGForm(forms.Form): name = forms.CharField(max_length=255, label="WG Name", required=True) - acronym = forms.CharField(max_length=8, label="WG Acronym", required=True) + acronym = forms.CharField(max_length=10, label="WG Acronym", required=True) chairs = EmailsField(label="WG Chairs", required=False) secretaries = EmailsField(label="WG Secretaries", required=False) techadv = EmailsField(label="WG Technical Advisors", required=False) diff --git a/static/css/doc.css b/static/css/doc.css index 3a49e3c9e..8d1e4211e 100644 --- a/static/css/doc.css +++ b/static/css/doc.css @@ -9,7 +9,7 @@ .m_h { font-family: arial; font-weight:bold;} .snapshots { margin: 0.5em 0; } -.snapshots .revisions a:first-child { font-weight: bold } +.snapshots .revisions a:last-child { font-weight: bold; } .metabox .actions a { display: inline-block; margin-right: 0.4em; } .metabox .ballot-summary { font-style: italic; }