Port IESG agenda pages to new schema, add tests for them, move agenda

utilities to agenda.py, fix a couple of things, remove obsolete test
versions of agenda view, add support for viewing future IESG agendas
through /agenda/YYYY-MM-DD/* (useful when testing)
 - Legacy-Id: 6395
This commit is contained in:
Ole Laursen 2013-10-09 12:40:42 +00:00
parent 53ec62a5c9
commit bd34270cbc
21 changed files with 523 additions and 470 deletions

170
ietf/iesg/agenda.py Normal file
View file

@ -0,0 +1,170 @@
# utilities for constructing agendas for IESG telechats
import codecs, re, os, datetime
from django.http import Http404
from django.conf import settings
from ietf.iesg.models import TelechatDate, TelechatAgendaItem
from ietf.doc.models import Document, TelechatDocEvent, LastCallDocEvent, ConsensusDocEvent, DocEvent
from ietf.group.models import Group, GroupMilestone
def get_agenda_date(date=None):
if not date:
try:
return TelechatDate.objects.active().order_by('date')[0].date
except IndexError:
return datetime.date.today()
else:
try:
return TelechatDate.objects.active().get(date=datetime.datetime.strptime(date, "%Y-%m-%d").date()).date
except (ValueError, TelechatDate.DoesNotExist):
raise Http404
def get_doc_section(doc):
if doc.type_id == 'draft':
if doc.intended_std_level_id in ["bcp", "ds", "ps", "std"]:
s = "2"
else:
s = "3"
g = doc.group_acronym()
if g and str(g) != 'none':
s = s + "1"
elif (s == "3") and doc.stream_id in ("ise","irtf"):
s = s + "3"
else:
s = s + "2"
if doc.get_state_slug() != "rfc" and doc.get_state_slug('draft-iesg') not in ("lc", "writeupw", "goaheadw", "iesg-eva", "defer"):
s = s + "3"
elif doc.returning_item():
s = s + "2"
else:
s = s + "1"
elif doc.type_id == 'charter':
s = get_wg_section(doc.group)
elif doc.type_id == 'statchg':
protocol_action = False
for relation in doc.relateddocument_set.filter(relationship__slug__in=('tops','tois','tohist','toinf','tobcp','toexp')):
if relation.relationship.slug in ('tops','tois') or relation.target.document.std_level.slug in ('std','ds','ps'):
protocol_action = True
if protocol_action:
s="23"
else:
s="33"
if doc.get_state_slug() not in ("iesgeval", "defer", "appr-pr", "appr-pend", "appr-sent"):
s = s + "3"
elif doc.returning_item():
s = s + "2"
else:
s = s + "1"
elif doc.type_id == 'conflrev':
if doc.get_state('conflrev').slug not in ('adrev','iesgeval','appr-reqnopub-pend','appr-reqnopub-sent','appr-noprob-pend','appr-noprob-sent','defer'):
s = "343"
elif doc.returning_item():
s = "342"
else:
s = "341"
return s
def get_wg_section(wg):
s = ""
charter_slug = None
if wg.charter:
charter_slug = wg.charter.get_state_slug()
if wg.state_id in ['active','dormant']:
if charter_slug in ['extrev','iesgrev']:
s = '422'
else:
s = '421'
else:
if charter_slug in ['extrev','iesgrev']:
s = '412'
else:
s = '411'
return s
def agenda_docs(date):
matches = Document.objects.filter(docevent__telechatdocevent__telechat_date=date).select_related("stream").distinct()
docmatches = []
for doc in matches:
if doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date != date:
continue
e = doc.latest_event(type="started_iesg_process")
doc.balloting_started = e.time if e else datetime.datetime.min
if doc.type_id == "draft":
s = doc.get_state("draft-iana-review")
if s: # and s.slug in ("not-ok", "changed", "need-rev"):
doc.iana_review_state = str(s)
if doc.get_state_slug("draft-iesg") == "lc":
e = doc.latest_event(LastCallDocEvent, type="sent_last_call")
if e:
doc.lastcall_expires = e.expires
if doc.stream_id in ("ietf", "irtf", "iab"):
doc.consensus = "Unknown"
e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
if e:
doc.consensus = "Yes" if e.consensus else "No"
elif doc.type_id=='conflrev':
doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
docmatches.append(doc)
# Be careful to keep this the same as what's used in agenda_documents
docmatches.sort(key=lambda d: d.balloting_started)
res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4))
for k in range(1,4):
res['s34%d'%k]=[]
for doc in docmatches:
section_key = "s" + get_doc_section(doc)
if section_key not in res:
res[section_key] = []
res[section_key].append(doc)
return res
def agenda_wg_actions(date):
res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4))
charters = Document.objects.filter(type="charter", docevent__telechatdocevent__telechat_date=date).select_related("group").distinct()
charters = charters.filter(group__state__slug__in=["proposed","active"])
for c in charters:
if c.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date != date:
continue
c.group.txt_link = settings.CHARTER_TXT_URL + "%s-%s.txt" % (c.canonical_name(), c.rev)
section_key = "s" + get_wg_section(c.group)
if section_key not in res:
res[section_key] = []
res[section_key].append(c)
return res
def agenda_management_issues(date):
return TelechatAgendaItem.objects.filter(type=3).order_by('id')
def agenda_data(request, date=None):
"""Return a dict with the different IESG telechat agenda components."""
date = get_agenda_date(date)
docs = agenda_docs(date)
mgmt = agenda_management_issues(date)
wgs = agenda_wg_actions(date)
data = {'date':str(date), 'docs':docs,'mgmt':mgmt,'wgs':wgs}
for key, filename in {'action_items':settings.IESG_TASK_FILE,
'roll_call':settings.IESG_ROLL_CALL_FILE,
'minutes':settings.IESG_MINUTES_FILE}.items():
try:
f = codecs.open(filename, 'r', 'utf-8', 'replace')
text = f.read().strip()
f.close()
data[key] = text
except IOError:
data[key] = "(Error reading "+key+")"
return data

View file

@ -1,4 +1,4 @@
import os, shutil
import os, shutil, json
import django.test
from django.core.urlresolvers import reverse as urlreverse
@ -6,12 +6,14 @@ from django.conf import settings
from pyquery import PyQuery
from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest, canonicalize_feed, login_testing_unauthorized
from ietf.utils.test_data import make_test_data
from ietf.doc.models import Document, DocEvent, TelechatDocEvent, State
from ietf.person.models import Person
from ietf.group.models import Group
from ietf.name.models import StreamName
from ietf.iesg.models import *
from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest, canonicalize_feed, login_testing_unauthorized
from ietf.iesg.agenda import get_agenda_date
class ReviewDecisionsTests(django.test.TestCase):
def test_review_decisions(self):
@ -30,27 +32,113 @@ class ReviewDecisionsTests(django.test.TestCase):
class IESGAgendaTests(django.test.TestCase):
def test_feed(self):
draft = make_test_data()
def setUp(self):
make_test_data()
ise_draft = Document.objects.get(name="draft-imaginary-independent-submission")
ise_draft.stream = StreamName.objects.get(slug="ise")
ise_draft.save()
self.telechat_docs = {
"ietf_draft": Document.objects.get(name="draft-ietf-mars-test"),
"ise_draft": ise_draft,
"conflrev": Document.objects.get(name="conflict-review-imaginary-irtf-submission"),
"statusch": Document.objects.get(name="status-change-imaginary-mid-review"),
"charter": Document.objects.filter(type="charter")[0],
}
by = Person.objects.get(name="Aread Irector")
date = get_agenda_date()
for d in self.telechat_docs.values():
TelechatDocEvent.objects.create(type="scheduled_for_telechat",
doc=d,
by=by,
telechat_date=date,
returning_item=True)
def test_feed(self):
url = "/feed/iesg-agenda/"
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
self.assertTrue(draft.name not in r.content)
# add to schedule
e = TelechatDocEvent(type="scheduled_for_telechat")
e.doc = draft
e.by = Person.objects.get(name="Aread Irector")
e.telechat_date = TelechatDate.objects.active()[0].date
e.returning_item = True
e.save()
for d in self.telechat_docs.values():
self.assertTrue(d.name in r.content)
self.assertTrue(d.title in r.content)
def test_agenda_json(self):
r = self.client.get(urlreverse("ietf.iesg.views.agenda_json"))
self.assertEquals(r.status_code, 200)
for k, d in self.telechat_docs.iteritems():
if d.type_id == "charter":
self.assertTrue(d.group.name in r.content, "%s not in response" % k)
self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k)
else:
self.assertTrue(d.name in r.content, "%s not in response" % k)
self.assertTrue(d.title in r.content, "%s title not in response" % k)
self.assertTrue(json.loads(r.content))
def test_agenda(self):
r = self.client.get(urlreverse("ietf.iesg.views.agenda"))
self.assertEquals(r.status_code, 200)
for k, d in self.telechat_docs.iteritems():
self.assertTrue(d.name in r.content, "%s not in response" % k)
self.assertTrue(d.title in r.content, "%s title not in response" % k)
def test_agenda_txt(self):
r = self.client.get(urlreverse("ietf.iesg.views.agenda_txt"))
self.assertEquals(r.status_code, 200)
for k, d in self.telechat_docs.iteritems():
if d.type_id == "charter":
self.assertTrue(d.group.name in r.content, "%s not in response" % k)
self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k)
else:
self.assertTrue(d.name in r.content, "%s not in response" % k)
self.assertTrue(d.title in r.content, "%s title not in response" % k)
def test_agenda_scribe_template(self):
r = self.client.get(urlreverse("ietf.iesg.views.agenda_scribe_template"))
self.assertEquals(r.status_code, 200)
for k, d in self.telechat_docs.iteritems():
if d.type_id == "charter":
continue # scribe template doesn't contain chartering info
self.assertTrue(d.name in r.content, "%s not in response" % k)
self.assertTrue(d.title in r.content, "%s title not in response" % k)
def test_agenda_moderator_package(self):
url = urlreverse("ietf.iesg.views.agenda_moderator_package")
login_testing_unauthorized(self, "secretary", url)
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
self.assertTrue(draft.name in r.content)
self.assertTrue(draft.title in r.content)
for k, d in self.telechat_docs.iteritems():
if d.type_id == "charter":
self.assertTrue(d.group.name in r.content, "%s not in response" % k)
self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k)
else:
self.assertTrue(d.name in r.content, "%s not in response" % k)
self.assertTrue(d.title in r.content, "%s title not in response" % k)
def test_agenda_package(self):
url = urlreverse("ietf.iesg.views.agenda_package")
login_testing_unauthorized(self, "secretary", url)
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
for k, d in self.telechat_docs.iteritems():
if d.type_id == "charter":
self.assertTrue(d.group.name in r.content, "%s not in response" % k)
self.assertTrue(d.group.acronym in r.content, "%s acronym not in response" % k)
else:
self.assertTrue(d.name in r.content, "%s not in response" % k)
self.assertTrue(d.title in r.content, "%s title not in response" % k)
class RescheduleOnAgendaTestCase(django.test.TestCase):
def test_reschedule(self):

View file

@ -38,28 +38,22 @@ from ietf.iesg import views
urlpatterns = patterns('',
(r'^telechat/.*$', 'django.views.generic.simple.redirect_to', { 'url': 'http://www.ietf.org/iesg/minutes.html' }),
(r'^decisions/(?:(?P<year>[0-9]{4})/)?$', views.review_decisions),
(r'^ann/(?:ind|new|prev)/$', 'django.views.generic.simple.redirect_to', { 'url': "/iesg/decisions/", 'permanent': True }),
(r'^agenda/$', views.agenda),
(r'^agenda/agenda.txt$', views.agenda_txt),
(r'^agenda/agenda.json$', views.agenda_json),
(r'^agenda/scribe_template.html$', views.agenda_scribe_template),
(r'^agenda/moderator_package.html$', views.agenda_moderator_package),
(r'^agenda/agenda_package.txt$', views.agenda_package),
(r'^decisions/(?:(?P<year>[0-9]{4})/)?$', views.review_decisions),
(r'^agenda/(?:(?P<date>\d{4}-\d{2}-\d{2})/)?$', views.agenda),
(r'^agenda/(?:(?P<date>\d{4}-\d{2}-\d{2})/)?agenda.txt$', views.agenda_txt),
(r'^agenda/(?:(?P<date>\d{4}-\d{2}-\d{2})/)?agenda.json$', views.agenda_json),
(r'^agenda/(?:(?P<date>\d{4}-\d{2}-\d{2})/)?scribe_template.html$', views.agenda_scribe_template),
(r'^agenda/(?:(?P<date>\d{4}-\d{2}-\d{2})/)?moderator_package.html$', views.agenda_moderator_package),
(r'^agenda/(?:(?P<date>\d{4}-\d{2}-\d{2})/)?agenda_package.txt$', views.agenda_package),
(r'^agenda/documents.txt$', views.agenda_documents_txt),
(r'^agenda/documents/$', views.agenda_documents),
(r'^agenda/telechat-(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+)-docs.tgz', views.telechat_docs_tarfile),
(r'^discusses/$', views.discusses),
(r'^milestones', views.milestones_needing_review),
(r'^milestones$', views.milestones_needing_review),
(r'^telechatdates/$', 'django.views.generic.simple.redirect_to', { 'url': '/admin/iesg/telechatdate/' }),
url(r'^wgactions/$', views.working_group_actions, name="iesg_working_group_actions"),
url(r'^wgactions/add/$', views.edit_working_group_action, { 'wga_id': None }, name="iesg_add_working_group_action"),
url(r'^wgactions/(?P<wga_id>\d+)/$', views.edit_working_group_action, name="iesg_edit_working_group_action"),
)
if settings.SERVER_MODE != 'production':
urlpatterns += patterns('',
(r'^agenda/(?P<date>\d{4}-\d\d-\d\d)/$', views.agenda),
(r'^_test/moderator_package.html$', views.agenda_moderator_package_test),
(r'^_test/agenda_package.txt', views.agenda_package_test),
)

View file

@ -36,7 +36,6 @@ import codecs, re, os, glob
import datetime
import tarfile
from django.views.generic.list_detail import object_list
from django.views.generic.simple import direct_to_template
from django.views.decorators.vary import vary_on_cookie
from django.core.urlresolvers import reverse as urlreverse
@ -51,12 +50,16 @@ from ietf.idtracker.models import IDInternal, InternetDraft, AreaGroup, Position
from ietf.iesg.models import TelechatDates, TelechatAgendaItem, WGAction
from ietf.idrfc.idrfc_wrapper import IdWrapper, RfcWrapper
from ietf.doc.utils import update_telechat
from ietf.ietfauth.decorators import group_required, role_required
from ietf.ietfauth.utils import has_role
from ietf.iesg.models import TelechatDate, TelechatAgendaItem
from ietf.ipr.models import IprDocAlias
from ietf.doc.models import Document, TelechatDocEvent, LastCallDocEvent, ConsensusDocEvent, DocEvent
from ietf.group.models import Group, GroupMilestone
from ietf.person.models import Person
from ietf.doc.utils import update_telechat
from ietf.ietfauth.utils import has_role, role_required
from ietf.iesg.agenda import get_agenda_date, agenda_data, agenda_docs, agenda_wg_actions, agenda_management_issues
def review_decisions(request, year=None):
events = DocEvent.objects.filter(type__in=("iesg_disapproved", "iesg_approved"))
@ -85,150 +88,8 @@ def review_decisions(request, year=None):
timeframe=timeframe),
context_instance=RequestContext(request))
def get_doc_section(id):
pass
def get_doc_sectionREDESIGN(doc):
if doc.type_id == 'draft':
if doc.intended_std_level_id in ["bcp", "ds", "ps", "std"]:
s = "2"
else:
s = "3"
g = doc.group_acronym()
if g and str(g) != 'none':
s = s + "1"
elif (s == "3") and doc.stream_id in ("ise","irtf"):
s = s + "3"
else:
s = s + "2"
if not doc.get_state_slug=="rfc" and doc.get_state_slug('draft-iesg') not in ("lc", "writeupw", "goaheadw", "iesg-eva", "defer"):
s = s + "3"
elif doc.returning_item():
s = s + "2"
else:
s = s + "1"
elif doc.type_id == 'charter':
s = get_wg_section(doc.group)
elif doc.type_id == 'statchg':
protocol_action = False
for relation in doc.relateddocument_set.filter(relationship__slug__in=('tops','tois','tohist','toinf','tobcp','toexp')):
if relation.relationship.slug in ('tops','tois') or relation.target.document.std_level.slug in ('std','ds','ps'):
protocol_action = True
if protocol_action:
s="23"
else:
s="33"
if doc.get_state_slug() not in ("iesgeval", "defer", "appr-pr", "appr-pend", "appr-sent"):
s = s + "3"
elif doc.returning_item():
s = s + "2"
else:
s = s + "1"
elif doc.type_id == 'conflrev':
if doc.get_state('conflrev').slug not in ('adrev','iesgeval','appr-reqnopub-pend','appr-reqnopub-sent','appr-noprob-pend','appr-noprob-sent','defer'):
s = "343"
elif doc.returning_item():
s = "342"
else:
s = "341"
return s
def get_wg_section(wg):
s = ""
charter_slug = None
if wg.charter:
charter_slug = wg.charter.get_state_slug()
if wg.state_id in ['active','dormant']:
if charter_slug in ['extrev','iesgrev']:
s = '422'
else:
s = '421'
else:
if charter_slug in ['extrev','iesgrev']:
s = '412'
else:
s = '411'
return s
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
get_doc_section = get_doc_sectionREDESIGN
def agenda_docs(date, next_agenda):
matches = Document.objects.filter(docevent__telechatdocevent__telechat_date=date).select_related("stream").distinct()
docmatches = []
for doc in matches:
if doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date != date:
continue
e = doc.latest_event(type="started_iesg_process")
doc.balloting_started = e.time if e else datetime.datetime.min
if doc.type_id == "draft":
s = doc.get_state("draft-iana-review")
if s: # and s.slug in ("not-ok", "changed", "need-rev"):
doc.iana_review_state = str(s)
if doc.get_state_slug("draft-iesg") == "lc":
e = doc.latest_event(LastCallDocEvent, type="sent_last_call")
if e:
doc.lastcall_expires = e.expires
if doc.stream_id in ("ietf", "irtf", "iab"):
doc.consensus = "Unknown"
e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
if e:
doc.consensus = "Yes" if e.consensus else "No"
elif doc.type_id=='conflrev':
doc.conflictdoc = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
docmatches.append(doc)
# Be careful to keep this the same as what's used in agenda_documents
docmatches.sort(key=lambda d: d.balloting_started)
res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4))
for k in range(1,4):
res['s34%d'%k]=[]
for id in docmatches:
section_key = "s"+get_doc_section(id)
if section_key not in res:
res[section_key] = []
res[section_key].append({'obj':id})
return res
def agenda_wg_actions(date):
res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4))
charters = Document.objects.filter(type="charter", docevent__telechatdocevent__telechat_date=date).select_related("group").distinct()
charters = charters.filter(group__state__slug__in=["proposed","active"])
for c in charters:
if c.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date != date:
continue
c.group.txt_link = settings.CHARTER_TXT_URL + "%s-%s.txt" % (c.canonical_name(), c.rev)
section_key = "s" + get_wg_section(c.group)
if section_key not in res:
res[section_key] = []
# Cleanup - Older view code wants obj, newer wants doc. Older code should be moved forward
res[section_key].append({'obj': c.group, 'doc': c})
return res
def agenda_management_issues(date):
return TelechatAgendaItem.objects.filter(type=3).order_by('id')
def _agenda_json(request, date=None):
if not date:
date = TelechatDates.objects.all()[0].date1
next_agenda = True
else:
y,m,d = date.split("-")
date = datetime.date(int(y), int(m), int(d))
next_agenda = None
def agenda_json(request, date=None):
date = get_agenda_date(date)
data = {'telechat-date':str(date),
'as-of':str(datetime.datetime.utcnow()),
@ -272,83 +133,88 @@ def _agenda_json(request, date=None):
data['sections']['6'] = {'title':"Management Issues"}
data['sections']['7'] = {'title':"Working Group News"}
docs = agenda_docs(date, next_agenda)
docs = agenda_docs(date)
for section in docs.keys():
# in case the document is in a state that does not have an agenda section
if section != 's':
s = str(".".join(list(section)[1:]))
if s[0:1] == '4':
# ignore these; not sure why they are included by agenda_docs
pass
if section == 's':
continue
s = str(".".join(list(section)[1:]))
if s[0:1] == '4':
# ignore these; not sure why they are included by agenda_docs
continue
if not docs[section]:
continue
# If needed, add a "For Action" section to agenda
if s[4:5] == '3':
data['sections'][s] = {'title':"For Action", 'docs':[]}
for d in docs[section]:
docinfo = {'docname':d.canonical_name(),
'title':d.title,
'ad':d.ad.name if d.ad else None }
if d.note:
docinfo['note'] = d.note
defer = d.active_defer_event()
if defer:
docinfo['defer-by'] = defer.by.name
docinfo['defer-at'] = str(defer.time)
if d.type_id == "draft":
docinfo['rev'] = d.rev
docinfo['intended-std-level'] = str(d.intended_std_level)
if d.rfc_number():
docinfo['rfc-number'] = d.rfc_number()
iana_state = d.get_state("draft-iana-review")
if iana_state and iana_state.slug in ("not-ok", "changed", "need-rev"):
docinfo['iana-review-state'] = str(iana_state)
if d.get_state_slug("draft-iesg") == "lc":
e = d.latest_event(LastCallDocEvent, type="sent_last_call")
if e:
docinfo['lastcall-expires'] = e.expires.strftime("%Y-%m-%d")
docinfo['consensus'] = None
e = d.latest_event(ConsensusDocEvent, type="changed_consensus")
if e:
docinfo['consensus'] = e.consensus
elif d.type_id == 'conflrev':
docinfo['rev'] = d.rev
td = d.relateddocument_set.get(relationship__slug='conflrev').target.document
docinfo['target-docname'] = td.canonical_name()
docinfo['target-title'] = td.title
docinfo['target-rev'] = td.rev
docinfo['intended-std-level'] = str(td.intended_std_level)
docinfo['stream'] = str(td.stream)
else:
if len(docs[section]) != 0:
# If needed, add a "For Action" section to agenda
if s[4:5] == '3':
data['sections'][s] = {'title':"For Action", 'docs':[]}
for obj in docs[section]:
d = obj['obj']
docinfo = {'docname':d.canonical_name(),
'title':d.title,
'ad':d.ad.name}
if d.note:
docinfo['note'] = d.note
defer = d.active_defer_event()
if defer:
docinfo['defer-by'] = defer.by.name
docinfo['defer-at'] = str(defer.time)
if d.type_id == "draft":
docinfo['rev'] = d.rev
docinfo['intended-std-level'] = str(d.intended_std_level)
if d.rfc_number():
docinfo['rfc-number'] = d.rfc_number()
iana_state = d.get_state("draft-iana-review")
if iana_state and iana_state.slug in ("not-ok", "changed", "need-rev"):
docinfo['iana-review-state'] = str(iana_state)
if d.get_state_slug("draft-iesg") == "lc":
e = d.latest_event(LastCallDocEvent, type="sent_last_call")
if e:
docinfo['lastcall-expires'] = e.expires.strftime("%Y-%m-%d")
docinfo['consensus'] = None
e = d.latest_event(ConsensusDocEvent, type="changed_consensus")
if e:
docinfo['consensus'] = e.consensus
elif d.type_id == 'conflrev':
docinfo['rev'] = d.rev
td = d.relateddocument_set.get(relationship__slug='conflrev').target.document
docinfo['target-docname'] = td.canonical_name()
docinfo['target-title'] = td.title
docinfo['target-rev'] = td.rev
docinfo['intended-std-level'] = str(td.intended_std_level)
docinfo['stream'] = str(td.stream)
else:
# XXX check this -- is there nothing to set for
# all other documents here?
pass
data['sections'][s]['docs'] += [docinfo, ]
# XXX check this -- is there nothing to set for
# all other documents here?
pass
data['sections'][s]['docs'] += [docinfo, ]
wgs = agenda_wg_actions(date)
for section in wgs.keys():
# in case the charter is in a state that does not have an agenda section
if section != 's':
s = str(".".join(list(section)[1:]))
if s[0:1] != '4':
# ignore these; not sure why they are included by agenda_wg_actions
pass
else:
if len(wgs[section]) != 0:
for obj in wgs[section]:
wg = obj['obj']
doc = obj['doc']
wginfo = {'docname': doc.canonical_name(),
'rev': doc.rev,
'wgname': doc.group.name,
'acronym': doc.group.acronym,
'ad': doc.group.ad.name}
data['sections'][s]['wgs'] += [wginfo, ]
if section == 's':
continue
s = str(".".join(list(section)[1:]))
if s[0:1] != '4':
# ignore these; not sure why they are included by agenda_wg_actions
continue
if not wgs[section]:
continue
for doc in wgs[section]:
wginfo = {'docname': doc.canonical_name(),
'rev': doc.rev,
'wgname': doc.group.name,
'acronym': doc.group.acronym,
'ad': doc.group.ad.name}
data['sections'][s]['wgs'] += [wginfo, ]
mgmt = agenda_management_issues(date)
num = 0
@ -356,83 +222,36 @@ def _agenda_json(request, date=None):
num += 1
data['sections']["6.%d" % num] = {'title':m.title}
return data
def _agenda_data(request, date=None):
if not date:
date = TelechatDates.objects.all()[0].date1
next_agenda = True
else:
y,m,d = date.split("-")
date = datetime.date(int(y), int(m), int(d))
next_agenda = None
#date = "2006-03-16"
docs = agenda_docs(date, next_agenda)
mgmt = agenda_management_issues(date)
wgs = agenda_wg_actions(date)
data = {'date':str(date), 'docs':docs,'mgmt':mgmt,'wgs':wgs}
for key, filename in {'action_items':settings.IESG_TASK_FILE,
'roll_call':settings.IESG_ROLL_CALL_FILE,
'minutes':settings.IESG_MINUTES_FILE}.items():
try:
f = codecs.open(filename, 'r', 'utf-8', 'replace')
text = f.read().strip()
f.close()
data[key] = text
except IOError:
data[key] = "(Error reading "+key+")"
return data
return HttpResponse(json.dumps(data, indent=2), mimetype='text/plain')
@vary_on_cookie
def agenda(request, date=None):
data = _agenda_data(request, date)
data = agenda_data(request, date)
data['private'] = 'private' in request.REQUEST
data['settings'] = settings
return render_to_response("iesg/agenda.html", data, context_instance=RequestContext(request))
def agenda_txt(request):
data = _agenda_data(request)
def agenda_txt(request, date=None):
data = agenda_data(request, date)
return render_to_response("iesg/agenda.txt", data, context_instance=RequestContext(request), mimetype="text/plain")
def agenda_json(request):
response = HttpResponse(mimetype='text/plain')
response.write(json.dumps(_agenda_json(request), indent=2))
return response
def agenda_scribe_template(request, date=None):
date = get_agenda_date(date)
docs = agenda_docs(date)
return render_to_response('iesg/scribe_template.html', { 'date':str(date), 'docs':docs }, context_instance=RequestContext(request) )
def agenda_scribe_template(request):
date = TelechatDates.objects.all()[0].date1
docs = agenda_docs(date, True)
return render_to_response('iesg/scribe_template.html', {'date':str(date), 'docs':docs, 'USE_DB_REDESIGN_PROXY_CLASSES': settings.USE_DB_REDESIGN_PROXY_CLASSES}, context_instance=RequestContext(request) )
def _agenda_moderator_package(request):
data = _agenda_data(request)
data['ad_names'] = [str(x) for x in IESGLogin.active_iesg()]
data['ad_names'].sort(key=lambda x: x.split(' ')[-1])
@role_required('Area Director', 'Secretariat')
def agenda_moderator_package(request, date=None):
data = agenda_data(request, date)
data['ads'] = sorted(Person.objects.filter(role__name="ad", role__group__state="active"),
key=lambda p: p.name_parts()[3])
return render_to_response("iesg/moderator_package.html", data, context_instance=RequestContext(request))
@group_required('Area_Director','Secretariat')
def agenda_moderator_package(request):
return _agenda_moderator_package(request)
def agenda_moderator_package_test(request):
if request.META['REMOTE_ADDR'] == "127.0.0.1":
return _agenda_moderator_package(request)
else:
return HttpResponseForbidden()
def _agenda_package(request):
data = _agenda_data(request)
@role_required('Area Director', 'Secretariat')
def agenda_package(request, date=None):
data = agenda_data(request)
return render_to_response("iesg/agenda_package.txt", data, context_instance=RequestContext(request), mimetype='text/plain')
@group_required('Area_Director','Secretariat')
def agenda_package(request):
return _agenda_package(request)
def agenda_package_test(request):
if request.META['REMOTE_ADDR'] == "127.0.0.1":
return _agenda_package(request)
else:
return HttpResponseForbidden()
def agenda_documents_txt(request):
dates = TelechatDates.objects.all()[0].dates()
@ -665,7 +484,7 @@ def get_possible_wg_actions():
return res
@group_required('Area_Director', 'Secretariat')
@role_required('Area Director', 'Secretariat')
def working_group_actions(request):
current_items = WGAction.objects.order_by('status_date').select_related()
@ -716,7 +535,7 @@ class EditWGActionForm(forms.ModelForm):
self.fields['telechat_date'].choices = choices
@group_required('Secretariat')
@role_required('Secretariat')
def edit_working_group_action(request, wga_id):
if wga_id != None:
wga = get_object_or_404(WGAction, pk=wga_id)

View file

@ -8,15 +8,14 @@ from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from ietf.doc.models import DocEvent, Document, BallotDocEvent, BallotPositionDocEvent, TelechatDocEvent, WriteupDocEvent, save_document_in_history
from ietf.doc.proxy import InternetDraft
from ietf.doc.utils import get_document_content, log_state_changed
from ietf.group.models import Group
from ietf.name.models import BallotPositionName
from ietf.person.models import Person
from ietf.doc.lastcall import request_last_call
from ietf.doc.mails import email_ad, email_state_changed
from ietf.iesg.models import TelechatDate, TelechatAgendaItem, WGAction
from ietf.iesg.views import _agenda_data
from ietf.iesg.models import TelechatDate, TelechatAgendaItem
from ietf.iesg.agenda import agenda_data
from forms import *
import os
@ -38,9 +37,7 @@ active_ballot_positions: takes one argument, doc. returns a dictionary with a k
NOTE: this function has been deprecated as of Datatracker 4.34. Should now use methods on the Document.
For example: doc.active_ballot().active_ad_positions()
_agenda_data: takes a request object and a date string in the format YYYY-MM-DD.
- 2012-07-28 this function was changed to return Document objects instead
of old InternetDraft wrappers
agenda_data: takes a request object and a date string in the format YYYY-MM-DD.
'''
# -------------------------------------------------
@ -55,7 +52,7 @@ def get_doc_list(agenda):
for key in sorted(agenda['docs']):
docs.extend(agenda['docs'][key])
return [x['obj'] for x in docs]
return docs
def get_doc_writeup(doc):
'''
@ -100,15 +97,12 @@ def get_section_header(file,agenda):
h3b = {'1':'Proposed for IETF Review','2':'Proposed for Approval'}
h3c = {'1':'Under Evaluation for IETF Review','2':'Proposed for Approval'}
# Robert updated _agenda_data to return Document objects instead of the ID wrapper
#doc = InternetDraft.objects.get(filename=file)
doc = Document.objects.get(name=file)
test = {'obj':doc}
for k,v in agenda['docs'].iteritems():
if test in v:
if doc in v:
section = k
count = '%s of %s' % (v.index(test) + 1, len(v))
count = '%s of %s' % (v.index(doc) + 1, len(v))
break
header = [ '%s %s' % (section[1], h1[section[1]]) ]
@ -135,7 +129,7 @@ def get_first_doc(agenda):
'''
for k,v in sorted(agenda['docs'].iteritems()):
if v:
return v[0]['obj']
return v[0]
return None
@ -144,7 +138,7 @@ def get_first_doc(agenda):
# -------------------------------------------------
def bash(request, date):
agenda = _agenda_data(request, date=date)
agenda = agenda_data(request, date=date)
return render_to_response('telechat/bash.html', {
'agenda': agenda,
@ -158,7 +152,7 @@ def doc(request, date):
displays the message "No Documents"
'''
agenda = _agenda_data(request, date=date)
agenda = agenda_data(request, date=date)
doc = get_first_doc(agenda)
if doc:
url = reverse('telechat_doc_detail', kwargs={'date':date,'name':doc.name})
@ -212,7 +206,7 @@ def doc_detail(request, date, name):
'substate':tag}
BallotFormset = formset_factory(BallotForm, extra=0)
agenda = _agenda_data(request, date=date)
agenda = agenda_data(request, date=date)
header = get_section_header(name,agenda) if name else ''
# nav button logic
@ -329,7 +323,7 @@ def doc_navigate(request, date, name, nav):
The view retrieves the appropriate document and redirects to the doc view.
'''
doc = get_object_or_404(Document, docalias__name=name)
agenda = _agenda_data(request, date=date)
agenda = agenda_data(request, date=date)
target = name
docs = get_doc_list(agenda)
@ -346,10 +340,6 @@ def doc_navigate(request, date, name, nav):
def main(request):
'''
The is the main view where the user selects an existing telechat or creates a new one.
NOTES ON EXTERNAL HELPER FUNCTIONS:
_agenda_data(): returns dictionary of agenda sections
get_ballot(name): returns a BallotWrapper and RfcWrapper or IdWrapper
'''
if request.method == 'POST':
date=request.POST['date']
@ -371,7 +361,7 @@ def management(request, date):
This view displays management issues and lets the user update the status
'''
agenda = _agenda_data(request, date=date)
agenda = agenda_data(request, date=date)
issues = TelechatAgendaItem.objects.filter(type=3).order_by('id')
return render_to_response('telechat/management.html', {
@ -396,7 +386,7 @@ def minutes(request, date):
pa_docs = [ d for d in docs if d.intended_std_level.slug not in ('inf','exp','hist') ]
da_docs = [ d for d in docs if d.intended_std_level.slug in ('inf','exp','hist') ]
agenda = _agenda_data(request, date=date)
agenda = agenda_data(request, date=date)
return render_to_response('telechat/minutes.html', {
'agenda': agenda,
@ -422,8 +412,8 @@ def new(request):
def roll_call(request, date):
agenda = _agenda_data(request, date=date)
ads = Person.objects.filter(role__name='ad')
agenda = agenda_data(request, date=date)
ads = Person.objects.filter(role__name='ad', role__group__state="active")
sorted_ads = sorted(ads, key = lambda a: a.name_parts()[3])
return render_to_response('telechat/roll_call.html', {

View file

@ -1,7 +1,7 @@
{% if section_docs %}
<ul class="doc-list">
{% for doc in section_docs %}
<li><a href="{% url telechat_doc_detail date=date name=doc.obj.name %}">{{ doc.obj.name }}</a></li>
<li><a href="{% url telechat_doc_detail date=date name=doc.name %}">{{ doc.name }}</a></li>
{% endfor %}
</ul>
{% else %}

View file

@ -65,11 +65,11 @@ div.agenda-wg { margin-left: 30px; margin-top:0.5em; margin-bottom: 0.5em; width
<h2>1. Administrivia</h2>
<div id="section1">
<h3>1.1 {% if private or user|in_group:"Area Director,IAB Chair,Secretariat" %}<a href="https://www.ietf.org/iesg/internal/rollcall.txt">Roll Call</a>{%else%}Roll Call{%endif%}</h3>
<h3>1.1 {% if private or user|has_role:"Area Director,IAB Chair,Secretariat" %}<a href="https://www.ietf.org/iesg/internal/rollcall.txt">Roll Call</a>{% else %}Roll Call{% endif %}</h3>
<h3>1.2 Bash the Agenda</h3>
<h3>1.3 Approval of the {% if private or user|in_group:"Area Director,IAB Chair,Secretariat" %}<a href="https://www.ietf.org/iesg/internal/minutes.txt">Minutes</a>{%else%}Minutes{%endif%} of Past Telechats</h3>
<h3>1.3 Approval of the {% if private or user|has_role:"Area Director,IAB Chair,Secretariat" %}<a href="https://www.ietf.org/iesg/internal/minutes.txt">Minutes</a>{%else%}Minutes{%endif%} of Past Telechats</h3>
<h3>1.4 List of Remaining Action Items from Last Telechat</h3>
<pre>
{{ action_items }}
@ -96,11 +96,11 @@ div.agenda-wg { margin-left: 30px; margin-top:0.5em; margin-bottom: 0.5em; width
<div id="section6">
{% for m in mgmt %}
<h3>6.{{forloop.counter}} {{m.title|escape}}</h3>
{% if user|in_group:"Area Director,IAB Chair,Secretariat" %}
{% if user|has_role:"Area Director,IAB Chair,Secretariat" %}
<pre>
{{m.text|wordwrap:"76"}}
</pre>
{% endif %}{# if user|in_group #}
{% endif %}{# if user|has_role #}
{% endfor %}
</div>

View file

@ -68,29 +68,26 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% endif %}<h4>{{ title3 }}</h4>
{% for doc in section_docs %}
{% if forloop.first %}
{% endif %}
<table class="agenda-doc">
<tbody>
<tr><td>
<a href="{% url doc_view name=doc.obj.name %}">{{doc.obj.name}}-{{doc.obj.rev}}</a>
<a href="http://www.ietf.org/id/{{doc.obj.name}}-{{doc.obj.rev}}.txt">[txt]</a>
<a href="{% url doc_view name=doc.name %}">{{doc.name}}-{{doc.rev}}</a>
<a href="http://www.ietf.org/id/{{doc.name}}-{{doc.rev}}.txt">[txt]</a>
<br/>{{ doc.obj.title|escape }}
<br/>{{ doc.title|escape }}
<div style="padding-left:30px;">
<a href="{% url doc_view name=doc.obj.conflictdoc.name %}">{{doc.obj.conflictdoc.name}}-{{doc.obj.conflictdoc.rev}}</a>
<a href="http://www.ietf.org/id/{{doc.obj.conflictdoc.name}}-{{doc.obj.conflictdoc.rev}}.txt">[txt]</a>
<br/>{{ doc.obj.conflictdoc.title|escape }} ({{doc.obj.conflictdoc.stream}}: {{ doc.obj.conflictdoc.intended_std_level }})
{% if doc.obj.conflictdoc.note %}
<br/>Note: {{ doc.obj.conflictdoc.note|linebreaksbr }}
<a href="{% url doc_view name=doc.conflictdoc.name %}">{{doc.conflictdoc.name}}-{{doc.conflictdoc.rev}}</a>
<a href="http://www.ietf.org/id/{{doc.conflictdoc.name}}-{{doc.conflictdoc.rev}}.txt">[txt]</a>
<br/>{{ doc.conflictdoc.title|escape }} ({{doc.conflictdoc.stream}}: {{ doc.conflictdoc.intended_std_level }})
{% if doc.conflictdoc.note %}
<br/>Note: {{ doc.conflictdoc.note|linebreaksbr }}
{% endif %}
{% if doc.obj.conflictdoc.ipr %}
{% if doc.conflictdoc.ipr %}
<br />
<h5>IPR:</h5>
<ul>
{% for ipr in doc.obj.conflictdoc.ipr %}
{% for ipr in doc.conflictdoc.ipr %}
{% ifequal ipr.ipr.status 1 %}
<li><a href="/ipr/{{ ipr.ipr.ipr_id }}/">{{ ipr.ipr.title|escape }}</a></li>
{% endifequal %}
@ -100,17 +97,16 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% endif %}
</div>
Token: {{ doc.obj.ad }}
{% with doc.obj.active_defer_event as defer %}
Token: {{ doc.ad }}
{% with doc.active_defer_event as defer %}
{% if defer %}
<br/>Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}
{% endif %}
{% endwith %}
</td><td style="padding-left:20px; width: 50px;">
{% ballot_icon doc.obj %}
{% ballot_icon doc %}
</td></tr></tbody></table>
{% if forloop.last %}
{% endif %}
{% empty %}
<p>NONE</p>
{% endfor %}

View file

@ -39,13 +39,13 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{{ title2 }}
{% endif %}{{ title3 }}
{% for doc in section_docs %}
o {{doc.obj.canonical_name}}-{{doc.obj.rev}}
{% filter wordwrap:"68"|indent|indent %}{{ doc.obj.title }}{% endfilter %}
{{doc.obj.conflictdoc.canonical_name}}-{{doc.obj.conflictdoc.rev}}
{% filter wordwrap:"66"|indent:"4" %}{{ doc.obj.conflictdoc.title }} ({{doc.obj.conflictdoc.stream}}: {{ doc.obj.conflictdoc.intended_std_level }}){% endfilter %}
{% if doc.obj.conflictdoc.note %}{# note: note is not escaped #} {% filter wordwrap:"64"|indent:"6" %}Note: {{ doc.obj.conflictdoc.note|striptags }}{% endfilter %}
{% endif %} Token: {{ doc.obj.ad }}
{% with doc.obj.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %}
o {{doc.canonical_name}}-{{doc.rev}}
{% filter wordwrap:"68"|indent|indent %}{{ doc.title }}{% endfilter %}
{{doc.conflictdoc.canonical_name}}-{{doc.conflictdoc.rev}}
{% filter wordwrap:"66"|indent:"4" %}{{ doc.conflictdoc.title }} ({{doc.conflictdoc.stream}}: {{ doc.conflictdoc.intended_std_level }}){% endfilter %}
{% if doc.conflictdoc.note %}{# note: note is not escaped #} {% filter wordwrap:"64"|indent:"6" %}Note: {{ doc.conflictdoc.note|striptags }}{% endfilter %}
{% endif %} Token: {{ doc.ad }}
{% with doc.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %}
{% empty %}
NONE
{% endfor %}

View file

@ -64,35 +64,32 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% endif %}<h4>{{ title3 }}</h4>
{% for doc in section_docs %}
{% if forloop.first %}
{% endif %}
<table class="agenda-doc">
<tbody>
<tr><td>
<a href="{% url doc_view name=doc.obj.canonical_name %}">{{doc.obj.canonical_name}}</a>
{% with doc.obj.rfc_number as rfc_number %}
<a href="{% url doc_view name=doc.canonical_name %}">{{doc.canonical_name}}</a>
{% with doc.rfc_number as rfc_number %}
{% if rfc_number %}
<a href="http://www.rfc-editor.org/rfc/rfc{{rfc_number}}/">[txt]</a>
{% else %}
<a href="http://www.ietf.org/id/{{doc.obj.name}}-{{doc.obj.rev}}.txt">[txt]</a>
<a href="http://www.ietf.org/id/{{doc.name}}-{{doc.rev}}.txt">[txt]</a>
{% endif %}
{% endwith %}
<span class="stream">{% if doc.obj.stream %} - {{ doc.obj.stream }} stream{% endif %}</span>
<span class="stream">{% if doc.stream %} - {{ doc.stream }} stream{% endif %}</span>
<br/>{{ doc.obj.title|escape }} ({{ doc.obj.intended_std_level }})
<br/>{{ doc.title|escape }} ({{ doc.intended_std_level }})
{% if doc.obj.note %}
<br/>Note: {{ doc.obj.note|linebreaksbr }}
{% if doc.note %}
<br/>Note: {{ doc.note|linebreaksbr }}
{% endif %}
{% if doc.obj.ipr %}
{% if doc.ipr %}
<br />
<h5>IPR:</h5>
<ul>
{% for ipr in doc.obj.ipr %}
{% for ipr in doc.ipr %}
{% ifequal ipr.ipr.status 1 %}
<li><a href="/ipr/{{ ipr.ipr.ipr_id }}/">{{ ipr.ipr.title|escape }}</a></li>
{% endifequal %}
@ -101,30 +98,29 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% endif %}
<br/>Token: {{ doc.obj.ad }} ({{doc.obj.area_acronym}} area)
{% with doc.obj.active_defer_event as defer %}
<br/>Token: {{ doc.ad }} ({{doc.area_acronym}} area)
{% with doc.active_defer_event as defer %}
{% if defer %}
<br/>Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}
{% endif %}
{% endwith %}
{% if doc.obj.iana_review_state %}
<br/>IANA Review: {{ doc.obj.iana_review_state }}
{% if doc.iana_review_state %}
<br/>IANA Review: {{ doc.iana_review_state }}
{% endif %}
{% if doc.obj.consensus %}
<br/>Consensus: {{ doc.obj.consensus }}
{% if doc.consensus %}
<br/>Consensus: {{ doc.consensus }}
{% endif %}
{% if doc.obj.lastcall_expires %}
<br/>Last call expires: {{ doc.obj.lastcall_expires|date:"Y-m-d" }}
{% if doc.lastcall_expires %}
<br/>Last call expires: {{ doc.lastcall_expires|date:"Y-m-d" }}
{% endif %}
</td><td style="padding-left:20px; width: 50px;">
{% ballot_icon doc.obj %}
{% ballot_icon doc %}
</td></tr></tbody></table>
{% if forloop.last %}
{% endif %}
{% empty %}
<p>NONE</p>
{% endfor %}

View file

@ -38,15 +38,15 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% if title2_first %}{% if title1_first %}{{ title1 }}{% endif %}
{{ title2 }}
{% endif %}{{ title3 }}
{% for doc in section_docs %}{% with doc.obj.rfc_number as rfc_number %}
o {{doc.obj.canonical_name}}{% if not rfc_number %}-{{doc.obj.rev}}{% endif %}{% endwith %}{% if doc.obj.stream %} - {{ doc.obj.stream }} stream{% endif %}
{% filter wordwrap:"68"|indent|indent %}{{ doc.obj.title }} ({{ doc.obj.intended_std_level }}){% endfilter %}
{% if doc.obj.note %}{# note: note is not escaped #} {% filter wordwrap:"68"|indent|indent %}Note: {{ doc.obj.note|striptags }}{% endfilter %}
{% endif %} Token: {{ doc.obj.ad }}{% if doc.obj.iana_review_state %}
IANA Review: {{ doc.obj.iana_review_state }}{% endif %}{% if doc.obj.consensus %}
Consensus: {{ doc.obj.consensus }}{% endif %}{% if doc.obj.lastcall_expires %}
Last call expires: {{ doc.obj.lastcall_expires|date:"Y-m-d" }}{% endif %}
{% with doc.obj.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %}
{% for doc in section_docs %}{% with doc.rfc_number as rfc_number %}
o {{doc.canonical_name}}{% if not rfc_number %}-{{doc.rev}}{% endif %}{% endwith %}{% if doc.stream %} - {{ doc.stream }} stream{% endif %}
{% filter wordwrap:"68"|indent|indent %}{{ doc.title }} ({{ doc.intended_std_level }}){% endfilter %}
{% if doc.note %}{# note: note is not escaped #} {% filter wordwrap:"68"|indent|indent %}Note: {{ doc.note|striptags }}{% endfilter %}
{% endif %} Token: {{ doc.ad }}{% if doc.iana_review_state %}
IANA Review: {{ doc.iana_review_state }}{% endif %}{% if doc.consensus %}
Consensus: {{ doc.consensus }}{% endif %}{% if doc.lastcall_expires %}
Last call expires: {{ doc.lastcall_expires|date:"Y-m-d" }}{% endif %}
{% with doc.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %}
{% empty %}
NONE
{% endfor %}

View file

@ -5,7 +5,7 @@ Contents:
1. Roll Call and Dial-In Instructions
https://www.ietf.org/iesg/internal/rollcall.txt
2. Agenda
http://datatracker.ietf.org/iesg/agenda/?private
https://datatracker.ietf.org/iesg/agenda/
3. Management Item Details
https://datatracker.ietf.org/cgi-bin/display_news.cgi?template_type=3
4. Previous minutes

View file

@ -37,16 +37,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<h3>{{ title2 }}</h3>
{% endif %}<h4>{{ title3 }}</h4>
{% for wg in section_wgs %}
{% for doc in section_wgs %}
<div class="agenda-wg">
<span width="30%" style="float:right;">
{% ballot_icon wg.doc %}
{% ballot_icon doc %}
</span>
<span width="30%">
<div> <a href="{{ wg.doc.get_absolute_url }}">{{ wg.doc.name}}-({{wg.doc.rev}})</a> <a href="{{ settings.CHARTER_TXT_URL }}{{ wg.doc.filename_with_rev }}">[txt]</a> </div>
<div>{{ wg.doc.group.name|escape }} ({{wg.doc.group.acronym}})</div>
<div>Area: {{ wg.doc.group.parent.acronym|upper }} ({{ wg.doc.ad|default:"Sponsoring AD not assigned" }})</div>
<div> <a href="{{ doc.get_absolute_url }}">{{ doc.name}}-({{doc.rev}})</a> <a href="{{ settings.CHARTER_TXT_URL }}{{ doc.filename_with_rev }}">[txt]</a> </div>
<div>{{ doc.group.name|escape }} ({{doc.group.acronym}})</div>
<div>Area: {{ doc.group.parent.acronym|upper }} ({{ doc.ad|default:"Sponsoring AD not assigned" }})</div>
</span>
</div>

View file

@ -34,8 +34,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% if title2_first %}{% if title1_first %}{{ title1 }}{% endif %}
{{ title2 }}
{% endif %}{{ title3 }}
{% for wg in section_wgs %}
o {{ wg.obj.name }} ({{wg.obj.acronym}})
{% for doc in section_wgs %}
o {{ doc.group.name }} ({{ doc.group.acronym }})
{% empty %}
NONE
{% endfor %}

View file

@ -40,23 +40,23 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{{ title2 }}<br>
{{ title3 }} ({{ forloop.counter }} of {{ section_docs|length }})</h3>
<div><b>{{doc.obj.name}}-{{doc.obj.rev}}</b><br>
<i>({{ doc.obj.title|escape }})</i></div>
<div><b>{{doc.name}}-{{doc.rev}}</b><br>
<i>({{ doc.title|escape }})</i></div>
<div style="padding-left:20px">
<b>{{doc.obj.conflictdoc.name}}-{{doc.obj.conflictdoc.rev}}</b><br>
<i>({{ doc.obj.conflictdoc.title|escape }})</i><br>
<b>Intended status: {{ doc.obj.conflictdoc.intended_std_level }}<br>
<b>{{doc.conflictdoc.name}}-{{doc.conflictdoc.rev}}</b><br>
<i>({{ doc.conflictdoc.title|escape }})</i><br>
<b>Intended status: {{ doc.conflictdoc.intended_std_level }}<br>
</div>
<div>Token: {{ doc.obj.ad.plain_name|escape }}<br>
{% if doc.obj.type.slug == "draft" %}
Last call ends: {{ doc.obj.most_recent_ietflc.expires.date|default:"(none)" }}
{% if doc.obj.most_recent_ietflc.expires.date|timesince_days < 3 %}!!!{% endif %}
<div>Token: {{ doc.ad.plain_name|escape }}<br>
{% if doc.type.slug == "draft" %}
Last call ends: {{ doc.most_recent_ietflc.expires.date|default:"(none)" }}
{% if doc.most_recent_ietflc.expires.date|timesince_days < 3 %}!!!{% endif %}
{% endif %}</b></div>
{% if doc.obj.active_ballot %}
{% if doc.active_ballot %}
<small><pre>
Yes No-Objection Discuss Abstain Recuse
{% for pos in doc.obj.active_ballot.all_positions %}{% if pos.old_ad %}{{pos.ad.plain_name|bracket|ljust:"22"}}{%else%}{{pos.ad.plain_name|ljust:"22"}}{%endif%} {{pos|bracketpos:"yes"}} {{pos|bracketpos:"noobj"}} {{pos|bracketpos:"discuss"}} {{pos|bracketpos:"abstain"}} {{pos|bracketpos:"recuse"}}
{% for pos in doc.active_ballot.all_positions %}{% if pos.old_ad %}{{pos.ad.plain_name|bracket|ljust:"22"}}{%else%}{{pos.ad.plain_name|ljust:"22"}}{%endif%} {{pos|bracketpos:"yes"}} {{pos|bracketpos:"noobj"}} {{pos|bracketpos:"discuss"}} {{pos|bracketpos:"abstain"}} {{pos|bracketpos:"recuse"}}
{% endfor %}
</pre></small>
@ -68,13 +68,13 @@ Last call ends: {{ doc.obj.most_recent_ietflc.expires.date|default:"(none)" }}
{% endif %}
{% if title3|startswith:"3.4.1" or title3|startswith:"3.4.2" %}
<p>Does anyone have an objection to the this conflict review response being sent to the {{doc.obj.conflictdoc.stream}}?</p>
<p>Does anyone have an objection to the this conflict review response being sent to the {{doc.conflictdoc.stream}}?</p>
{% endif %}
{% if title3|startswith:"3.4.3" %}
<p>Who will do the review of this document?</p>
{% endif %}
<p>Current State: {{ doc.obj.friendly_state }}<br>
<p>Current State: {{ doc.friendly_state }}<br>
Next State:<br>
Sub State: </p>

View file

@ -40,19 +40,19 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{{ title2 }}<br>
{{ title3 }} ({{ forloop.counter }} of {{ section_docs|length }})</h3>
<p><b>{{doc.obj.name}}-{{doc.obj.rev}}</b><br>
<i>({{ doc.obj.title|escape }})</i><br>
<b>Intended status: {{ doc.obj.intended_std_level }}<br>
Token: {{ doc.obj.ad.plain_name|escape }}<br>
{% if doc.obj.type.slug == "draft" %}
Last call ends: {{ doc.obj.most_recent_ietflc.expires.date|default:"(none)" }}
{% if doc.obj.most_recent_ietflc.expires.date|timesince_days < 3 %}!!!{% endif %}
<p><b>{{doc.name}}-{{doc.rev}}</b><br>
<i>({{ doc.title|escape }})</i><br>
<b>Intended status: {{ doc.intended_std_level }}<br>
Token: {{ doc.ad.plain_name|escape }}<br>
{% if doc.type.slug == "draft" %}
Last call ends: {{ doc.most_recent_ietflc.expires.date|default:"(none)" }}
{% if doc.most_recent_ietflc.expires.date|timesince_days < 3 %}!!!{% endif %}
{% endif %}</b></p>
{% if doc.obj.active_ballot %}
{% if doc.active_ballot %}
<small><pre>
Yes No-Objection Discuss Abstain Recuse
{% for pos in doc.obj.active_ballot.all_positions %}{% if pos.old_ad %}{{pos.ad.plain_name|bracket|ljust:"22"}}{%else%}{{pos.ad.plain_name|ljust:"22"}}{%endif%} {{pos|bracketpos:"yes"}} {{pos|bracketpos:"noobj"}} {{pos|bracketpos:"discuss"}} {{pos|bracketpos:"abstain"}} {{pos|bracketpos:"recuse"}}
{% for pos in doc.active_ballot.all_positions %}{% if pos.old_ad %}{{pos.ad.plain_name|bracket|ljust:"22"}}{%else%}{{pos.ad.plain_name|ljust:"22"}}{%endif%} {{pos|bracketpos:"yes"}} {{pos|bracketpos:"noobj"}} {{pos|bracketpos:"discuss"}} {{pos|bracketpos:"abstain"}} {{pos|bracketpos:"recuse"}}
{% endfor %}
</pre></small>
@ -69,16 +69,16 @@ Last call ends: {{ doc.obj.most_recent_ietflc.expires.date|default:"(none)" }}
{% endif %}
{% if title2|startswith:"3.1" or title2|startswith:"3.2" %}
<p>Does anyone have an[y further] objection to this document being published as an {{ doc.obj.intended_std_level }} RFC?</p>
<p>Does anyone have an[y further] objection to this document being published as an {{ doc.intended_std_level }} RFC?</p>
{% endif %}
{% if title3|startswith:"3.3.1" or title3|startswith:"3.3.2" %}
<p>Does anyone have an objection to this conflict review response being sent to the {{doc.obj.conflictdoc.stream}}?</p>
<p>Does anyone have an objection to this conflict review response being sent to the {{doc.conflictdoc.stream}}?</p>
{% endif %}
{% if title3|startswith:"3.3.3" %}
<p>Who will do the review of this document?</p>
{% endif %}
<p>Current State: {{ doc.obj.friendly_state }}<br>
<p>Current State: {{ doc.friendly_state }}<br>
Next State:<br>
Sub State: </p>

View file

@ -144,7 +144,7 @@ teleconference. The Secretariat will post them in the public archive.</p>
<h3>7. Working Group News</h3>
{% filter linebreaks_crlf %}<pre>
{% for name in ad_names %}[ ] {{ name }}
{% for ad in ads %}[ ] {{ ad.plain_name }}
{% endfor %}
</pre>{% endfilter %}

View file

@ -31,12 +31,12 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endcomment %}{% load ietf_filters %}
{% for wg in section_wgs %}
{% for doc in section_wgs %}
<h3>{{ title1 }}<br>
{{ title2 }}<br>
{{ title3 }} ({{ forloop.counter }} of {{ section_wgs|length }})</h3>
{{ title3 }} ({{ forloop.counter }} of {{ section_wgs|length }})</h3>
<p><b>{{ wg.obj.name }} ({{wg.obj.acronym}})<br>
<p><b>{{ doc.group.name }} ({{ doc.group.acronym }})<br>
{% if title3|startswith:"4.1.1" %}
<p>Does anyone have an objection to the charter being sent for

View file

@ -44,37 +44,37 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
<ul>
{% for doc in section_docs %}
<li>
{{ doc.obj.title|escape }}
<br><a href="{% url doc_view name=doc.obj.canonical_name %}">{{doc.obj.canonical_name}}</a>
<a href="http://www.ietf.org/id/{{doc.obj.canonical_name}}-{{doc.obj.rev}}.txt">[txt]</a>
{{ doc.title|escape }}
<br><a href="{% url doc_view name=doc.canonical_name %}">{{doc.canonical_name}}</a>
<a href="http://www.ietf.org/id/{{doc.canonical_name}}-{{doc.rev}}.txt">[txt]</a>
<div style="padding-left:20px">
{{ doc.obj.conflictdoc.title|escape }} ({{doc.obj.conflictdoc.stream}}: {{ doc.obj.conflictdoc.intended_std_level }})
<br><a href="{% url doc_view name=doc.obj.conflictdoc.canonical_name %}">{{doc.obj.conflictdoc.canonical_name}}</a>
<a href="http://www.ietf.org/id/{{doc.obj.conflictdoc.canonical_name}}-{{doc.obj.conflictdoc.rev}}.txt">[txt]</a>
{% if doc.obj.conflictdoc.note %}
<br>Note: {{ doc.obj.conflictdoc.note|linebreaksbr }}
{{ doc.conflictdoc.title|escape }} ({{doc.conflictdoc.stream}}: {{ doc.conflictdoc.intended_std_level }})
<br><a href="{% url doc_view name=doc.conflictdoc.canonical_name %}">{{doc.conflictdoc.canonical_name}}</a>
<a href="http://www.ietf.org/id/{{doc.conflictdoc.canonical_name}}-{{doc.conflictdoc.rev}}.txt">[txt]</a>
{% if doc.conflictdoc.note %}
<br>Note: {{ doc.conflictdoc.note|linebreaksbr }}
{% endif %}
{% for ipr in doc.obj.conflictdoc.ipr %}
{% for ipr in doc.conflictdoc.ipr %}
{% ifequal ipr.ipr.status 1 %}
<br>IPR: <a href="http://datatracker.ietf.org/ipr/{{ ipr.ipr.ipr_id }}/">{{ ipr.ipr.title|escape }}</a>
{% endifequal %}
{% endfor %}
</div>
Token: {{ doc.obj.ad.plain_name|escape }}
{% if doc.obj.active_ballot %}
<br><b>Discusses/comments</b> <a href="http://datatracker.ietf.org/idtracker/ballot/{{doc.obj.canonical_name}}/">[ballot]</a>:
Token: {{ doc.ad.plain_name|escape }}
{% if doc.active_ballot %}
<br><b>Discusses/comments</b> <a href="http://datatracker.ietf.org/idtracker/ballot/{{doc.canonical_name}}/">[ballot]</a>:
<ul>
{% for p in doc.obj.active_ballot.active_ad_positions.values %}
{% for p in doc.active_ballot.active_ad_positions.values %}
{% if p.pos %}
{% if p.discuss %}
<li>
<a href="#{{doc.obj.name}}+{{p.ad|slugify}}+discuss">{{ p.ad }}: Discuss [{{ p.discuss_time }}]</a>:
<a href="#{{doc.name}}+{{p.ad|slugify}}+discuss">{{ p.ad }}: Discuss [{{ p.discuss_time }}]</a>:
<br>{{ p.discuss }}
</li>
{% endif %}
{% if p.comment %}
<li>
<a href="#{{doc.obj.name}}+{{p.ad|slugify}}+comment">{{ p.ad }}: Comment [{{ p.comment_time }}]</a>:
<a href="#{{doc.name}}+{{p.ad|slugify}}+comment">{{ p.ad }}: Comment [{{ p.comment_time }}]</a>:
<br>{{ p.comment }}
</li>
{% endif %}

View file

@ -44,38 +44,38 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
<ul>
{% for doc in section_docs %}
<li>
{{ doc.obj.title|escape }} ({{ doc.obj.intended_std_level }})
<br><a href="{% url doc_view name=doc.obj.canonical_name %}">{{doc.obj.canonical_name}}</a>
{% with doc.obj.rfc_number as rfc_number %}
{{ doc.title|escape }} ({{ doc.intended_std_level }})
<br><a href="{% url doc_view name=doc.canonical_name %}">{{doc.canonical_name}}</a>
{% with doc.rfc_number as rfc_number %}
{% if rfc_number %}
<a href="http://www.rfc-editor.org/rfc/rfc{{rfc_number}}/">[txt]</a>
{% else %}
<a href="http://www.ietf.org/id/{{doc.obj.canonical_name}}-{{doc.obj.rev}}.txt">[txt]</a>
<a href="http://www.ietf.org/id/{{doc.canonical_name}}-{{doc.rev}}.txt">[txt]</a>
{% endif %}
{% endwith %}
<br>Token: {{ doc.obj.ad.plain_name|escape }} ({{doc.obj.area_acronym}} area)
{% if doc.obj.note %}
<br>Note: {{ doc.obj.note|linebreaksbr }}
<br>Token: {{ doc.ad.plain_name|escape }} ({{doc.area_acronym}} area)
{% if doc.note %}
<br>Note: {{ doc.note|linebreaksbr }}
{% endif %}
{% for ipr in doc.obj.ipr %}
{% for ipr in doc.ipr %}
{% ifequal ipr.ipr.status 1 %}
<br>IPR: <a href="http://datatracker.ietf.org/ipr/{{ ipr.ipr.ipr_id }}/">{{ ipr.ipr.title|escape }}</a>
{% endifequal %}
{% endfor %}
{% if doc.obj.active_ballot %}
<br><b>Discusses/comments</b> <a href="http://datatracker.ietf.org/doc/{{doc.obj.canonical_name}}/ballot/">[ballot]</a>:
{% if doc.active_ballot %}
<br><b>Discusses/comments</b> <a href="http://datatracker.ietf.org/doc/{{doc.canonical_name}}/ballot/">[ballot]</a>:
<ul>
{% for p in doc.obj.active_ballot.active_ad_positions.values %}
{% for p in doc.active_ballot.active_ad_positions.values %}
{% if p.pos %}
{% if p.discuss %}
<li>
<a href="#{{doc.obj.name}}+{{p.ad|slugify}}+discuss">{{ p.ad }}: Discuss [{{ p.discuss_time }}]</a>:
<a href="#{{doc.name}}+{{p.ad|slugify}}+discuss">{{ p.ad }}: Discuss [{{ p.discuss_time }}]</a>:
<br>{{ p.discuss|escape }}
</li>
{% endif %}
{% if p.comment %}
<li>
<a href="#{{doc.obj.name}}+{{p.ad|slugify}}+comment">{{ p.ad }}: Comment [{{ p.comment_time }}]</a>:
<a href="#{{doc.name}}+{{p.ad|slugify}}+comment">{{ p.ad }}: Comment [{{ p.comment_time }}]</a>:
<br>{{ p.comment|escape }}
</li>
{% endif %}

View file

@ -36,22 +36,22 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
{% load ietf_filters %}
<!-- ============================================================ -->
<p><b>{{ doc.obj.name }}</b></p>
<p><b>{{ doc.name }}</b></p>
{% autoescape off %}
{% if doc.obj.active_ballot %}
{% if doc.active_ballot %}
<ul>
{% for p in doc.obj.active_ballot.active_ad_positions.values %}
{% for p in doc.active_ballot.active_ad_positions.values %}
{% if p.pos and p.discuss %}
<li>
<a name="{{doc.obj.name}}+{{p.ad.plain_name|slugify}}+discuss">{{ p.ad.plain_name }}: Discuss [{{ p.discuss_time }}]</a>:
<a name="{{doc.name}}+{{p.ad.plain_name|slugify}}+discuss">{{ p.ad.plain_name }}: Discuss [{{ p.discuss_time }}]</a>:
<br><pre>{{ p.discuss|wrap_text:80|escape }}</pre>
{% endif %}
{% if p.pos and p.comment %}
<li>
<a name="{{doc.obj.name}}+{{p.ad.plain_name|slugify}}+comment">{{ p.ad.plain_name }}: Comment [{{ p.comment_time }}]</a>:
<a name="{{doc.name}}+{{p.ad.plain_name|slugify}}+comment">{{ p.ad.plain_name }}: Comment [{{ p.comment_time }}]</a>:
<br><pre>{{ p.comment|wrap_text:80|escape }}</pre>
{% endif %}
{% endfor %}
</ul>
{% endif%}
{% endautoescape %}
{% endautoescape %}