Merged [5794] to [5800] from olau@iola.dk:

* Skip IANA - Review Needed and Version Changed - Review Needed changes from
    IANA as it turns out that the Datatracker is the authoritative source on
    these states. Also improve logging so that the raw JSON from IANA is
    dumped, the parsed JSON on imported changes is dumped and we write to
    syslog before starting a sync script in the notification view.

  * Only add charter state change link when chartering, it doesn't make sense
    for an approved charter. Fixes #861.

  * Don't display group.comments on the charter document page. Apparently
    group.comments have been used by the Secretariat in the past for
    chartering comments, but it's not possible to edit the field and the whole
    thing doesn't make sense from a modelling perspective - a feature like
    this should probably use the note field on the charter.  Fixes issue
    #1048.

  * Don't crash if an attachment has been created already, just reuse it -
    this case shouldn't actually happen, but apparently sometimes does,
    probably due to a concurrency issue

  * Add link to charter pages from the milestones editing page (besides the
    cancel button), fixes #1044.

  * Special-case proposed working groups with respect to milestones, they get
    the charter milestones on the WG charter page rather than the current set

  * Show approved milestones on /doc/charter-xyz/ page if the charter is
    approved instead of only showing proposed milestones for proposed charters
 - Legacy-Id: 5812
Note: SVN reference [5794] has been migrated to Git commit a603b8e056

Note: SVN reference [5800] has been migrated to Git commit 0f69f87a56
This commit is contained in:
Henrik Levkowetz 2013-07-14 14:00:39 +00:00
commit bb7fbd8cab
13 changed files with 88 additions and 58 deletions

View file

@ -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)

View file

@ -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,

View file

@ -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')

View file

@ -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):

View file

@ -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,

View file

@ -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")

View file

@ -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 %}

View file

@ -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 %}

View file

@ -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 %}

View file

@ -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'):

View file

@ -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)

View file

@ -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,

View file

@ -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")