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 commita603b8e056
Note: SVN reference [5800] has been migrated to Git commit0f69f87a56
This commit is contained in:
commit
bb7fbd8cab
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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'):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in a new issue