diff --git a/ietf/bin/iana-changes-updates b/ietf/bin/iana-changes-updates index c0f2a1b6f..67361f90f 100755 --- a/ietf/bin/iana-changes-updates +++ b/ietf/bin/iana-changes-updates @@ -55,11 +55,13 @@ while t < end: # requests if necessary text = fetch_changes_json(settings.IANA_SYNC_CHANGES_URL, t, min(end, t + MAX_INTERVAL_ACCEPTED_BY_IANA)) + syslog.syslog("Retrieved the JSON: %s" % text) + changes = parse_changes_json(text) added_events, warnings = update_history_with_changes(changes, send_email=options.send_email) for e in added_events: - syslog.syslog("Added event for %s %s: %s" % (e.doc_id, e.time, e.desc)) + syslog.syslog("Added event for %s %s: %s (parsed json: %s)" % (e.doc_id, e.time, e.desc, e.json)) for w in warnings: syslog.syslog("WARNING: %s" % w) diff --git a/ietf/idrfc/views_doc.py b/ietf/idrfc/views_doc.py index 8b5509bf9..6f921f0c5 100644 --- a/ietf/idrfc/views_doc.py +++ b/ietf/idrfc/views_doc.py @@ -55,6 +55,7 @@ from ietf.doc.utils import * from ietf.utils.history import find_history_active_at from ietf.ietfauth.decorators import has_role from ietf.doc.views_status_change import RELATION_SLUGS as status_change_relationships +from ietf.wgcharter.utils import historic_milestones_for_charter def render_document_top(request, doc, tab, name): tabs = [] @@ -92,7 +93,7 @@ def document_main(request, name, rev=None): raise Http404() return document_main_idrfc(request, name, tab="document") - doc = get_object_or_404(Document, docalias__name=name) + orig_doc = doc = get_object_or_404(Document, docalias__name=name) group = doc.group if doc.type_id == 'conflrev': conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document @@ -153,9 +154,7 @@ def document_main(request, name, rev=None): chartering = get_chartering_type(doc) # inject milestones from group - milestones = None - if chartering and not snapshot: - milestones = doc.group.groupmilestone_set.filter(state="charter") + milestones = historic_milestones_for_charter(orig_doc, doc.rev) return render_to_response("idrfc/document_charter.html", dict(doc=doc, diff --git a/ietf/liaisons/formsREDESIGN.py b/ietf/liaisons/formsREDESIGN.py index b1cadfb76..4cb1b022a 100644 --- a/ietf/liaisons/formsREDESIGN.py +++ b/ietf/liaisons/formsREDESIGN.py @@ -280,11 +280,13 @@ class LiaisonForm(forms.Form): extension = '' written += 1 name = instance.name() + ("-attachment-%s" % written) - attach = Document.objects.create( - title = self.data.get(title_key), - type_id = "liaison", + attach, _ = Document.objects.get_or_create( name = name, - external_url = name + extension, # strictly speaking not necessary, but just for the time being ... + defaults=dict( + title = self.data.get(title_key), + type_id = "liaison", + external_url = name + extension, # strictly speaking not necessary, but just for the time being ... + ) ) instance.attachments.add(attach) attach_file = open(os.path.join(settings.LIAISON_ATTACH_PATH, attach.name + extension), 'w') diff --git a/ietf/sync/iana.py b/ietf/sync/iana.py index 2284a30ad..2d280210f 100644 --- a/ietf/sync/iana.py +++ b/ietf/sync/iana.py @@ -169,6 +169,11 @@ def update_history_with_changes(changes, send_email=True): state = states[kind][c["state"]] state_type = "draft-iana-%s" % kind + if state.slug in ("need-rev", "changed"): + # the Datatracker is the ultimate source of these + # states, so skip them + continue + e = StateDocEvent.objects.filter(type="changed_state", time=timestamp, state_type=state_type, state=state) if not e: @@ -185,6 +190,8 @@ def update_history_with_changes(changes, send_email=True): e = add_state_change_event(doc, system, prev_state, state, timestamp) if e: + # for logging purposes + e.json = c added_events.append(e) if not StateDocEvent.objects.filter(doc=doc, time__gt=timestamp, state_type=state_type): diff --git a/ietf/sync/tests.py b/ietf/sync/tests.py index 385315414..1b066dc8c 100644 --- a/ietf/sync/tests.py +++ b/ietf/sync/tests.py @@ -45,6 +45,12 @@ class IANASyncTestCase(django.test.TestCase): "state": "IANA Not OK", "type": "iana_review", }, + { + "time": "2011-10-09 12:00:02", + "doc": draft.name, + "state": "IANA - Review Needed", # this should be skipped + "type": "iana_review", + }, { "time": "2011-10-09 12:00:00", "doc": draft.name, diff --git a/ietf/sync/views.py b/ietf/sync/views.py index 917216590..d038c0440 100644 --- a/ietf/sync/views.py +++ b/ietf/sync/views.py @@ -78,6 +78,9 @@ def notify(request, org, notification): out, _ = p.communicate() return (p.returncode, out) + import syslog + syslog.syslog("Running sync script from notify view POST") + if notification == "protocols": failed, out = runscript("iana-protocols-updates") diff --git a/ietf/templates/idrfc/document_charter.html b/ietf/templates/idrfc/document_charter.html index 5070cc851..b4611a964 100644 --- a/ietf/templates/idrfc/document_charter.html +++ b/ietf/templates/idrfc/document_charter.html @@ -40,7 +40,7 @@ <td> <div> <a title="{{ doc.get_state.desc }}" - {% if not snapshot and user|has_role:"Area Director,Secretariat" %} + {% if not snapshot and chartering and user|has_role:"Area Director,Secretariat" %} class="editlink" href="{% url charter_change_state name=doc.name %}" {% endif %}> {{ doc.get_state.name }} @@ -69,14 +69,6 @@ </td> </tr> - {% if chartering and group.comments %} - <tr> - {% if chartering == "initial" %}<td>Reason for chartering:</td>{% endif %} - {% if chartering == "rechartering" %}<td>Reason for rechartering:</td>{% endif %} - <td>{{ group.comments }}</td> - </tr> - {% endif %} - <tr> <td>Responsible AD:</td> <td><a {% if request.user|has_role:"Area Director,Secretariat" %}class="editlink" href="{% url charter_edit_ad name=doc.name %}"{% endif %}>{{ doc.ad|default:"none" }}</a> </td> @@ -139,9 +131,8 @@ </div> {% endif %} -{% if not snapshot and chartering %} -<h3>Proposed Milestones -{% if user|has_role:"Area Director,Secretariat" %} +<h3>{% if chartering %}Proposed{% endif %} Milestones +{% if not snapshot and user|has_role:"Area Director,Secretariat" %} <a class="edit" href="{% url wg_edit_charter_milestones acronym=doc.group.acronym %}">Edit charter milestones</a> {% endif %} </h3> @@ -151,7 +142,6 @@ {% else %} <p>No milestones for charter found.</p> {% endif %} -{% endif %} {% endblock %} diff --git a/ietf/templates/wginfo/edit_milestones.html b/ietf/templates/wginfo/edit_milestones.html index 0aea2299d..ccbf0b3dd 100644 --- a/ietf/templates/wginfo/edit_milestones.html +++ b/ietf/templates/wginfo/edit_milestones.html @@ -41,6 +41,12 @@ tr.milestone.add { font-style: italic; } <noscript>This page depends on Javascript being enabled to work properly.</noscript> +<p>Links: + <a href="{% url wg_charter acronym=group.acronym %}">{{ group.acronym }} {{ group.type.name }}</a> + - <a href="{% url doc_view name=group.charter.canonical_name %}">{{ group.charter.canonical_name }}</a> +</p> + + <p class="help">{% if forms %}Click a milestone to edit it.{% endif %} {% if needs_review %} @@ -53,7 +59,7 @@ Director. {% if can_reset %} <p> You can <a href="{% url wg_reset_charter_milestones acronym=group.acronym %}">reset -this list</a> to the currently in-use milestones for the {{ group.acronym }} {{ group.type.name }}. +this list</a> to the milestones currently in use for the {{ group.acronym }} {{ group.type.name }}. </p> {% endif %} diff --git a/ietf/templates/wginfo/wg_charter.html b/ietf/templates/wginfo/wg_charter.html index 3ffe76e99..be23cbead 100644 --- a/ietf/templates/wginfo/wg_charter.html +++ b/ietf/templates/wginfo/wg_charter.html @@ -162,13 +162,15 @@ is occasionally incorrect.</span> </p> {% endif %} -<h2>Charter for Working Group</h2> +<h2>Charter for {% if wg.state_id == "proposed" %}Proposed{% endif %} Working Group</h2> <p>{{ wg.charter_text|escape|format_charter|safe }}</p> -<h2>Milestones +<h2>{% if wg.state_id == "proposed" %}Proposed{% endif %} Milestones +{% if wg.state_id != "proposed" %} {% if user|has_role:"Area Director,Secretariat" or is_chair %} <a class="button" href="{% url wg_edit_milestones acronym=wg.acronym %}">Add or edit milestones</a> {% endif %} +{% endif %} </h2> {% with wg.milestones as milestones %}{% include "wginfo/milestones.html" %}{% endwith %} diff --git a/ietf/urls.py b/ietf/urls.py index f91e2d042..80f2d5d5d 100644 --- a/ietf/urls.py +++ b/ietf/urls.py @@ -22,9 +22,6 @@ admin.autodiscover() admin.site.disable_action('delete_selected') -from dajaxice.core import dajaxice_autodiscover -dajaxice_autodiscover() - feeds = { 'iesg-agenda': IESGAgenda, 'last-call': InLastCall, @@ -80,7 +77,6 @@ urlpatterns = patterns('', # Google webmaster tools verification url (r'^googlea30ad1dacffb5e5b.html', 'django.views.generic.simple.direct_to_template', { 'template': 'googlea30ad1dacffb5e5b.html' }), - (r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, include('dajaxice.urls')), ) if settings.SERVER_MODE in ('development', 'test'): diff --git a/ietf/wgcharter/utils.py b/ietf/wgcharter/utils.py index 1012ae473..a38cdf84a 100644 --- a/ietf/wgcharter/utils.py +++ b/ietf/wgcharter/utils.py @@ -3,7 +3,8 @@ import re, datetime, os from django.conf import settings from ietf.group.models import GroupEvent, ChangeStateGroupEvent -from ietf.doc.models import Document, DocAlias, DocHistory, RelatedDocument, DocumentAuthor, DocEvent +from ietf.doc.models import Document, DocAlias, DocHistory, RelatedDocument, DocumentAuthor, DocEvent, NewRevisionDocEvent +from ietf.utils.history import find_history_active_at def log_state_changed(request, doc, by, prev_state): e = DocEvent(doc=doc, by=by) @@ -43,6 +44,44 @@ def read_charter_text(doc): except IOError: return "Error: couldn't read charter text" +def historic_milestones_for_charter(charter, rev): + """Return GroupMilestone/GroupMilestoneHistory objects for charter + document at rev by looking through the history.""" + + chartering = "-" in rev + if chartering: + need_state = "charter" + else: + need_state = "active" + + # slight complication - we can assign milestones to a revision up + # until the point where the next superseding revision is + # published, so that time shall be our limit + revision_event = charter.latest_event(NewRevisionDocEvent, type="new_revision", rev=rev) + if not revision_event: + return [] + + e = charter.docevent_set.filter(time__gt=revision_event.time, type="new_revision").order_by("time") + if not chartering: + e = e.exclude(newrevisiondocevent__rev__contains="-") + + if e: + # subtract a margen of error to avoid collisions with + # milestones being published at the same time as the new + # revision (when approving a charter) + just_before_next_rev = e[0].time - datetime.timedelta(seconds=5) + else: + just_before_next_rev = datetime.datetime.now() + + res = [] + for m in charter.chartered_group.groupmilestone_set.all(): + mh = find_history_active_at(m, just_before_next_rev) + if mh and mh.state_id == need_state: + res.append(mh) + + return res + + def update_telechat(request, doc, by, new_telechat_date): # FIXME: reuse function in idrfc/utils.py instead of this one # (need to fix auto-setting returning item problem first though) diff --git a/ietf/wgcharter/views.py b/ietf/wgcharter/views.py index a2352febb..04f2f4a66 100644 --- a/ietf/wgcharter/views.py +++ b/ietf/wgcharter/views.py @@ -716,35 +716,12 @@ def charter_with_milestones_txt(request, name, rev): charter_text = "Error reading charter text %s" % filename - # find milestones - - chartering = "-" in rev - if chartering: - need_state = "charter" - else: - need_state = "active" - - # slight complication - we can assign milestones to a revision up - # until the point where the next superseding revision is - # published, so that time shall be our limit - e = charter.docevent_set.filter(time__gt=revision_event.time, type="new_revision").order_by("time") - if not chartering: - e = e.exclude(newrevisiondocevent__rev__contains="-") - - if e: - # subtract a margen of error - just_before_next_rev = e[0].time - datetime.timedelta(seconds=5) - else: - just_before_next_rev = datetime.datetime.now() + milestones = historic_milestones_for_charter(charter, rev) + # wrap the output nicely wrapper = textwrap.TextWrapper(initial_indent="", subsequent_indent=" " * 11, width=80, break_long_words=False) - - milestones = [] - for m in charter.chartered_group.groupmilestone_set.all(): - mh = find_history_active_at(m, just_before_next_rev) - if mh and mh.state_id == need_state: - mh.desc_filled = wrapper.fill(mh.desc) - milestones.append(mh) + for m in milestones: + m.desc_filled = wrapper.fill(m.desc) return render_to_response('wgcharter/charter_with_milestones.txt', dict(charter_text=charter_text, diff --git a/ietf/wginfo/views.py b/ietf/wginfo/views.py index f2b147f55..a0dd53071 100644 --- a/ietf/wginfo/views.py +++ b/ietf/wginfo/views.py @@ -55,7 +55,8 @@ def fill_in_charter_info(wg, include_drafts=False): wg.techadvisors = Email.objects.filter(role__group=wg, role__name="techadv") wg.editors = Email.objects.filter(role__group=wg, role__name="editor") wg.secretaries = Email.objects.filter(role__group=wg, role__name="secr") - wg.milestones = wg.groupmilestone_set.filter(state="active").order_by('due') + milestone_state = "charter" if wg.state_id == "proposed" else "active" + wg.milestones = wg.groupmilestone_set.filter(state=milestone_state).order_by('due') if include_drafts: aliases = DocAlias.objects.filter(document__type="draft", document__group=wg).select_related('document').order_by("name")