Merged in changes from Pasi, see changelog and Pasi's branch for details.

- Legacy-Id: 1464
This commit is contained in:
Henrik Levkowetz 2009-05-12 14:06:21 +00:00
parent 203d2e313f
commit bd0157c03b
24 changed files with 1158 additions and 432 deletions

View file

@ -1,3 +1,23 @@
ietfdb (2.25)
* Refactored IdRfcWrapper and lots of improvements to ID/RFC pages.
* New "Documents on Future IESG Telechat Agendas" page; some
improvements for the "IESG Discuss Positions" page.
* Improved "Sign in" dialog for new ID/RFC pages.
* Better error message if cookies are not supported when logging in.
* Include all comments (not just 15) in document comment Atom feed;
correctly sort comments on same date.
* New template tags for comparisons: greater_than/less_than/equal.
* Get YUI base URL from settings instead of hardcoding.
-- Pasi Eronen <pasi.eronen@nokia.com> 12 May 2009 14:45:17 +0200
ietfdb (2.24)
* Merged in code from Pasi for new ID/RFC search and per-document pages,
@ -15,6 +35,8 @@ ietfdb (2.24)
* Fix problem with area model in admin interface
-- Henrik Levkowetz <henrik@levkowetz.com> 26 Apr 2009 16:02:00 +0200
ietfdb (2.23)
* Fixed a wrong link in the html agenda (from Henrik)

View file

@ -8,3 +8,6 @@ def server_mode(request):
def revision_info(request):
return {'revision_time': __date__[7:32], 'revision_date': __date__[34:-3], 'revision_num': __rev__[6:-2], "revision_id": __id__[5:-2], "version_num": __version__ }
def yui_url(request):
return {'yui_url':settings.YUI_URL}

View file

@ -43,156 +43,315 @@ BALLOT_ACTIVE_STATES = ['In Last Call',
'IESG Evaluation',
'IESG Evaluation - Defer']
# A wrapper to make writing templates less painful
# Can represent either an Internet Draft, RFC, or combine both
def jsonify_helper(obj, keys):
result = {}
for k in keys:
if hasattr(obj, k):
v = getattr(obj, k)
if callable(v):
v = v()
if v == None:
pass
elif isinstance(v, (types.StringType, types.IntType, types.BooleanType, types.LongType, types.ListType)):
result[k] = v
elif isinstance(v, date):
result[k] = str(v)
else:
result[k] = 'Unknown type '+str(type(v))
return result
class IdRfcWrapper:
# avoid using these in templates
draft = None
idinternal = None
rfc = None
rfcIndex = None
# Wrappers to make writing templates less painful
# ---------------------------------------------------------------------------
class IdWrapper:
_draft = None
_idinternal = None
is_id_wrapper = True
is_rfc_wrapper = False
# Active, RFC, Expired, Replaced, etc.
document_status = None
draft_name = None
draft_revision = None
# Active/Expired/RFC/Withdrawn by Submitter/Replaced/Withdrawn by IETF
draft_status = None
# Revision is sometimes incorrect (+1 too large) if status != Active
latest_revision = None
# Set if and only if draft_status is "RFC"
rfc_number = None
title = None
rfc_number = None
revision_date = None
tracker_id = None
rfc_maturity_level = None
iesg_main_state = None
iesg_state = None
iesg_sub_state = None
iesg_state_date = None
publication_date = None
ietf_process = None
# must give either draft or rfcIndex!
def __init__(self, draft=None, rfc=None, rfcIndex=None, findRfc=False):
def __init__(self, draft):
if isinstance(draft, IDInternal):
self.idinternal = draft
self.draft = self.idinternal.draft
elif draft:
self.draft = draft
self._idinternal = draft
self._draft = self._idinternal.draft
else:
self._draft = draft
if draft.idinternal:
self.idinternal = draft.idinternal
if findRfc:
if self.draft and self.draft.rfc_number:
try:
r = Rfc.objects.get(rfc_number=self.draft.rfc_number)
ri = RfcIndex.objects.get(rfc_number=self.draft.rfc_number)
self.rfc = r
self.rfcIndex = ri
except Rfc.DoesNotExist:
pass
except RfcIndex.DoesNotExist:
pass
elif rfcIndex:
try:
r = Rfc.objects.get(rfc_number=rfcIndex.rfc_number)
self.rfc = r
except Rfc.DoesNotExist:
pass
if rfcIndex:
self.rfcIndex = rfcIndex
if rfc:
self.rfc = rfc
self.init_basic_data()
def __str__(self):
return "IdRfcWrapper:"+self.debug_data()
self._idinternal = draft.idinternal
if self._idinternal:
self.ietf_process = IetfProcessData(self._idinternal)
def init_basic_data(self):
d = self.draft
i = self.idinternal
r = self.rfcIndex
if r:
self.document_status = "RFC"
else:
self.document_status = str(d.status)
if d:
self.draft_name = d.filename
self.draft_revision = d.revision
self.title = d.title
self.revision_date = d.revision_date
self.tracker_id = d.id_document_tag
if d.rfc_number:
self.rfc_number = d.rfc_number
if i:
self.iesg_main_state = str(i.cur_state)
if i.cur_sub_state_id > 0:
self.iesg_sub_state = str(i.cur_sub_state)
self.iesg_state = self.iesg_main_state + "::" + self.iesg_sub_state
self.draft_name = self._draft.filename
self.draft_status = str(self._draft.status)
if self.draft_status == "RFC":
if self._draft.rfc_number:
self.rfc_number = self._draft.rfc_number
else:
self.iesg_sub_state = None
self.iesg_state = self.iesg_main_state
self.iesg_state_date = i.event_date
if r:
self.title = r.title
self.revision_date = r.rfc_published_date
self.rfc_number = r.rfc_number
if not d:
self.draft_name = r.draft
self.rfc_maturity_level = r.current_status
# Handle incorrect database entries
if self.is_rfc() and not self.rfc_number:
self.document_status = "Expired"
# Handle missing data
if self.is_rfc() and not self.rfc_maturity_level:
self.rfc_maturity_level = "Unknown?"
def is_rfc(self):
return (self.document_status == "RFC")
def in_iesg_tracker(self):
return (self.idinternal != None)
def ad_name(self):
if self.idinternal:
name = self.idinternal.token_name
# Some old documents have token name as "Surname, Firstname";
# newer ones have "Firstname Surname"
m = re.match(r'^(\w+), (\w+)$', name)
if m:
return m.group(2)+" "+m.group(1)
else:
return name
else:
return None
def draft_name_and_revision(self):
if self.draft_name and self.draft_revision:
return self.draft_name+"-"+self.draft_revision
else:
return None
# Handle incorrect database entries
self.draft_status = "Expired"
self.latest_revision = self._draft.revision
self.title = self._draft.title
self.tracker_id = self._draft.id_document_tag
self.publication_date = self._draft.revision_date
def rfc_editor_state(self):
try:
if self.draft:
qs = self.draft.rfc_editor_queue_state
return qs.state
qs = self._draft.rfc_editor_queue_state
return qs.state
except RfcEditorQueue.DoesNotExist:
pass
return None
def has_rfc_errata(self):
return self.rfcIndex and (self.rfcIndex.has_errata > 0)
def last_call_ends(self):
if self.iesg_main_state == "In Last Call":
return self.draft.lc_expiration_date
def replaced_by(self):
try:
if self._draft.replaced_by:
return [self._draft.replaced_by.filename]
except InternetDraft.DoesNotExist:
pass
return None
def replaces(self):
r = [str(r.filename) for r in self._draft.replaces_set.all()]
if len(r) > 0:
return r
else:
return None
def in_ietf_process(self):
return self.ietf_process != None
def file_types(self):
return self._draft.file_type.split(",")
def group_acronym(self):
if self._draft.group_id != 0 and self._draft.group != None and str(self._draft.group) != "none":
return str(self._draft.group)
else:
return None
# TODO: Returning integers here isn't nice
# 0=Unknown, 1=IETF, 2=IAB, 3=IRTF, 4=Independent
def stream_id(self):
if self.draft_name.startswith("draft-iab-"):
return 2
elif self.draft_name.startswith("draft-irtf-"):
return 3
elif self._idinternal:
if self._idinternal.via_rfc_editor > 0:
return 4
else:
return 1
elif self.group_acronym():
return 1
else:
return 0
def draft_name_and_revision(self):
return self.draft_name+"-"+self.latest_revision
def friendly_state(self):
if self.draft_status == "RFC":
return "<a href=\"/doc/rfc%d/\">RFC %d</a>" % (self.rfc_number, self.rfc_number)
elif self.draft_status == "Replaced":
rs = self.replaced_by()
if rs:
return "Replaced by <a href=\"/doc/%s/\">%s</a>" % (rs[0],rs[0])
else:
return "Replaced"
elif self.draft_status == "Active":
if self.in_ietf_process() and self.ietf_process.main_state != "Dead":
if self.ietf_process.main_state == "In Last Call":
return self.ietf_process.state + " (ends "+str(self._idinternal.document().lc_expiration_date)+")"
else:
return self.ietf_process.state
else:
return "I-D Exists"
else:
# Expired/Withdrawn by Submitter/IETF
return self.draft_status
def abstract(self):
return self._draft.abstract
# TODO: ugly hack
def authors(self):
return self._draft.authors
def expected_expiration_date(self):
if self.draft_status == "Active" and self._draft.can_expire():
return self._draft.expiration()
else:
return None
def ad_name(self):
if self.in_ietf_process():
return self.ietf_process.ad_name()
else:
return None
def to_json(self):
result = jsonify_helper(self, ['draft_name', 'draft_status', 'latest_revision', 'rfc_number', 'title', 'tracker_id', 'publication_date','rfc_editor_state', 'replaced_by', 'replaces', 'in_ietf_process', 'file_types', 'group_acronym', 'stream_id','friendly_state', 'abstract', 'ad_name'])
if self.in_ietf_process():
result['ietf_process'] = self.ietf_process.to_json_helper()
return simplejson.dumps(result, indent=2)
# ---------------------------------------------------------------------------
class RfcWrapper:
_rfc = None
_rfcindex = None
_idinternal = None
is_id_wrapper = False
is_rfc_wrapper = True
rfc_number = None
title = None
publication_date = None
maturity_level = None
ietf_process = None
def __init__(self, rfcindex, rfc=None, idinternal=None):
self._rfcindex = rfcindex
self._rfc = rfc
self._idinternal = idinternal
if not self._idinternal:
try:
self._idinternal = IDInternal.objects.get(rfc_flag=1, draft=self._rfcindex.rfc_number)
except IDInternal.DoesNotExist:
pass
if self._idinternal:
self.ietf_process = IetfProcessData(self._idinternal)
self.rfc_number = self._rfcindex.rfc_number
self.title = self._rfcindex.title
self.publication_date = self._rfcindex.rfc_published_date
self.maturity_level = self._rfcindex.current_status
if not self.maturity_level:
self.maturity_level = "Unknown"
def _rfc_doc_list(self, name):
if (not self._rfcindex) or (not self._rfcindex.__dict__[name]):
return None
else:
s = self._rfcindex.__dict__[name]
s = s.replace(",", ", ")
s = re.sub("([A-Z])([0-9])", "\\1 \\2", s)
return s
def obsoleted_by(self):
return self._rfc_doc_list("obsoleted_by")
def obsoletes(self):
return self._rfc_doc_list("obsoletes")
def updated_by(self):
return self._rfc_doc_list("updated_by")
def updates(self):
return self._rfc_doc_list("updates")
def has_errata(self):
return self._rfcindex and (self._rfcindex.has_errata > 0)
def in_ietf_process(self):
return self.ietf_process != None
def file_types(self):
# Not really correct, but the database doesn't
# have this data for RFCs yet
return [".txt"]
# TODO:
# also/bcp_number/std_number/fyi_number
# group_acronym
# ad_name
def friendly_state(self):
if self.in_ietf_process():
s = self.ietf_process.main_state
if not s in ["RFC Published", "AD is watching", "Dead"]:
return "RFC %d (%s)<br/>%s (to %s)" % (self.rfc_number, self.maturity_level, s, self.ietf_process.intended_maturity_level())
return "RFC %d (%s)" % (self.rfc_number, self.maturity_level)
def ad_name(self):
if self.in_ietf_process():
return self.ietf_process.ad_name()
else:
# TODO: get AD name of the draft
return None
def to_json(self):
result = jsonify_helper(self, ['rfc_number', 'title', 'publication_date', 'maturity_level', 'obsoleted_by','obsoletes','updated_by','updates','has_errata','file_types','in_ietf_process', 'friendly_state'])
if self.in_ietf_process():
result['ietf_process'] = self.ietf_process.to_json_helper()
return simplejson.dumps(result, indent=2)
# ---------------------------------------------------------------------------
class IetfProcessData:
_idinternal = None
main_state = None
sub_state = None
state = None
state_date = None
_ballot = None
def __init__(self, idinternal):
self._idinternal = idinternal
i = self._idinternal
self.main_state = str(i.cur_state)
if i.cur_sub_state_id > 0:
self.sub_state = str(i.cur_sub_state)
self.state = self.main_state + "::" + self.sub_state
else:
self.sub_state = None
self.state = self.main_state
self.state_date = i.event_date
def has_iesg_ballot(self):
try:
if self._idinternal.ballot.ballot_issued:
return True
except BallotInfo.DoesNotExist:
pass
return False
def has_active_iesg_ballot(self):
if not self.has_iesg_ballot():
return False
if not self.main_state in BALLOT_ACTIVE_STATES:
return False
if (not self._idinternal.rfc_flag) and self._idinternal.draft.status_id != 1:
# Active
return False
return True
# don't call this unless has_[active_]iesg_ballot returns True
def iesg_ballot(self):
if not self._ballot:
self._ballot = BallotWrapper(self._idinternal)
return self._ballot
def ad_name(self):
name = self._idinternal.token_name
# Some old documents have token name as "Surname, Firstname";
# newer ones have "Firstname Surname"
m = re.match(r'^(\w+), (\w+)$', name)
if m:
return m.group(2)+" "+m.group(1)
else:
return name
def iesg_note(self):
if self.idinternal and self.idinternal.note:
n = self.idinternal.note
if self._idinternal.note:
n = self._idinternal.note
# Hide unnecessary note of form "RFC 1234"
if re.match("^RFC\s*\d+$", n):
return None
@ -200,179 +359,121 @@ class IdRfcWrapper:
else:
return None
def iesg_ballot_approval_text(self):
def to_json_helper(self):
result = {'main_state':self.main_state,
'sub_state':self.sub_state,
'state':self.state,
'state_date':str(self.state_date),
'has_iesg_ballot':self.has_iesg_ballot(),
'has_active_iesg_ballot':self.has_active_iesg_ballot(),
'ad_name':self.ad_name(),
'intended_maturity_level':self.intended_maturity_level()}
if self.iesg_note():
result['iesg_note'] = self.iesg_note()
if self.has_iesg_ballot():
return self.idinternal.ballot.approval_text
result['iesg_ballot'] = self.iesg_ballot().to_json_helper()
return result
def intended_maturity_level(self):
if self._idinternal.rfc_flag:
s = str(self._idinternal.document().intended_status)
# rfc_intend_status table uses different names, argh!
if s == "Proposed":
s = "Proposed Standard"
elif s == "Draft":
s = "Draft Standard"
elif s == "None":
s = None
else:
return None
def iesg_ballot_writeup(self):
if self.has_iesg_ballot():
return self.idinternal.ballot.ballot_writeup
s = str(self._idinternal.draft.intended_status)
if s == "None":
s = None
elif s == "Request":
s = None
return s
# intended_maturity_level(self):
# telechat_date, on_telechat_agenda, returning_telechat_item
# state_change_notice_to?
# comment_log?
# ---------------------------------------------------------------------------
class IdRfcWrapper:
rfc = None
id = None
def __init__(self, id, rfc):
self.id = id
self.rfc = rfc
def title(self):
if self.rfc:
return self.rfc.title
else:
return None
return self.id.title
# TODO: Returning integers here isn't nice
# 0=Unknown, 1=IETF, 2=IAB, 3=IRTF, 4=Independent
def stream_id(self):
if self.draft_name:
if self.draft_name.startswith("draft-iab-"):
return 2
elif self.draft_name.startswith("draft-irtf-"):
return 3
elif self.idinternal:
if self.idinternal.via_rfc_editor > 0:
return 4
else:
return 1
g = self.group_acronym()
if g:
return 1
return 0
# Ballot exists (may be old or active one)
def has_iesg_ballot(self):
try:
if self.idinternal and self.idinternal.ballot.ballot_issued:
return True
except BallotInfo.DoesNotExist:
pass
return False
# Ballot exists and balloting is ongoing
def has_active_iesg_ballot(self):
return self.idinternal and (self.iesg_main_state in BALLOT_ACTIVE_STATES) and self.has_iesg_ballot() and self.document_status == "Active"
def iesg_ballot_id(self):
if self.has_iesg_ballot():
return self.idinternal.ballot_id
def friendly_state(self):
if self.rfc:
return self.rfc.friendly_state()
else:
return None
return self.id.friendly_state()
# Don't call unless has_iesg_ballot() returns True
def iesg_ballot_positions(self):
return create_ballot_object(self.idinternal, self.has_active_iesg_ballot())
def group_acronym(self):
if self.draft and self.draft.group_id != 0 and self.draft.group != None and str(self.draft.group) != "none":
return str(self.draft.group)
else:
if self.rfc and self.rfc.group_acronym and (self.rfc.group_acronym != 'none'):
return str(self.rfc.group_acronym)
def ad_name(self):
if self.rfc:
s = self.rfc.ad_name()
if s:
return s
if self.id:
return self.id.ad_name()
return None
def publication_date(self):
if self.rfc:
return self.rfc.publication_date
else:
return self.id.publication_date
def view_sort_group(self):
if self.is_rfc():
if self.rfc:
return 'RFC'
elif self.document_status == "Active":
elif self.id.draft_status == "Active":
return 'Active Internet-Draft'
else:
return 'Old Internet-Draft'
def view_sort_key(self):
if self.is_rfc():
x = self.rfc_number
y = self.debug_data()
if self.draft:
z = str(self.draft.status)
return "2%04d" % self.rfc_number
elif self.document_status == "Active":
return "1"+self.draft_name
else:
return "3"+self.draft_name
def friendly_state(self):
if self.is_rfc():
return "RFC - "+self.rfc_maturity_level
elif self.document_status == "Active":
if self.iesg_main_state and self.iesg_main_state != "Dead":
return self.iesg_main_state
else:
return "I-D Exists"
else:
return self.document_status
def draft_replaced_by(self):
try:
if self.draft and self.draft.replaced_by:
return [self.draft.replaced_by.filename]
except InternetDraft.DoesNotExist:
pass
return None
def draft_replaces(self):
if not self.draft:
return None
r = [str(r.filename) for r in self.draft.replaces_set.all()]
if len(r) > 0:
return r
else:
return None
# TODO: return just a text string for now
def rfc_obsoleted_by(self):
if (not self.rfcIndex) or (not self.rfcIndex.obsoleted_by):
return None
else:
return self.rfcIndex.obsoleted_by
def rfc_updated_by(self):
if (not self.rfcIndex) or (not self.rfcIndex.updated_by):
return None
else:
return self.rfcIndex.updated_by
def is_active_draft(self):
return self.document_status == "Active"
def file_types(self):
if self.draft:
return self.draft.file_type.split(",")
else:
# Not really correct, but the database doesn't
# have this data for RFCs yet
return [".txt"]
def abstract(self):
if self.draft:
return self.draft.abstract
else:
return None
def debug_data(self):
s = ""
if self.draft:
s = s + "draft("+self.draft.filename+","+str(self.draft.id_document_tag)+","+str(self.draft.rfc_number)+")"
if self.idinternal:
s = s + ",idinternal()"
if self.rfc:
s = s + ",rfc("+str(self.rfc.rfc_number)+")"
if self.rfcIndex:
s = s + ",rfcIndex("+str(self.rfcIndex.rfc_number)+")"
return s
return "2%04d" % self.rfc.rfc_number
elif self.id.draft_status == "Active":
return "1"+self.id.draft_name
else:
return "3"+self.id.draft_name
def view_sort_key_byad(self):
if self.rfc:
return "2%04d" % self.rfc.rfc_number
elif self.id.draft_status == "Active":
if self.id.in_ietf_process():
return "11%02d" % (self.id.ietf_process._idinternal.cur_state_id)
else:
return "10"
else:
return "3"
# def debug_data(self):
# s = ""
# if self.draft:
# s = s + "draft("+self.draft.filename+","+str(self.draft.id_document_tag)+","+str(self.draft.rfc_number)+")"
# if self.idinternal:
# s = s + ",idinternal()"
# if self._rfc:
# s = s + ",rfc("+str(self._rfc.rfc_number)+")"
# if self.rfcIndex:
# s = s + ",rfcIndex("+str(self.rfcIndex.rfc_number)+")"
# if self.rfc_idinternal:
# s = s + ",rfc_idinternal("+str(self.rfc_idinternal.draft_id)+")"
# return s
def to_json(self):
result = {}
for k in ['document_status', 'draft_name', 'draft_revision', 'title', 'rfc_number', 'revision_date', 'tracker_id', 'rfc_maturity_level', 'iesg_main_state', 'iesg_state', 'iesg_sub_state', 'iesg_state_date', 'is_rfc', 'in_iesg_tracker', 'ad_name', 'draft_name_and_revision','rfc_editor_state','has_rfc_errata','last_call_ends','iesg_note','iesg_ballot_approval_text', 'iesg_ballot_writeup', 'stream_id','has_iesg_ballot','has_active_iesg_ballot','iesg_ballot_id','group_acronym','friendly_state','file_types','debug_data','draft_replaced_by','draft_replaces']:
if hasattr(self, k):
v = getattr(self, k)
if callable(v):
v = v()
if v == None:
pass
elif isinstance(v, (types.StringType, types.IntType, types.BooleanType, types.LongType, types.ListType)):
result[k] = v
elif isinstance(v, date):
result[k] = str(v)
else:
result[k] = 'Unknown type '+str(type(v))
return simplejson.dumps(result, indent=2)
# def create_document_object(draft=None, rfc=None, rfcIndex=None, base=None):
# if draft:
# o['fileTypes'] = draft.file_type.split(",")
# if draft.intended_status and str(draft.intended_status) != "None":
# o['intendedStatus'] = str(draft.intended_status)
# else:
# o['intendedStatus'] = None
#
# if idinternal:
# o['stateChangeNoticeTo'] = idinternal.state_change_notice_to
# if idinternal.returning_item > 0:
@ -381,20 +482,11 @@ class IdRfcWrapper:
# o['telechatDate'] = str(idinternal.telechat_date)
# o['onTelechatAgenda'] = (idinternal.agenda > 0)
#
# if rfc:
# o['intendedStatus'] = None
# if rfcIndex:
# o['rfcUpdates'] = rfcIndex.updates
# o['rfcObsoletes'] = rfcIndex.obsoletes
# o['rfcAlso'] = rfcIndex.also
# for k in ['rfcUpdates','rfcUpdatedBy','rfcObsoletes','rfcObsoletedBy','rfcAlso']:
# if o[k]:
# o[k] = o[k].replace(",", ", ")
# o[k] = re.sub("([A-Z])([0-9])", "\\1 \\2", o[k])
# return o
# ---------------------------------------------------------------------------
class BallotWrapper:
idinternal = None
_idinternal = None
ballot = None
ballot_active = False
@ -402,11 +494,29 @@ class BallotWrapper:
position_values = ["Discuss", "Yes", "No Objection", "Abstain", "Recuse", "No Record"]
def __init__(self, idinternal, ballot_active):
self.idinternal = idinternal
def __init__(self, idinternal):
self._idinternal = idinternal
self.ballot = idinternal.ballot
self.ballot_active = ballot_active
if not idinternal.rfc_flag:
self.ballot_active = self.ballot.ballot_issued and (str(idinternal.cur_state) in BALLOT_ACTIVE_STATES) and str(idinternal.draft.status)=="Active";
else:
self.ballot_active = self.ballot.ballot_issued and (str(idinternal.cur_state) in BALLOT_ACTIVE_STATES)
def approval_text(self):
return self.ballot.approval_text
def ballot_writeup(self):
return self.ballot.ballot_writeup
def is_active(self):
return self.ballot_active
def ballot_id(self):
return self._idinternal.ballot_id
def was_deferred(self):
return self.ballot.defer
def deferred_by(self):
return self.ballot.defer_by
def deferred_date(self):
return self.ballot.defer_date
def _init(self):
try:
ads = set()
@ -429,6 +539,13 @@ class BallotWrapper:
positions.append({"ad_name":str(ad), "position":"No Record"})
self._positions = positions
def position_for_ad(self, ad_name):
pl = self.position_list()
for p in pl:
if p["ad_name"] == ad_name:
return p["position"]
return None
def position_list(self):
if not self._positions:
self._init()
@ -453,6 +570,9 @@ class BallotWrapper:
def get_texts(self):
return [p for p in self.position_list() if ('has_text' in p) and p['has_text']]
def to_json_helper(self):
return {}
def position_to_string(position):
positions = {"yes":"Yes",
"noobj":"No Objection",

View file

@ -32,18 +32,40 @@
from django import template
from ietf.idtracker.models import BallotInfo
from ietf.idrfc.idrfc_wrapper import position_to_string
from ietf.idrfc.idrfc_wrapper import position_to_string, BALLOT_ACTIVE_STATES
from ietf.idtracker.templatetags.ietf_filters import in_group, timesince_days
register = template.Library()
def get_user_adid(context):
if 'user' in context and in_group(context['user'], "iesg"):
try:
usermap = context['user'].usermap_set.all()[0]
person = usermap.person
iesglogin = person.iesglogin_set.all()[0]
adId = iesglogin.id
return adId
except:
pass
return None
def get_user_name(context):
if 'user' in context and context['user'].is_authenticated():
try:
usermap = context['user'].usermap_set.all()[0]
person = usermap.person
if person:
return str(person)
except:
pass
return None
def render_ballot_icon(context, doc):
if not doc.has_active_iesg_ballot():
return ""
ballot = BallotInfo.objects.get(ballot=doc.iesg_ballot_id())
if 'adId' in context:
adId = context['adId']
if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot():
ballot = doc._idinternal.ballot
else:
adId = None
return ""
adId = get_user_adid(context)
red = 0
green = 0
gray = 0
@ -60,10 +82,13 @@ def render_ballot_icon(context, doc):
gray = gray + 1
if adId and (p['ad'].id == adId):
my = position_to_string(p['pos'])
return render_ballot_icon2(doc.draft_name, doc.tracker_id, red,green,gray,blank,my)+"<!-- adId="+str(adId)+" my="+str(my)+"-->"
if doc.is_rfc_wrapper:
return render_ballot_icon2("rfc"+str(doc.rfc_number), doc.rfc_number, red,green,gray,blank,my)+"<!-- adId="+str(adId)+" my="+str(my)+"-->"
else:
return render_ballot_icon2(doc.draft_name, doc.tracker_id, red,green,gray,blank,my)+"<!-- adId="+str(adId)+" my="+str(my)+"-->"
def render_ballot_icon2(draft_name, tracker_id, red,green,gray,blank,my):
res = '<span class="ballot_icon_wrapper"><table class="ballot_icon" title="IESG Evaluation Record (click to show more)" onclick="showBallot(\'' + draft_name + '\',' + str(tracker_id) + ')">'
res = '<table class="ballot_icon" title="IESG Evaluation Record (click to show more)" onclick="showBallot(\'' + draft_name + '\',' + str(tracker_id) + ')">'
for y in range(3):
res = res + "<tr>"
for x in range(5):
@ -89,7 +114,7 @@ def render_ballot_icon2(draft_name, tracker_id, red,green,gray,blank,my):
else:
res = res + '<td class="'+c+'" />'
res = res + '</tr>'
res = res + '</table></span>'
res = res + '</table>'
return res
@ -108,3 +133,38 @@ def do_ballot_icon(parser, token):
return BallotIconNode(docName)
register.tag('ballot_icon', do_ballot_icon)
@register.filter
def my_position(doc, user):
user_name = get_user_name({'user':user})
if not user_name:
return None
if not in_group(user, "iesg"):
return None
if not doc.in_ietf_process():
return None
if not doc.ietf_process.has_iesg_ballot():
return None
ballot = doc.ietf_process.iesg_ballot()
return ballot.position_for_ad(user_name)
@register.filter
def state_age_colored(doc):
if not doc.in_ietf_process():
return ""
main_state = doc.ietf_process.main_state
sub_state = doc.ietf_process.sub_state
if main_state in ["Dead","AD is watching","RFC Published"]:
return ""
days = timesince_days(doc.ietf_process.state_date)
goal = 0
if sub_state == "Revised ID Needed":
goal = 30
elif main_state == "RFC Ed Queue":
goal = 60
else:
goal = 14
if days > goal:
return '<span style="padding:0 2px;font-size:85%%;background:yellow;" title="Goal is %d days">(for %d days)</span>' % (goal,days)
else:
return '<span style="font-size:85%%;">(for %d days)</span>' % (days,)

View file

@ -41,5 +41,6 @@ urlpatterns = patterns('',
(r'^(?P<name>[^/]+)/_debug.data$', views_doc.document_debug),
(r'^(?P<name>[^/]+)/_comments.data$', views_doc.document_comments),
(r'^(?P<name>[^/]+)/_ballot.data$', views_doc.document_ballot),
(r'^(?P<name>[^/]+)/_versions.data$', views_doc.document_versions)
(r'^(?P<name>[^/]+)/_versions.data$', views_doc.document_versions),
(r'^ad/(?P<name>[^/]+)/$', views_search.by_ad)
)

View file

@ -35,7 +35,7 @@ from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
from ietf.idtracker.models import InternetDraft, IETFWG, Area, IDInternal
from ietf.idrfc.models import RfcIndex, RfcEditorQueue, DraftVersions
from ietf.idrfc.idrfc_wrapper import IdRfcWrapper, BallotWrapper
from ietf.idrfc.idrfc_wrapper import BallotWrapper, IdWrapper, RfcWrapper
from ietf.idrfc import markup_txt
from ietf import settings
from django.template import RequestContext
@ -48,15 +48,15 @@ def document_debug(request, name):
if m:
rfc_number = int(m.group(1))
rfci = get_object_or_404(RfcIndex, rfc_number=rfc_number)
doc = IdRfcWrapper(rfcIndex=rfci, findRfc=True)
doc = RfcWrapper(rfci)
else:
id = get_object_or_404(InternetDraft, filename=name)
doc = IdRfcWrapper(draft=id, findRfc=True)
doc = IdWrapper(draft=id)
return HttpResponse(doc.to_json(), mimetype='text/plain')
def document_main_rfc(request, rfc_number):
rfci = get_object_or_404(RfcIndex, rfc_number=rfc_number)
doc = IdRfcWrapper(rfcIndex=rfci, findRfc=True)
doc = RfcWrapper(rfci)
info = {}
content1 = None
@ -85,7 +85,7 @@ def document_main(request, name):
if m:
return document_main_rfc(request, int(m.group(1)))
id = get_object_or_404(InternetDraft, filename=name)
doc = IdRfcWrapper(draft=id, findRfc=True)
doc = IdWrapper(id)
info = {}
stream_id = doc.stream_id()
@ -99,17 +99,19 @@ def document_main(request, name):
stream = " ("+doc.group_acronym().upper()+" WG document)"
else:
stream = " (Individual document)"
if id.status.status == "Active":
info['is_active_draft'] = True
info['type'] = "Active Internet-Draft"+stream
else:
info['is_active_draft'] = False
info['type'] = "Old Internet-Draft"+stream
info['has_pdf'] = (".pdf" in doc.file_types())
content1 = None
content2 = None
if doc.is_active_draft():
if info['is_active_draft']:
f = None
try:
try:
@ -129,7 +131,12 @@ def document_main(request, name):
context_instance=RequestContext(request));
def document_comments(request, name):
id = get_object_or_404(IDInternal, draft__filename=name)
r = re.compile("^rfc([0-9]+)$")
m = r.match(name)
if m:
id = get_object_or_404(IDInternal, rfc_flag=1, draft=int(m.group(1)))
else:
id = get_object_or_404(IDInternal, rfc_flag=0, draft__filename=name)
results = []
commentNumber = 0
for comment in id.public_comments():
@ -150,16 +157,20 @@ def document_comments(request, name):
return render_to_response('idrfc/doc_comments.html', {'comments':results}, context_instance=RequestContext(request))
def document_ballot(request, name):
id = get_object_or_404(IDInternal, draft__filename=name)
r = re.compile("^rfc([0-9]+)$")
m = r.match(name)
if m:
id = get_object_or_404(IDInternal, rfc_flag=1, draft=int(m.group(1)))
else:
id = get_object_or_404(IDInternal, rfc_flag=0, draft__filename=name)
try:
if not id.ballot.ballot_issued:
raise Http404
except BallotInfo.DoesNotExist:
raise Http404
doc = IdRfcWrapper(draft=id)
ballot = BallotWrapper(id, doc.has_active_iesg_ballot())
return render_to_response('idrfc/doc_ballot.html', {'ballot':ballot, 'doc':doc}, context_instance=RequestContext(request))
ballot = BallotWrapper(id)
return render_to_response('idrfc/doc_ballot.html', {'ballot':ballot}, context_instance=RequestContext(request))
def document_versions(request, name):
draft = get_object_or_404(InternetDraft, filename=name)
@ -172,3 +183,4 @@ def document_versions(request, name):
ov.append({"draft_name":d.filename, "revision":v.revision, "revision_date":v.revision_date})
return render_to_response('idrfc/doc_versions.html', {'versions':ov}, context_instance=RequestContext(request))

View file

@ -38,7 +38,8 @@ from django.template import RequestContext
from ietf.idtracker.models import IDState, IDStatus, IETFWG, IESGLogin, IDSubState, Area, InternetDraft, Rfc, IDInternal
from ietf.idrfc.models import RfcIndex
from ietf.idrfc.idrfc_wrapper import IdRfcWrapper
from django.http import Http404, HttpResponse
from ietf.idrfc.idrfc_wrapper import IdWrapper,RfcWrapper,IdRfcWrapper
from ietf.idindex.models import orgs
from ietf.utils import normalize_draftname
@ -186,13 +187,23 @@ def search_query(query):
if len(rfcs) >= 1:
r[3] = rfcs[0]
# TODO: require that RfcINdex is present
results = []
for res in idresults+rfcresults:
if len(res)==1:
doc = IdRfcWrapper(draft=res[0])
doc = IdRfcWrapper(IdWrapper(res[0]), None)
results.append(doc)
else:
doc = IdRfcWrapper(draft=res[1], rfc=res[2], rfcIndex=res[3])
results.append(doc)
d = None
r = None
if res[1]:
d = IdWrapper(res[1])
if res[3]:
r = RfcWrapper(res[3])
if d or r:
doc = IdRfcWrapper(d, r)
results.append(doc)
results.sort(key=lambda obj: obj.view_sort_key())
meta = {}
if maxReached:
@ -215,3 +226,27 @@ def search_main(request):
form = SearchForm()
return render_to_response('idrfc/search_main.html', {'form':form}, context_instance=RequestContext(request))
def by_ad(request, name):
ad_id = None
ad_name = None
for i in IESGLogin.objects.all():
iname = str(i).lower().replace(' ','.')
if name == iname:
ad_id = i.id
ad_name = str(i)
break
if not ad_id:
raise Http404
form = SearchForm(request.REQUEST)
if form.is_valid():
pass
form.clean_data['ad'] = ad_id
form.clean_data['activeDrafts'] = True
form.clean_data['rfcs'] = True
form.clean_data['oldDrafts'] = True
(results,meta) = search_query(form.clean_data)
results.sort(key=lambda obj: obj.view_sort_key_byad())
return render_to_response('idrfc/by_ad.html', {'form':form, 'docs':results,'meta':meta, 'ad_name':ad_name}, context_instance=RequestContext(request))

View file

@ -36,7 +36,7 @@ class DocumentComments(Feed):
return self.title(obj)
def items(self, obj):
return obj.public_comments().order_by("-date")[:15]
return obj.public_comments().order_by("-date","-id")
def item_pubdate(self, item):
time = datetime.time(*[int(t) for t in item.time.split(":")])

View file

@ -286,6 +286,18 @@ def wrap_long_lines(text):
filled += [ line.rstrip() ]
return "\n".join(filled)
@register.filter(name='greater_than')
def greater_than(x, y):
return x > int(y)
@register.filter(name='less_than')
def less_than(x, y):
return x < int(y)
@register.filter(name='equal')
def equal(x, y):
return str(x)==str(y)
# based on http://www.djangosnippets.org/snippets/847/ by 'whiteinge'
@register.filter
def in_group(user, groups):

View file

@ -65,8 +65,9 @@ urlpatterns += patterns('django.views.generic.list_detail',
urlpatterns += patterns('',
(r'^agenda/$', views.telechat_agenda),
(r'^agenda/documents.txt$', views.telechat_agenda_documents),
(r'^discusses/$', views.discusses),
(r'^agenda/documents.txt$', views.telechat_agenda_documents_txt),
(r'^agenda/documents/$', views.telechat_agenda_documents),
(r'^discusses/$', views.discusses),
(r'^ann/ind/$',views.inddocs),
(r'^ann/(?P<cat>[^/]+)/$',views.wgdocs),
)

View file

@ -41,7 +41,8 @@ from django.http import Http404, HttpResponse
from django.template import RequestContext, Context, loader
from django.shortcuts import render_to_response
from ietf.iesg.models import TelechatDates, TelechatAgendaItem, WGAction
from ietf.idrfc.idrfc_wrapper import IdRfcWrapper, BallotWrapper
from ietf.idrfc.idrfc_wrapper import BallotWrapper, IdWrapper, RfcWrapper
from ietf.idrfc.models import RfcIndex
import datetime
@ -164,7 +165,7 @@ def telechat_agenda(request, date=None):
return render_to_response('iesg/agenda.html', {'date':str(date), 'docs':docs,'mgmt':mgmt,'wgs':wgs, 'private':private}, context_instance=RequestContext(request) )
def telechat_agenda_documents(request):
def telechat_agenda_documents_txt(request):
dates = TelechatDates.objects.all()[0].dates()
docs = []
for date in dates:
@ -186,17 +187,44 @@ def discusses(request):
for p in positions:
try:
draft = p.ballot.drafts.filter(primary_flag=1)
if len(draft) > 0 and draft[0].rfc_flag:
if not -draft[0].draft_id in ids:
ids.add(-draft[0].draft_id)
try:
ri = RfcIndex.objects.get(rfc_number=draft[0].draft_id)
doc = RfcWrapper(ri)
if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot():
res.append(doc)
except RfcIndex.DoesNotExist:
# NOT QUITE RIGHT, although this should never happen
pass
if len(draft) > 0 and draft[0].draft.id_document_tag not in ids:
ids.add(draft[0].draft.id_document_tag)
doc = IdRfcWrapper(draft=draft[0])
if doc.has_active_iesg_ballot():
res.append({'doc':doc})
doc = IdWrapper(draft=draft[0])
if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot():
res.append(doc)
except IDInternal.DoesNotExist:
pass
# find discussing ads
for row in res:
ballot = BallotWrapper(row['doc'].idinternal, True)
row['discuss_positions'] = ballot.get_discuss()
return direct_to_template(request, 'iesg/discusses.html', {'docs':res})
def telechat_agenda_documents(request):
dates = TelechatDates.objects.all()[0].dates()
telechats = []
for date in dates:
matches = IDInternal.objects.filter(telechat_date=date,primary_flag=1,agenda=1)
idmatches = matches.filter(rfc_flag=0).order_by('ballot_id')
rfcmatches = matches.filter(rfc_flag=1).order_by('ballot_id')
res = {}
for id in list(idmatches)+list(rfcmatches):
section_key = "s"+get_doc_section(id)
if section_key not in res:
res[section_key] = []
if not id.rfc_flag:
w = IdWrapper(draft=id)
else:
ri = RfcIndex.objects.get(rfc_number=id.draft_id)
w = RfcWrapper(ri)
res[section_key].append(w)
telechats.append({'date':date, 'docs':res})
return direct_to_template(request, 'iesg/agenda_documents.html', {'telechats':telechats})

View file

@ -113,6 +113,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.i18n',
'ietf.context_processors.server_mode',
'ietf.context_processors.revision_info',
'ietf.context_processors.yui_url'
)
INSTALLED_APPS = (
@ -179,6 +180,9 @@ IPR_EMAIL_TO = ['ietf-ipr@ietf.org', ]
# The number of days for which a password-request URL is valid
PASSWORD_DAYS = 3
# Base URL for YUI library
YUI_URL = "https://ajax.googleapis.com/ajax/libs/yui"
# Put SECRET_KEY in here, or any other sensitive or site-specific
# changes. DO NOT commit settings_local.py to svn.
from settings_local import *

View file

@ -36,15 +36,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>{% block title %}No title{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/fonts/fonts-min.css"></link>
<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/assets/skins/sam/skin.css"></link>
<link rel="stylesheet" type="text/css" href="{{yui_url}}/2.7.0/build/fonts/fonts-min.css"></link>
<link rel="stylesheet" type="text/css" href="{{yui_url}}/2.7.0/build/assets/skins/sam/skin.css"></link>
<link rel="stylesheet" type="text/css" href="/css/base2.css"></link>
<style type="text/css">
{% block morecss %}{% endblock %}
</style>
{% block pagehead %}{% endblock %}
<script type="text/javascript">
IETF_DOCS = {};
IETF = {};
</script>
</head>
<body class="yui-skin-sam" {% block bodyAttrs %}{%endblock%}>
@ -54,9 +54,9 @@ IETF_DOCS = {};
</div>
<div id="ietf-login" style="position:absolute;top:8px;right:10px;">
{% if user.is_authenticated %}
{{ user }}&nbsp;|&nbsp;<a id="ietf-login-signout" href="{% url django.contrib.auth.views.logout %}">Sign out</a>
{{ user }}&nbsp;|&nbsp;<a id="ietf-login-signout" href="javascript:signOut();">Sign out</a>
{% else %}
<a id="ietf-login-signin" href="{% url django.contrib.auth.views.login %}">Sign in</a>
<a id="ietf-login-signin" href="javascript:signIn();">Sign in</a>
{% endif %}
</div>
@ -70,15 +70,14 @@ IETF_DOCS = {};
<td>
<div style="padding:0 8px 0 8px;">
{% block content %}
{% endblock %}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/container/container-min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/menu/menu-min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/element/element-min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/button/button-min.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/container/container-min.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/menu/menu-min.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/element/element-min.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/button/button-min.js"></script>
<script type="text/javascript">
//<![CDATA[
@ -90,9 +89,10 @@ YAHOO.util.Event.onContentReady("wgs", function () {
YAHOO.util.Event.onContentReady("search_submit_button", function () {
var oButton = new YAHOO.widget.Button("search_submit_button", {});
});
//]]>
</script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/connection/connection-min.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/connection/connection-min.js"></script>
<script type="text/javascript" src="/js/base.js"></script>
{% block scripts %}
{% endblock %}
@ -101,11 +101,45 @@ YAHOO.util.Event.onContentReady("search_submit_button", function () {
{% endblock %}
</div>
<div id="db-extras"></div>
<div id="db-extras">
<div id="signin_dlg" style="visibility:hidden;">
<form name="signin_form" method="post" action="/account/login/" onsubmit="return false;">
<div class="hd">Sign in</div>
<div class="bd">
<table>
<tr><td><label>Username:</label></td>
<td><input type="text" name="username" size="30" maxlength="30" /></td></tr>
<tr><td><label>Password:</label></td>
<td><input id="signin_password" type="password" name="password" size="30" maxlength="30" /></td></tr>
<tr><td colspan="2"><div id="signin_msg" style="color:red;"></div>
</td></tr>
<tr><td colspan="2">
<a href="/account/request/">Create an account..</a><br/>
<a href="/account/request/">I forgot my password...</a>
</td>
</tr>
</table>
<div style="text-align:right;">
<span id="signin_button1" class="yui-button yui-submit-button default">
<span class="first-child">
<button type="submit">Sign in</button>
</span>
</span>
<span id="signin_button2" class="yui-button yui-push-button">
<span class="first-child">
<button type="button">Cancel</button>
</span>
</span>
</div>
</div> <!-- bd -->
</form>
</div>
</div>
</td></tr></table>
{% include "debug.html" %}
<!-- v{{version_num}}, {{ revision_date }} -->
</body>
</html>
</body></html>

View file

@ -35,7 +35,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% load wg_menu %}
{% load ietf_filters %}
<ul>
{% if user|in_group:"IESG" %}
<li class="sect first">IESG Dashboard</li>
<li><a href="/doc/ad/{{user.first_name|lower}}.{{user.last_name|lower}}/">My Documents (as AD)</a></li>
<li><a href="/iesg/agenda/documents/">Reviews for next telechat</a></li>
<li><a href="/iesg/discusses/">Discusses</a></li>
</li>
<li class="sect">Working Groups by Area</li>
{% else %}
<li class="sect first">Working Groups by Area</li>
{% endif %}
<li><div id="wgs" class="yuimenu"><div class="bd">
<ul class="first-of-type" style="padding:0;">
@ -49,15 +58,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<li class="sect">Internet Drafts&nbsp;&amp;&nbsp;RFCs</li>
<li><a href="/doc/">Search</a></li>
<li><form action="/doc/search/" method="get"><input type="text" style="margin-left:10px; width:100px; border:1px solid #89d;" name="name"/>
<li><form action="/doc/search/" method="get" style="margin-bottom:0;"><input type="text" style="margin-left:10px; width:100px; border:1px solid #89d;" name="name"/>
<input type="hidden" name="activeDrafts" value="on"/><input type="hidden" name="rfcs" value="on"/></form></li>
<li><a href="https://datatracker.ietf.org/idst/upload.cgi">Submit a draft</a></li>
{% if user|in_group:"IESG" %}
<li class="sect">IESG only</li>
<li><a href="/iesg/discusses/">Discusses</a></li>
</li>
{% endif %}
<li class="sect">Meetings</li>
<li><a href="/meeting/agenda/">Agenda</a></li>

View file

@ -0,0 +1,61 @@
{% comment %}
Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the Nokia Corporation and/or its
subsidiary(-ies) nor the names of its contributors may be used
to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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 %}
{% extends "idrfc/base.html" %}
{% block title %}Internet-Drafts and RFCs for {{ ad_name }}
{% endblock %}
{% block content %}
<h1 style="margin-top:0;">Internet-Drafts and RFCs for {{ ad_name }}</h1>
<div id="search_results" class="search_results">
{% regroup docs by view_sort_group as grouped_docs %}
<table>
<tr><th class="doc">Document</th><th class="title">Title</th><th class="date">Date</th><th class="status" colspan="2">Status</th><th class="ad">Area Director</th></tr>
{% for doc_group in grouped_docs %}
<tr class="header"><td colspan="6">{{doc_group.grouper}}s</td></tr>
{% for doc in doc_group.list %}
{% include "idrfc/search_result_row.html" %}
{% endfor %}
{% endfor %}
</table>
</div>
{% endblock %}

View file

@ -91,9 +91,9 @@ function toggleComment(n) {
<ul class="yui-nav">
<li class="selected"><a href="#tab1"><em>Document</em></a></li>
<li><a href="#tab2"><em>Versions</em></a></li>
<li {% if not doc.has_iesg_ballot %} class="disabled" {%endif%}><a href="#tab3"><em>IESG Evaluation Record</em></a></li>
<li {% if not doc.has_iesg_ballot %} class="disabled" {%endif%}><a href="#tab4"><em>IESG Writeups</em></a></li>
<li {% if not doc.in_iesg_tracker %} class="disabled" {%endif%}><a href="#tab5"><em>IESG Comment Log</em></a></li>
<li {% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}{% else %}class="disabled" {%endif%}><a href="#tab3"><em>IESG Evaluation Record</em></a></li>
<li {% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}{%else%}class="disabled" {%endif%}><a href="#tab4"><em>IESG Writeups</em></a></li>
<li {% if not doc.in_ietf_process %} class="disabled" {%endif%}><a href="#tab5"><em>IESG Comment Log</em></a></li>
</ul>
<div class="yui-content">
@ -103,17 +103,17 @@ function toggleComment(n) {
<table id="metatable">
<tr><td style="width:18ex;">Document type:</td><td>{{ info.type|escape }}</td></tr>
<tr><td>State:</td><td>
{{ doc.friendly_state|escape }}
{% if doc.last_call_ends %} (ends {{doc.last_call_ends}}){%endif%}
{% if doc.draft_replaced_by %} by {% for rep in doc.draft_replaced_by %}<a href="/doc/{{rep}}/">{{rep}}</a> {% endfor %} {%endif %}
{{ doc.friendly_state }}
{% if doc.rfc_editor_state %}<br />RFC Editor State: {{ doc.rfc_editor_state|escape }} {% endif %}
{% if doc.replaces %}<br />Replaces {% for rep in doc.replaces %}<a href="/doc/{{rep}}/">{{rep}}</a> {% endfor %}{% endif %}
</td></tr>
<tr><td>Last updated:</td><td> {{ doc.revision_date|default:"(data missing)" }}</td></tr>
<tr><td>Responsible AD:</td><td>{{ doc.ad_name|default:"-"|escape }}</td></tr>
{% if doc.iesg_note %}<tr><td>IESG Note:</td><td>{{ doc.iesg_note|escape }}</td></tr>{% endif %}
<tr><td>Intended status:</td><td>{% if doc.in_ietf_process %}{{ doc.ietf_process.intended_maturity_level|default:"-" }}{% else %}-{%endif%}</td></tr>
<tr><td>Last updated:</td><td> {{ doc.publication_date|default:"(data missing)" }}</td></tr>
<tr><td>Responsible AD:</td><td>{% if doc.in_ietf_process %}{{ doc.ietf_process.ad_name|default:"-"|escape }}{%else%}-{%endif%}</td></tr>
{% if doc.in_ietf_process and doc.ietf_process.iesg_note %}<tr><td>IESG Note:</td><td>{{ doc.ietf_process.iesg_note|escape }}</td></tr>{% endif %}
{% if doc.is_active_draft %}
{% ifequal doc.draft_status "Active" %}
<tr><td>Other versions:</td><td>
<a href="http://www.ietf.org/internet-drafts/{{doc.draft_name_and_revision}}.txt" target="_blank">plain text</a>
{% for ext in doc.file_types %}
@ -125,12 +125,8 @@ function toggleComment(n) {
<a href="http://tools.ietf.org/pdf/{{doc.draft_name_and_revision}}.pdf" target="_blank">pdf</a>
{% endif %}
</td></tr>
{% else %}
{% endif %}
{% endifequal %}
{% comment %}
{% if doc.replaces %}<br />Replaces {% for rep in doc.replaces %}<a href="/doc/{{rep}}/">{{rep}}</a> {% endfor %}{% endif %}
{% endcomment %}
</table>
<div style="padding-top:6px;padding-bottom:6px;">
@ -138,7 +134,7 @@ function toggleComment(n) {
<span class="mybutton"><a href="http://www.fenron.com/~fenner/ietf/deps/index.cgi?dep={{doc.draft_name}}" rel="nofollow" target="_blank">Dependencies to this draft</a></span> &nbsp;
<span class="mybutton"><a href="https://datatracker.ietf.org/ipr/search/?option=document_search&amp;id_document_tag={{doc.tracker_id}}" rel="nofollow" target="_blank">IPR Disclosures</a></span> &nbsp;
<span class="mybutton"><a href="http://tools.ietf.org/idnits?url=http://tools.ietf.org/id/{{doc.draft_name_and_revision}}.txt" rel="nofollow" target="_blank">Check nits</a></span> &nbsp;
{% if doc.in_iesg_tracker %}
{% if doc.in_ietf_process %}
<span class="mybutton"><a href="https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=view_id&amp;dTag={{doc.tracker_id}}" rel="nofollow" target="_blank">Edit state (IESG Tracker)</a></span>
{% else %}
<span class="mybutton"><a href="https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=add_id_confirm&amp;dTag={{doc.tracker_id}}&amp;rfc_flag=0&amp;ballot_id=0" rel="nofollow" target="_blank">Add to IESG Tracker</a></span>
@ -155,7 +151,7 @@ function toggleComment(n) {
<div id="tab3">
<div id="doc_ballot" style="display:none;">
{% if doc.has_iesg_ballot %}
{% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}
<div style="position:absolute;right:0px;">
<span id="doc_ballot_button" class="yui-button yui-link-button"><span class="first-child">
<a href="https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=open_ballot&amp;id_document_tag={{doc.tracker_id}}">Edit position</a>
@ -168,17 +164,17 @@ function toggleComment(n) {
<div id="tab4">
<div id="doc_writeup" style="display:none;">
{% if doc.has_iesg_ballot %}
{% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}
<div style="position:absolute;right:0px;">
<span id="doc_writeup_edit_button" class="yui-button yui-link-button"><span class="first-child">
<a href="https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=ballot_writeup&amp;filename={{doc.draft_filename}}&amp;ballot_id={{doc.iesg_ballot_id}}">Edit writeups</a>
<a href="https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=ballot_writeup&amp;filename={{doc.draft_filename}}&amp;ballot_id={{doc.ietf_process.iesg_ballot.ballot_id}}">Edit writeups</a>
</span></span></div>
---- following is a DRAFT of message to be sent AFTER approval ---
<pre>
{{ doc.iesg_ballot_approval_text|escape|urlize }}
{{ doc.ietf_process.iesg_ballot.approval_text|escape|urlize }}
</pre>
<pre>
{{ doc.iesg_ballot_writeup|escape|urlize }}
{{ doc.ietf_process.iesg_ballot.ballot_writeup|escape|urlize }}
</pre>
{% endif %}
</div>
@ -193,7 +189,7 @@ function toggleComment(n) {
</div> <!-- mytabs -->
<div id="rfcText1">
{% if doc.is_active_draft %}
{% ifequal doc.draft_status "Active" %}
<div class="markup_draft">
{{ content1 }}
</div>
@ -204,7 +200,7 @@ function toggleComment(n) {
<p style="max-width: 400px;"><b>Abstract:</b><br/> {{ doc.abstract|escape }}</p>
<p><b>Authors:</b><br/>
{% for author in doc.draft.authors.all %}
{% for author in doc.authors.all %}
{% if author.email %}
<a href="mailto:{{ author.email }}">{{ author.person }} &lt;{{author.email}}&gt;</a>
@ -220,12 +216,12 @@ Missing author info #{{ author.person_id }}
<p>(Note: The e-mail addresses provided for the authors of this Internet-Draft may no longer be valid)</p>
{% endif %}
{% endifequal %}
</div> <!-- rfcText1 -->
{% endblock %}
{% block scripts %}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/tabview/tabview-min.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/tabview/tabview-min.js"></script>
<script type="text/javascript">
//<![CDATA[
function loadX(element, url) {
@ -251,13 +247,13 @@ document.getElementById('rfcText2').style.display = 'none';
document.getElementById('doc_versions').style.display = 'block';
loadX("doc_versions", '/doc/{{doc.draft_name}}/_versions.data');
{% if doc.has_iesg_ballot %}
{% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}
document.getElementById('doc_ballot').style.display = 'block';
loadX("doc_ballot_content", '/doc/{{doc.draft_name}}/_ballot.data');
document.getElementById('doc_writeup').style.display = 'block';
{% endif %}
{% if doc.in_iesg_tracker %}
{% if doc.in_ietf_process %}
document.getElementById('doc_comments').style.display = 'block';
loadX("doc_comments", '/doc/{{doc.draft_name}}/_comments.data');
{% endif %}
@ -268,10 +264,10 @@ loadX("doc_comments", '/doc/{{doc.draft_name}}/_comments.data');
{% block content_end %}
<div id="rfcText2">
{% if doc.is_active_draft %}
{% ifequal doc.draft_status "Active" %}
<div class="markup_draft">
{{ content2 }}
</div>
{% endif %}
{% endifequal %}
</div>
{% endblock %}

View file

@ -91,11 +91,9 @@ function toggleComment(n) {
<ul class="yui-nav">
<li class="selected"><a href="#tab1"><em>Document</em></a></li>
<li><a href="#tab2"><em>Versions</em></a></li>
{%comment %}
<li {% if not doc.has_iesg_ballot %} class="disabled" {%endif%}><a href="#tab3"><em>IESG Evaluation Record</em></a></li>
<li {% if not doc.has_iesg_ballot %} class="disabled" {%endif%}><a href="#tab4"><em>IESG Writeups</em></a></li>
<li {% if not doc.in_iesg_tracker %} class="disabled" {%endif%}><a href="#tab5"><em>IESG Comment Log</em></a></li>
{% endcomment %}
<li {% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}{%else%} class="disabled" {%endif%}><a href="#tab3"><em>IESG Evaluation Record</em></a></li>
<li {% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}{%else%} class="disabled" {%endif%}><a href="#tab4"><em>IESG Writeups</em></a></li>
<li {% if not doc.in_ietf_process %} class="disabled" {%endif%}><a href="#tab5"><em>IESG Comment Log</em></a></li>
</ul>
<div class="yui-content">
@ -103,8 +101,13 @@ function toggleComment(n) {
<div id="metabox">
<table id="metatable">
<tr><td style="width:18ex;">Document type:</td><td>RFC - {{ doc.rfc_maturity_level }}</td></tr>
<tr><td>Published:</td><td> {{ doc.revision_date|default:"(data missing)" }}</td></tr>
<tr><td style="width:18ex;">Document type:</td><td>RFC - {{ doc.maturity_level }}
{% if doc.obsoleted_by %}<br />Obsoleted by {{ doc.obsoleted_by }}{%endif %}
{% if doc.updated_by %}<br />Updated by {{ doc.updated_by }}{%endif %}
{% if doc.obsoletes %}<br />Obsoletes {{ doc.obsoletes }}{%endif %}
{% if doc.updates %}<br />Updates {{ doc.updates }}{%endif %}
</td></tr>
<tr><td>Published:</td><td> {{ doc.publication_date|default:"(data missing)" }}</td></tr>
</table>
</div>
@ -116,6 +119,43 @@ Foo
</div>
</div>
<div id="tab3">
<div id="doc_ballot" style="display:none;">
{% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}
<div style="position:absolute;right:0px;">
<span id="doc_ballot_button" class="yui-button yui-link-button"><span class="first-child">
<a href="https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=open_ballot&amp;id_document_tag={{doc.rfc_number}}">Edit position</a>
</span></span>
</div>
{% endif %}
<div id="doc_ballot_content"></div>
</div>
</div>
<div id="tab4">
<div id="doc_writeup" style="display:none;">
{% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}
<div style="position:absolute;right:0px;">
<span id="doc_writeup_edit_button" class="yui-button yui-link-button"><span class="first-child">
<a href="https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=ballot_writeup&amp;ballot_id={{doc.ietf_process.iesg_ballot.ballot_id}}">Edit writeups</a>
</span></span></div>
---- following is a DRAFT of message to be sent AFTER approval ---
<pre>
{{ doc.ietf_process.iesg_ballot.approval_text|escape|urlize }}
</pre>
<pre>
{{ doc.ietf_process.iesg_ballot.ballot_writeup|escape|urlize }}
</pre>
{% endif %}
</div>
</div>
<div id="tab5">
<div id="doc_comments" style="display:none;">
</div>
</div>
</div> <!-- yui-content -->
</div> <!-- mytabs -->
@ -127,7 +167,7 @@ Foo
{% endblock %}
{% block scripts %}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/tabview/tabview-min.js"></script>
<script type="text/javascript" src="{{yui_url}}/2.7.0/build/tabview/tabview-min.js"></script>
<script type="text/javascript">
//<![CDATA[
function loadX(element, url) {
@ -151,8 +191,17 @@ document.getElementById('rfcText1').style.display = 'none';
document.getElementById('rfcText2').style.display = 'none';
} });
//document.getElementById('doc_versions').style.display = 'block';
//loadX("doc_versions", '/doc/{{doc.draft_name}}/_versions.data');
{% if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot %}
document.getElementById('doc_ballot').style.display = 'block';
loadX("doc_ballot_content", '/doc/rfc{{doc.rfc_number}}/_ballot.data');
document.getElementById('doc_writeup').style.display = 'block';
{% endif %}
{% if doc.in_ietf_process %}
document.getElementById('doc_comments').style.display = 'block';
loadX("doc_comments", '/doc/rfc{{doc.rfc_number}}/_comments.data');
{% endif %}
//]]>
</script>

View file

@ -36,22 +36,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% load ballot_icon %}
<tr class="{% cycle oddrow,evenrow %}">
<td class="doc">
{% if doc.is_rfc %}<a href="/doc/rfc{{doc.rfc_number}}/">RFC {{doc.rfc_number}}</a>
{% if doc.draft_name %}<br />(<a href="/doc/{{doc.draft_name}}/">{{doc.draft_name}}</a>){%endif%}
{% else %}<a href="/doc/{{doc.draft_name}}/">{{doc.draft_name_and_revision}}</a>{% endif %}</td>
{% if doc.rfc %}<a href="/doc/rfc{{doc.rfc.rfc_number}}/">RFC {{doc.rfc.rfc_number}}</a>
{% if doc.id %}<br />(<a href="/doc/{{doc.id.draft_name}}/">{{doc.id.draft_name}}</a>){%endif%}
{% else %}<a href="/doc/{{doc.id.draft_name}}/">{{doc.id.draft_name_and_revision}}</a>{% endif %}</td>
<td class="title">{{ doc.title|escape }}</td>
<td class="date">{{ doc.revision_date }}</td>
<td class="date">{{ doc.publication_date }}
{% if doc.publication_date|timesince_days|less_than:"14" %}<br/><span style="padding:0 2px;background:yellow;font-size:85%;">new</span>{%endif%}
{% if doc.id and doc.id.expected_expiration_date and doc.id.expected_expiration_date|timesince_days|greater_than:"-14" %}<br/><span style="padding:0 2px;font-size:85%;background:yellow;">expires soon</span>{%endif%}
</td>
<td class="status">{{ doc.friendly_state|escape }}
{% if doc.is_rfc %}
{% if doc.has_rfc_errata %}<br /><a href="http://www.rfc-editor.org/errata_search.php?rfc={{doc.rfc_number}}" rel="nofollow" target="_blank">Errata</a>{% endif %}
{% if not doc.rfc %}{{ doc.id|state_age_colored }}{% endif %}
{% if doc.rfc %}
{% if doc.rfc.obsoleted_by %}<br />Obsoleted by {{ doc.rfc.obsoleted_by }}{%endif %}
{% if doc.rfc.updated_by %}<br />Updated by {{ doc.rfc.updated_by }}{%endif %}
{% if doc.rfc.has_errata %}<br /><a href="http://www.rfc-editor.org/errata_search.php?rfc={{doc.rfc.rfc_number}}" rel="nofollow" target="_blank">Errata</a>{% endif %}
{% else %}
{% if doc.draft_replaced_by %} by {% for rep in doc.draft_replaced_by %}<a href="/doc/{{rep}}/">{{rep}}</a> {% endfor %} {%endif %}
{% if doc.last_call_ends %} (ends {{doc.last_call_ends}}){%endif%}
{% if doc.rfc_editor_state %}<br />RFC Editor State: {{ doc.rfc_editor_state|escape }}{% endif %}
{% if doc.id.rfc_editor_state %}<br />RFC Editor State: {{ doc.id.rfc_editor_state|escape }}{% endif %}
{% endif %}
</td>
<td class="ballot">{% ballot_icon doc %}</td>
<td class="ballot">
{% if doc.rfc and doc.rfc.in_ietf_process and doc.rfc.ietf_process.has_active_iesg_ballot %}{% ballot_icon doc.rfc %}{% else %}{% if doc.id %}{% ballot_icon doc.id %}{%endif%}{%endif%}</td>
<td class="ad">{% if doc.ad_name %}{{ doc.ad_name|escape }}{% else %}&nbsp;{% endif %}</td>
</tr>

View file

@ -0,0 +1,113 @@
{% comment %}
Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the Nokia Corporation and/or its
subsidiary(-ies) nor the names of its contributors may be used
to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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 %}
{% extends "idrfc/base.html" %}
{% load ballot_icon %}
{% load ietf_filters %}
{% block title %}Documents on Future IESG Telechat Agendas
{% endblock %}
{% block morecss %}
.agenda_docs tr.oddrow {background-color: #EDF5FF; }
.agenda_docs tr.header.telechat_date { margin-top:10px; background:#2647A0; color: white;}
.agenda_docs tr.header.telechat_date td { font-size: 125%; }
.agenda_docs tr.header + tr.header { border-top: 2px solid white;}
{% endblock %}
{% block content %}
<h1 style="margin-top:0;">Documents on Future IESG Telechat Agendas</h1>
<div class="search_results agenda_docs">
<table>
{% for t in telechats %}
{% if not forloop.first %}
<tr class="header"><td colspan="5">&nbsp;</td></tr>
{% endif %}
<tr class="header telechat_date"><td colspan="5">IESG telechat {{t.date}}</td></tr>
<tr class="header"><td colspan="5">2. Protocol Actions</td></tr>
<tr class="header"><td colspan="5">2.1 WG Submissions</td></tr>
{% for doc in t.docs.s211 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s212 %}<tr class="header"><td colspan="5">2.1.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s212 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s213 %}<tr class="header"><td colspan="5">2.1.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s213 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="5">2.2 Individual Submissions</td></tr>
{% for doc in t.docs.s221 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s222 %}<tr class="header"><td colspan="5">2.2.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s222 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s223 %}<tr class="header"><td colspan="5">2.2.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s223 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="5">3. Document Actions</td></tr>
<tr class="header"><td colspan="5">3.1 WG Submissions</td></tr>
{% for doc in t.docs.s311 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s312 %}<tr class="header"><td colspan="5">3.1.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s312 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s313 %}<tr class="header"><td colspan="5">3.1.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s313 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="5">3.2 Individual Submissions Via AD</td></tr>
{% for doc in t.docs.s321 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s322 %}<tr class="header"><td colspan="5">3.2.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s322 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s323 %}<tr class="header"><td colspan="5">3.2.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s323 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
<tr class="header"><td colspan="5">3.3 Independent Submissions Via RFC Editor</td></tr>
{% for doc in t.docs.s331 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s332 %}<tr class="header"><td colspan="5">3.3.2 Returning Item</td></tr>{% endif %}
{% for doc in t.docs.s332 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% if t.docs.s333 %}<tr class="header"><td colspan="5">3.3.3 For Action</td></tr>{% endif %}
{% for doc in t.docs.s333 %}{% include "iesg/agenda_documents_row.html" %}{%endfor%}
{% endfor %}
</table>
</div>
{% endblock %}

View file

@ -0,0 +1,66 @@
{% comment %}
Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the Nokia Corporation and/or its
subsidiary(-ies) nor the names of its contributors may be used
to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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 ballot_icon %}
{% load ietf_filters %}
<tr
{% if user|in_group:"IESG" %}
{% if doc|my_position:user|equal:"Discuss" %}style="background:#ffa0a0;"{% endif %}
{% if doc|my_position:user|equal:"Yes" or doc|my_position:user|slugify|equal:"no-objection" %}style="background:#a0ffa0;"{% endif %}
{% if doc|my_position:user|equal:"Abstain" or doc|my_position:user|equal:"Recuse" %}style="background:#c0c0c0;"{% endif %}
{% endif %}
>
<td class="doc">
{% if doc.is_rfc_wrapper %}<a href="/doc/rfc{{doc.rfc_number}}/">RFC {{doc.rfc_number}}</a>
{% else %}<a href="/doc/{{doc.draft_name}}/">{{doc.draft_name_and_revision}}</a>{% endif %}
{% if doc.ietf_process.iesg_ballot.was_deferred %}
<br/><b title="deferred by {{ doc.ietf_process.iesg_ballot.deferred_by}}">(deferred on {{doc.ietf_process.iesg_ballot.deferred_date }})</b>
{% endif %}
</td>
<td class="title">{{ doc.title|escape }}</td>
<td class="status">{{ doc.friendly_state }}
<br/>Intended status: {{doc.ietf_process.intended_maturity_level}}
{% if doc.is_rfc_wrapper %}
{% if doc.has_errata %}<br /><a href="http://www.rfc-editor.org/errata_search.php?rfc={{doc.rfc_number}}" rel="nofollow" target="_blank">Errata</a>{% endif %}
{% else %}
{% if doc.rfc_editor_state %}<br />RFC Editor State: {{ doc.rfc_editor_state|escape }}{% endif %}
{% endif %}
</td>
<td class="ballot">{% ballot_icon doc %}</td>
<td class="ad">{% if doc.ad_name %}{{ doc.ad_name|escape }}{% else %}&nbsp;{% endif %}</td>
</tr>

View file

@ -40,30 +40,73 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endblock %}
{% block morecss %}
.discuss_hidden {display:none;}
{% endblock %}
{% block content %}
<h1 style="margin-top:0;">IESG Discuss Positions</h1>
{% if user|in_group:"IESG" %}
<div id="discuss_show1" style="display:block;">
<a href="javascript:show_only_mine()">Show only my discusses</a>
</div>
<div id="discuss_show2" style="display:none;">
<a href="javascript:show_all()">Show all discusses (currently showing only mine)</a>
</div>
<div style="padding-top:4px;"></div>
{% endif %}
<div class="search_results">
<table>
<table id="discuss_table">
<tr><th class="doc">Document</th><th class="status" colspan="2">Status</th><th class="ad">Area Director</th><th>Discusses</th></tr>
{% for row in docs %}
<tr class="{% cycle oddrow,evenrow %}">
{% for doc in docs %}
<tr {% if user|in_group:"IESG" %}{% if doc|my_position:user|equal:"Discuss" %}
class="discuss_my" {% else %} class="discuss_not_my" {% endif %}{% endif %}>
<td class="doc">
<a href="/doc/{{row.doc.draft_name}}/">{{row.doc.draft_name_and_revision}}</a>
{% if doc.is_rfc_wrapper %}
<a href="/doc/rfc{{doc.rfc_number}}/">RFC {{doc.rfc_number}}</a>
{% else %}
<a href="/doc/{{doc.draft_name}}/">{{doc.draft_name_and_revision}}</a>
{% endif %}
</td>
<td class="status">{{ row.doc.friendly_state|escape }}</td>
<td class="ballot">{% ballot_icon row.doc %}</td>
<td class="ad">{% if row.doc.ad_name %}{{ row.doc.ad_name|escape }}{% else %}&nbsp;{% endif %}</td>
<td class="status">{{ doc.friendly_state }}</td>
<td class="ballot">{% ballot_icon doc %}</td>
<td class="ad">{% if doc.ad_name %}{{ doc.ad_name|escape }}{% else %}&nbsp;{% endif %}</td>
<td>
{% for po in row.discuss_positions %}
{{po.ad_name}} ({% if po.discuss_date %}{{po.discuss_date|timesince_days}}{%endif%} days ago for -{{po.discuss_revision}})<br/>
{% endfor %}</td>
{% for po in doc.ietf_process.iesg_ballot.get_discuss %}
{{po.ad_name}} ({% if po.discuss_date %}{{po.discuss_date|timesince_days}}{%endif%} days ago{% if doc.is_id_wrapper %}{% ifnotequal po.discuss_revision doc.latest_revision %} for -{{po.discuss_revision}}{% endifnotequal %}{% endif %})<br/>
{% endfor %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
{% block scripts %}
<script type="text/javascript">
//<![CDATA[
function show_only_mine() {
document.getElementById("discuss_show2").style.display = 'block';
document.getElementById("discuss_show1").style.display = 'none';
var els = YAHOO.util.Dom.getElementsByClassName("discuss_not_my","tr");
var i;
for (i =0; i < els.length; i++) {
YAHOO.util.Dom.addClass(els[i], "discuss_hidden");
}
}
function show_all() {
document.getElementById("discuss_show1").style.display = 'block';
document.getElementById("discuss_show2").style.display = 'none';
var els = YAHOO.util.Dom.getElementsByClassName("discuss_not_my","tr");
var i;
for (i =0; i < els.length; i++) {
YAHOO.util.Dom.removeClass(els[i], "discuss_hidden");
}
}
//]]>
</script>
{% endblock %}

View file

@ -7,7 +7,9 @@
<h1>Log In</h1>
{% if form.has_errors %}
<p>Your username and password didn't match our records. Please try again.</p>
{% for error in form.username.errors %}
{{ error }}<br/>
{% endfor %}
{% endif %}
<form method="post" action=".">

View file

@ -78,7 +78,7 @@ form#search_form { padding-top: 4px; padding-bottom: 4px; }
/* checkboxes for document types */
#search_form table#search_types { border-collapse:collapse;}
#search_form #search_types td { padding:0; }
#search_form #search_types td input { margin-left: 0; width:14px;}
#search_form #search_types td input { margin-left: 0; width:14px; border:0;}
/* give checkbox a fixed width so that IE6 aligns the left edge correctly */
#search_form #id_filename,
@ -106,8 +106,7 @@ form#search_form { padding-top: 4px; padding-bottom: 4px; }
.search_results th.ad, .search_results td.ad { white-space:nowrap; min-width: 6em; }
.search_results td.ballot { border-left: hidden; }
.ballot_icon_wrapper { font-size: 4pt; line-height: 0.1; color: black; }
table.ballot_icon { empty-cells: show; padding: 0; border-spacing: 0; border: 1px solid black; border-collapse: collapse; table-layout:fixed; min-width:35px;}
table.ballot_icon { empty-cells: show; padding: 0; border-spacing: 0; border: 1px solid black; border-collapse: collapse; table-layout:fixed; min-width:35px; background:white; }
table.ballot_icon td { border: 1px solid black; height: 7px; width: 6px; padding: 0;}
td.ballot_icon_green { background:#80ff80; }
td.ballot_icon_red { background: #c00000; color: yellow; }

View file

@ -33,32 +33,32 @@
function showBallot(draftName, trackerId) {
var handleEditPosition = function() {
IETF_DOCS.ballotDialog.hide();
IETF.ballotDialog.hide();
var tid = document.getElementById("doc_ballot_dialog_id").innerHTML;
window.open("https://datatracker.ietf.org/cgi-bin/idtracker.cgi?command=open_ballot&id_document_tag="+tid);
};
var handleClose = function() {
IETF_DOCS.ballotDialog.hide();
IETF.ballotDialog.hide();
};
var el;
if (!IETF_DOCS.ballotDialog) {
if (!IETF.ballotDialog) {
el = document.createElement("div");
el.innerHTML = '<div id="doc_ballot_dialog" class="mydialog" style="visibility:hidden;"><div class="hd">Positions for <span id="doc_ballot_dialog_name">draft-ietf-foo-bar</span><span id="doc_ballot_dialog_id" style="display:none;"></span></div><div class="bd"> <div id="doc_ballot_dialog_12" style="overflow-y:scroll; height:500px;"></div> </div></div>';
document.getElementById("db-extras").appendChild(el);
var buttons = [{text:"Close", handler:handleClose, isDefault:true}];
buttons.unshift({text:"Edit Position", handler:handleEditPosition});
IETF_DOCS.ballotDialog = new YAHOO.widget.Dialog("doc_ballot_dialog", {
IETF.ballotDialog = new YAHOO.widget.Dialog("doc_ballot_dialog", {
visible:false, draggable:false, close:true, modal:true,
width:"850px", fixedcenter:true, constraintoviewport:true,
buttons: buttons});
IETF_DOCS.ballotDialog.render();
IETF.ballotDialog.render();
}
document.getElementById("doc_ballot_dialog_name").innerHTML = draftName;
document.getElementById("doc_ballot_dialog_id").innerHTML = trackerId;
IETF_DOCS.ballotDialog.show();
IETF.ballotDialog.show();
el = document.getElementById("doc_ballot_dialog_12");
el.innerHTML = "Loading...";
@ -69,3 +69,59 @@ function showBallot(draftName, trackerId) {
argument: null
}, null);
}
function signIn() {
document.cookie = "mytestcookie=worked; path=/";
if (document.cookie.length == 0) {
alert("You must enable cookies to sign in");
return;
}
// Initialize Django session cookie
YAHOO.util.Connect.asyncRequest('GET', '/account/login/', {}, null);
var onSuccess = function(o) {
if (o.status != 200) {
document.getElementById("signin_msg").innerHTML = o.statusText;
} else {
var t = o.responseText;
if (t.search("Please enter a correct username and password") >= 0) {
document.getElementById("signin_msg").innerHTML = "The username or password you entered is incorrect.";
} else if (t.search("Username and Email Address for legacy tools") >= 0) {
IETF.signinDialog.hide();
window.location.reload();
} else {
alert(t);
document.getElementById("signin_msg").innerHTML = "Internal error?";
}
}
};
var onFailure = function(o) {
document.getElementById("signin_msg").innerHTML = o.statusText;
};
var handleOk = function() {
document.getElementById("signin_msg").innerHTML = "Signing in...";
document.cookie = "testcookie=worked; path=/";
YAHOO.util.Connect.setForm(document.signin_form);
YAHOO.util.Connect.asyncRequest('POST',
'/account/login/', {success:onSuccess,failure:onFailure});
return false;
};
if (!IETF.signinDialog) {
var dialog = new YAHOO.widget.Panel("signin_dlg", {
draggable:false, modal:true,
width:"350px", fixedcenter:true, constraintoviewport:true });
var kl1 = new YAHOO.util.KeyListener(document, { keys: 27 }, function() { dialog.cancel();});
var kl2 = new YAHOO.util.KeyListener("signin_password", { keys: 13 }, function () { } );
dialog.cfg.queueProperty("keylisteners", [kl1,kl2]);
dialog.render();
YAHOO.util.Event.addListener(document.signin_form, "submit", handleOk);
var cancelButton = new YAHOO.widget.Button("signin_button2");
cancelButton.on("click", function() {dialog.hide();});
IETF.signinDialog = dialog;
}
document.getElementById("signin_msg").innerHTML = "";
IETF.signinDialog.show();
}
function signOut() {
YAHOO.util.Connect.asyncRequest('GET', '/account/logout/', { success: function(o) { window.location.reload(); } }, null);
};