Rewrite draft and RFC tabs in terms of the new schema, porting

write-up and history tabs as well
 - Legacy-Id: 5214
This commit is contained in:
Ole Laursen 2013-01-16 14:57:01 +00:00
parent 321f646dab
commit aa70cffe73
13 changed files with 750 additions and 88 deletions

View file

@ -1,4 +1,4 @@
import os
import os, re, urllib
from django.conf import settings
# Should this move from idrfc to doc?
@ -145,6 +145,37 @@ def augment_events_with_revision(doc, events):
e.rev = cur_rev
def add_links_in_new_revision_events(doc, events, diff_revisions):
"""Add direct .txt links and diff links to new_revision events."""
prev = None
diff_urls = dict(((name, revision), url) for name, revision, time, url in diff_revisions)
for e in sorted(events, key=lambda e: (e.time, e.id)):
if not e.type == "new_revision":
continue
if not (e.doc.name, e.rev) in diff_urls:
continue
full_url = diff_url = diff_urls[(e.doc.name, e.rev)]
if doc.type_id in "draft": # work around special diff url for drafts
full_url = "http://tools.ietf.org/id/" + diff_url + ".txt"
# build links
links = r'<a href="%s">\1</a>' % full_url
if prev:
links += ""
if prev != None:
links += ' (<a href="http:%s?url1=%s&url2=%s">diff from previous</a>)' % (settings.RFCDIFF_PREFIX, urllib.quote(diff_url, safe="~"), urllib.quote(prev, safe="~"))
# replace the bold filename part
e.desc = re.sub(r"<b>(.+-[0-9][0-9].txt)</b>", links, e.desc)
prev = diff_url
def get_document_content(key, filename, split=True, markup=True):
f = None
@ -153,15 +184,12 @@ def get_document_content(key, filename, split=True, markup=True):
raw_content = f.read()
except IOError:
error = "Error; cannot read ("+key+")"
if split:
return (error, "")
else:
return error
return error
finally:
if f:
f.close()
if markup:
return markup_txt.markup(raw_content,split)
return markup_txt.markup(raw_content, split)
else:
return raw_content

View file

@ -66,7 +66,8 @@ def markup(content, split=True):
if split:
n = content.find("\n", 5000)
content1 = "<pre>"+content[:n+1]+"</pre>\n"
content2 = "<pre>"+content[n+1:]+"</pre>\n"
return (content1, content2)
return content1
#content2 = "<pre>"+content[n+1:]+"</pre>\n"
#return (content1, content2)
else:
return "<pre>" + content + "</pre>\n"

View file

@ -2,7 +2,7 @@ from django.conf import settings
from ietf.idtracker.models import InternetDraft, DocumentComment, BallotInfo, IESGLogin
from ietf.idrfc.mails import *
from ietf.ietfauth.decorators import has_role
from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream
def add_document_comment(request, doc, text, ballot=None):
if request:
@ -177,17 +177,13 @@ def update_telechatREDESIGN(request, doc, by, new_telechat_date, new_returning_i
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
update_telechat = update_telechatREDESIGN
def can_edit_intended_std_level(doc, user):
def can_edit_intended_std_level(user, doc):
return user.is_authenticated() and (
has_role(user, ["Secretariat", "Area Director"]) or
doc.group.role_set.filter(name__in=("chair", "auth", "delegate"), person__user=user)
)
has_role(user, ["Secretariat", "Area Director"]) or is_authorized_in_doc_stream(user, doc))
def can_edit_consensus(doc, user):
def can_edit_consensus(user, doc):
return user.is_authenticated() and (
has_role(user, ["Secretariat", "Area Director"]) or
doc.group.role_set.filter(name__in=("chair", "auth", "delegate"), person__user=user)
)
has_role(user, ["Secretariat", "Area Director"]) or is_authorized_in_doc_stream(user, doc))
def nice_consensus(consensus):
mapping = {

View file

@ -30,7 +30,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import re, os, datetime
import re, os, datetime, urllib
from django.http import HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404, redirect
@ -53,7 +53,7 @@ from ietf.ietfworkflows.utils import get_full_info_for_draft
from ietf.doc.models import *
from ietf.doc.utils import *
from ietf.utils.history import find_history_active_at
from ietf.ietfauth.decorators import has_role
from ietf.ietfauth.utils import user_is_person, has_role, role_required, is_authorized_in_doc_stream
def render_document_top(request, doc, tab, name):
tabs = []
@ -72,7 +72,6 @@ def render_document_top(request, doc, tab, name):
tabs.append(("History", "history", urlreverse("ietf.idrfc.views_doc.document_history", kwargs=dict(name=doc.name)), True))
name = doc.canonical_name()
if name.startswith("rfc"):
name = "RFC %s" % name[3:]
else:
@ -86,11 +85,13 @@ def render_document_top(request, doc, tab, name):
def document_main(request, name, rev=None):
if name.lower().startswith("draft") or name.lower().startswith("rfc"):
if "old" in request.GET and (name.lower().startswith("draft") or name.lower().startswith("rfc")):
if rev != None: # no support for old revisions at the moment
raise Http404()
return document_main_idrfc(request, name, tab="document")
# generic part
doc = get_object_or_404(Document, docalias__name=name)
group = doc.group
if doc.type_id == 'conflrev':
@ -128,18 +129,246 @@ def document_main(request, name, rev=None):
top = render_document_top(request, doc, "document", name)
telechat = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
if telechat and not telechat.telechat_date:
if telechat and (not telechat.telechat_date or telechat.telechat_date < datetime.date.today()):
telechat = None
if telechat and telechat.telechat_date < datetime.date.today():
telechat = None
# specific document types
if doc.type_id == "draft":
filename = "%s-%s.txt" % (doc.name, doc.rev)
split_content = not request.GET.get('include_text')
if request.COOKIES.get("full_draft", "") == "on":
split = False
iesg_state = doc.get_state("draft-iesg")
can_edit = has_role(request.user, ("Area Director", "Secretariat"))
stream_slugs = StreamName.objects.values_list("slug", flat=True)
can_change_stream = bool(can_edit or (request.user.is_authenticated() and
Role.objects.filter(name__in=("chair", "auth"),
group__acronym__in=stream_slugs,
person__user=request.user)))
can_edit_iana_state = has_role(request.user, ("Secretariat", "IANA"))
if name.startswith("rfc"):
# RFC tab
rfc_number = name[3:]
filename = name + ".txt"
content = get_document_content(filename, os.path.join(settings.RFC_PATH, filename),
split_content, markup=True)
draft_name = doc.name if doc.name.startswith("draft") else None
def prettify_std_name(n):
if re.match(r"(rfc|bcp|fyi)[0-9]{4}", n):
return n[:3].upper() + " " + n[3:]
else:
return n
aliases = [prettify_std_name(a.name) for a in doc.docalias_set.filter(
models.Q(name__startswith="fyi") |
models.Q(name__startswith="std"))]
# file types
base_path = os.path.join(settings.RFC_PATH, name + ".")
possible_types = ["txt", "pdf", "ps"]
found_types = [t for t in possible_types if os.path.exists(base_path + t)]
base = "http://www.rfc-editor.org/rfc/"
file_urls = []
for t in found_types:
label = "plain text" if t == "txt" else t
file_urls.append((label, base + name + "." + t))
if "pdf" not in found_types and "txt" in found_types:
file_urls.append(("pdf", base + "pdfrfc/" + name + ".txt.pdf"))
if "txt" in found_types:
file_urls.append(("html", "http://tools.ietf.org/html/" + name))
if not found_types:
content = "This RFC is not currently available online."
split_content = False
elif "txt" not in found_types:
content = "This RFC is not available in plain text format."
split_content = False
return render_to_response("idrfc/document_rfc.html",
dict(doc=doc,
top=top,
name=name,
content=content,
split_content=split_content,
rfc_number=rfc_number,
updates=[prettify_std_name(d.name) for d in doc.related_that_doc("updates")],
updated_by=[prettify_std_name(d.canonical_name()) for d in doc.related_that("updates")],
obsoletes=[prettify_std_name(d.name) for d in doc.related_that_doc("obs")],
obsoleted_by=[prettify_std_name(d.canonical_name()) for d in doc.related_that("obs")],
draft_name=draft_name,
aliases=aliases,
has_errata=doc.tags.filter(slug="errata"),
published=doc.latest_event(type="published_rfc"),
file_urls=file_urls,
# can_edit=can_edit,
# can_change_stream=can_change_stream,
# can_edit_stream_info=can_edit_stream_info,
# telechat=telechat,
# ballot_summary=ballot_summary,
# iesg_state=iesg_state,
),
context_instance=RequestContext(request))
content = get_document_content(filename, os.path.join(settings.INTERNET_DRAFT_PATH, filename),
split_content, markup=True)
# ballot
ballot_summary = None
if iesg_state and iesg_state.slug in ("lc", "writeupw", "goaheadw", "iesg-eva", "defer"):
active_ballot = doc.active_ballot()
if active_ballot:
ballot_summary = needed_ballot_positions(doc, active_ballot.active_ad_positions().values())
# submission
submission = ""
if group.type_id == "individ":
if doc.stream_id and doc.stream_id != "ietf":
submission = doc.stream.name
else:
submission = "individual"
elif group.type_id == "area" and doc.stream_id == "ietf":
submission = "individual in %s area" % group.acronym
else:
submission = "%s %s" % (group.acronym, group.type)
if group.type_id == "wg":
submission = "<a href=\"%s\">%s</a>" % (urlreverse("wg_docs", kwargs=dict(acronym=doc.group.acronym)), submission)
if doc.get_state_slug("draft-stream-%s" % doc.stream_id) == "c-adopt":
submission = "candidate for %s" % submission
# resurrection
resurrected_by = None
if doc.get_state_slug() == "expired":
e = doc.latest_event(type__in=("requested_resurrect", "completed_resurrect"))
if e and e.type == "requested_resurrect":
resurrected_by = e.by
# file types
base_path = os.path.join(settings.INTERNET_DRAFT_PATH, doc.name + "-" + doc.rev + ".")
possible_types = ["pdf", "xml", "ps"]
found_types = ["txt"] + [t for t in possible_types if os.path.exists(base_path + t)]
tools_base = "http://tools.ietf.org/"
if doc.get_state_slug() == "active":
base = "http://www.ietf.org/id/"
else:
base = tools_base + "id/"
file_urls = []
for t in found_types:
label = "plain text" if t == "txt" else t
file_urls.append((label, base + doc.name + "-" + doc.rev + "." + t))
if "pdf" not in found_types:
file_urls.append(("pdf", tools_base + "pdf/" + doc.name + "-" + doc.rev + ".pdf"))
file_urls.append(("html", tools_base + "html/" + doc.name + "-" + doc.rev))
# stream info
stream_state = None
if doc.stream:
stream_state = doc.get_state("draft-stream-%s" % doc.stream_id)
stream_tags = get_tags_for_stream_id(doc.stream_id)
shepherd_writeup = doc.latest_event(WriteupDocEvent, type="changed_protocol_writeup")
can_edit_stream_info = is_authorized_in_doc_stream(request.user, doc)
can_edit_shepherd_writeup = can_edit_stream_info or user_is_person(request.user, doc.shepherd) or has_role(request.user, ["Area Director"])
consensus = None
if doc.stream_id in ("ietf", "irtf", "iab"):
e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
consensus = nice_consensus(e and e.consensus)
# mailing list search archive
search_archive = "www.ietf.org/mail-archive/web/"
if doc.stream_id == "ietf" and group.type_id == "wg" and group.list_archive:
search_archive = group.list_archive
search_archive = urllib.quote(search_archive, safe="~")
# conflict reviews
conflict_reviews = [d.name for d in doc.related_that("conflrev")]
# remaining actions
actions = []
if ((not doc.stream_id or doc.stream_id in ("ietf", "irtf")) and group.type_id == "individ" and
(Role.objects.filter(person__user=request.user, name__in=("chair", "delegate"), group__type__in=("wg",), group__state="active")
or has_role(request.user, "Secretariat"))):
actions.append(("Adopt in Group", urlreverse('edit_adopt', kwargs=dict(name=doc.name))))
if doc.get_state_slug() == "expired" and not resurrected_by and can_edit:
actions.append(("Request Resurrect", urlreverse('doc_request_resurrect', kwargs=dict(name=doc.name))))
if doc.get_state_slug() == "expired" and has_role(request.user, ("Secretariat",)):
actions.append(("Resurrect", urlreverse('doc_resurrect', kwargs=dict(name=doc.name))))
if doc.get_state_slug() != "expired" and doc.stream_id in ("ise", "irtf") and has_role(request.user, ("Secretariat",)) and not conflict_reviews:
label = "Begin IETF Conflict Review"
if not doc.intended_std_level:
label += " (note that intended status is not set)"
actions.append((label, urlreverse('conflict_review_start', kwargs=dict(name=doc.name))))
if doc.get_state_slug() != "expired" and doc.stream_id in ("ietf",) and can_edit and not iesg_state:
actions.append(("Begin IESG Processing", urlreverse('doc_edit_info', kwargs=dict(name=doc.name)) + "?new=1"))
return render_to_response("idrfc/document_draft.html",
dict(doc=doc,
top=top,
name=name,
content=content,
split_content=split_content,
revisions=revisions,
snapshot=snapshot,
can_edit=can_edit,
can_change_stream=can_change_stream,
can_edit_stream_info=can_edit_stream_info,
can_edit_shepherd_writeup=can_edit_shepherd_writeup,
can_edit_intended_std_level=can_edit_intended_std_level(request.user, doc),
can_edit_consensus=can_edit_consensus(request.user, doc),
can_edit_iana_state=can_edit_iana_state,
telechat=telechat,
ballot_summary=ballot_summary,
group=group,
submission=submission,
resurrected_by=resurrected_by,
replaces=[d.name for d in doc.related_that_doc("replaces")],
replaced_by=[d.name for d in doc.related_that("replaces")],
conflict_reviews=conflict_reviews,
file_urls=file_urls,
stream_state=stream_state,
stream_tags=stream_tags,
milestones=doc.groupmilestone_set.filter(state="active"),
consensus=consensus,
iesg_state=iesg_state,
rfc_editor_state=doc.get_state("draft-rfceditor"),
iana_review_state=doc.get_state("draft-iana-review"),
iana_action_state=doc.get_state("draft-iana-action"),
shepherd_writeup=shepherd_writeup,
search_archive=search_archive,
actions=actions,
),
context_instance=RequestContext(request))
if doc.type_id == "charter":
filename = "%s-%s.txt" % (doc.canonical_name(), doc.rev)
content = _get_html(filename, os.path.join(settings.CHARTER_PATH, filename), split=False)
content = get_document_content(filename, os.path.join(settings.CHARTER_PATH, filename), split=False, markup=True)
ballot_summary = None
if doc.get_state_slug() in ("intrev", "iesgrev"):
@ -179,7 +408,7 @@ def document_main(request, name, rev=None):
# This could move to a template
content = "A conflict review response has not yet been proposed."
else:
content = _get_html(filename, pathname, split=False)
content = get_document_content(filename, pathname, split=False, markup=True)
ballot_summary = None
if doc.get_state_slug() in ("iesgeval"):
@ -198,15 +427,10 @@ def document_main(request, name, rev=None):
),
context_instance=RequestContext(request))
raise Http404()
raise Http404
def document_history(request, name):
# todo: remove need for specific handling of drafts by porting the
# two event text hacks
if name.lower().startswith("draft") or name.lower().startswith("rfc"):
return document_main_idrfc(request, name, "history")
doc = get_object_or_404(Document, docalias__name=name)
top = render_document_top(request, doc, "history", name)
@ -241,6 +465,7 @@ def document_history(request, name):
events = doc.docevent_set.all().order_by("-time", "-id").select_related("by")
augment_events_with_revision(doc, events)
add_links_in_new_revision_events(doc, events, diff_revisions)
return render_to_response("idrfc/document_history.html",
dict(doc=doc,
@ -251,38 +476,61 @@ def document_history(request, name):
context_instance=RequestContext(request))
def document_writeup(request, name):
if name.lower().startswith("draft") or name.lower().startswith("rfc"):
# todo: migrate idrfc to pattern below
return document_main_idrfc(request, name, "writeup")
doc = get_object_or_404(Document, docalias__name=name)
top = render_document_top(request, doc, "writeup", name)
writeups = []
if doc.type_id == "charter":
e = doc.latest_event(WriteupDocEvent, type="changed_review_announcement")
writeups.append(("WG Review Announcement",
e.text if e else "",
urlreverse("ietf.wgcharter.views.announcement_text", kwargs=dict(name=doc.name, ann="review"))))
def text_from_writeup(event_type):
e = doc.latest_event(WriteupDocEvent, type=event_type)
if e:
return e.text
else:
return ""
e = doc.latest_event(WriteupDocEvent, type="changed_action_announcement")
writeups.append(("WG Action Announcement",
e.text if e else "",
urlreverse("ietf.wgcharter.views.announcement_text", kwargs=dict(name=doc.name, ann="action"))))
sections = []
if doc.type_id == "draft":
writeups = []
sections.append(("Approval Announcement",
"<em>Draft</em> of message to be sent <em>after</em> approval:",
writeups))
writeups.append(("Announcement",
text_from_writeup("changed_ballot_approval_text"),
urlreverse("doc_ballot_approvaltext", kwargs=dict(name=doc.name))))
writeups.append(("Ballot Text",
text_from_writeup("changed_ballot_writeup_text"),
urlreverse("doc_ballot_writeupnotes", kwargs=dict(name=doc.name))))
elif doc.type_id == "charter":
sections.append(("WG Review Announcement",
"",
[("WG Review Announcement",
text_from_writeup("changed_review_announcement"),
urlreverse("ietf.wgcharter.views.announcement_text", kwargs=dict(name=doc.name, ann="review")))]
))
sections.append(("WG Action Announcement",
"",
[("WG Action Announcement",
text_from_writeup("changed_action_announcement"),
urlreverse("ietf.wgcharter.views.announcement_text", kwargs=dict(name=doc.name, ann="action")))]
))
if doc.latest_event(BallotDocEvent, type="created_ballot"):
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
writeups.append(("Ballot Announcement",
e.text if e else "",
urlreverse("ietf.wgcharter.views.ballot_writeupnotes", kwargs=dict(name=doc.name))))
sections.append(("Ballot Announcement",
"",
[("Ballot Announcement",
text_from_writeup("changed_ballot_writeup_text"),
urlreverse("ietf.wgcharter.views.ballot_writeupnotes", kwargs=dict(name=doc.name)))]
))
if not writeups:
if not sections:
raise Http404()
return render_to_response("idrfc/document_writeup.html",
dict(doc=doc,
top=top,
writeups=writeups,
sections=sections,
can_edit=has_role(request.user, ("Area Director", "Secretariat")),
),
context_instance=RequestContext(request))
@ -404,9 +652,11 @@ def document_json(request, name):
return HttpResponse(json.dumps(data, indent=2), mimetype='text/plain')
def _get_html(key, filename, split=True):
return get_document_content(key, filename, split=split, markup=True)
# FIXME
return get_document_content(key, filename, split=split, markup=True), ""
def include_text(request):
# FIXME
include_text = request.GET.get( 'include_text' )
if "full_draft" in request.COOKIES:
if request.COOKIES["full_draft"] == "on":
@ -414,6 +664,7 @@ def include_text(request):
return include_text
def document_main_rfc(request, rfc_number, tab):
# FIXME
rfci = get_object_or_404(RfcIndex, rfc_number=rfc_number, states__type="draft", states__slug="rfc")
rfci.viewing_as_rfc = True
doc = RfcWrapper(rfci)
@ -445,6 +696,7 @@ def document_main_rfc(request, rfc_number, tab):
@decorator_from_middleware(GZipMiddleware)
def document_main_idrfc(request, name, tab):
# FIXME
r = re.compile("^rfc([1-9][0-9]*)$")
m = r.match(name)
if m:
@ -464,8 +716,8 @@ def document_main_idrfc(request, name, tab):
if id.stream_id in ("ietf", "irtf", "iab"):
e = id.latest_event(ConsensusDocEvent, type="changed_consensus")
info["consensus"] = nice_consensus(e and e.consensus)
info["can_edit_consensus"] = can_edit_consensus(id, request.user)
info["can_edit_intended_std_level"] = can_edit_intended_std_level(id, request.user)
info["can_edit_consensus"] = can_edit_consensus(request.user, id)
info["can_edit_intended_std_level"] = can_edit_intended_std_level(request.user, id)
(content1, content2) = _get_html(
str(name)+","+str(id.revision)+",html",

View file

@ -204,7 +204,7 @@ class ChangeStreamForm(forms.Form):
@login_required
def change_stream(request, name):
"""Change the stream of a Document of type 'draft' , notifying parties as necessary
"""Change the stream of a Document of type 'draft', notifying parties as necessary
and logging the change as a comment."""
doc = get_object_or_404(Document, docalias__name=name)
if not doc.type_id=='draft':
@ -271,7 +271,7 @@ def change_intention(request, name):
if doc.type_id != 'draft':
raise Http404
if not can_edit_intended_std_level(doc, request.user):
if not can_edit_intended_std_level(request.user, doc):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
login = request.user.get_profile()
@ -904,7 +904,7 @@ def edit_consensus(request, name):
doc = get_object_or_404(Document, type="draft", name=name)
if not can_edit_consensus(doc, request.user):
if not can_edit_consensus(request.user, doc):
return HttpResponseForbidden("You do not have the necessary permissions to view this page")
e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")

View file

@ -6,6 +6,7 @@ from django.views.generic.simple import redirect_to
urlpatterns = patterns('ietf.ietfworkflows.views',
url(r'^(?P<name>[^/]+)/history/$', 'stream_history', name='stream_history'),
url(r'^(?P<name>[^/]+)/edit/adopt/$', 'edit_adopt', name='edit_adopt'),
# FIXME: the name edit_state is far too generic
url(r'^(?P<name>[^/]+)/edit/state/$', 'edit_state', name='edit_state'),
url(r'^(?P<name>[^/]+)/edit/stream/$', redirect_to, { 'url': '/doc/%(name)s/edit/info/'}) ,
url(r'^delegates/(?P<stream_name>[^/]+)/$', 'stream_delegates', name='stream_delegates'),

View file

@ -1,6 +1,4 @@
{% extends "idrfc/doc_main.html" %}
{% comment extends "base.html" %}
{% endcomment %}
{% extends "base.html" %}
{% load ietf_filters %}
@ -99,24 +97,24 @@
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
</table>
<div class="actions">
<div class="links">
<a href="/feed/group-changes/{{ group.acronym }}/">Atom feed</a>
</div>
<div>
<div class="actions">
{% if not snapshot and user|has_role:"Area Director,Secretariat" %}
{% if chartering %}
<span id="charter_abandon_effort_button" class="yui-button yui-link-button" style="margin-left:2px;margin-top:2px">{% url charter_startstop_process name=doc.name option='abandon' as abandon_url %}{% if abandon_url %}<span class="first-child"><a href="{{abandon_url}}">Abandon Effort</a></span>{% endif %}</span>
{% url charter_startstop_process name=doc.name option='abandon' as abandon_url %}{% if abandon_url %}<a class="button" href="{{ abandon_url }}">Abandon Effort</a>{% endif %}
{% if request.user|has_role:"Secretariat" %}
<span id="charter_approve_button" class="yui-button yui-link-button" style="margin-left:2px;margin-top:2px">{% url charter_approve name=doc.name as approve_url %}{% if approve_url %}<span class="first-child"><a href="{{approve_url}}">Approve Charter</a></span>{% endif %}</span>
{% url charter_approve name=doc.name as approve_url %}{% if approve_url %}<a class="button" href="{{ approve_url }}">Approve Charter</a>{% endif %}
{% endif %}
{% else %}
{% if group.state_id == "proposed" or group.state_id == "bof" %}
<span id="charter_start_button" class="yui-button yui-link-button" style="margin-left:2px;margin-top:2px">{% url charter_submit name=doc.name option='initcharter' as start_url %}{% if start_url %}<span class="first-child"><a href="{{start_url}}">Start Chartering</a></span>{% endif %}</span>
{% url charter_submit name=doc.name option='initcharter' as start_url %}{% if start_url %}<a class="button" href="{{ start_url }}">Start Chartering</a>{% endif %}
{% else %}
<span id="charter_recharter_button" class="yui-button yui-link-button" style="margin-left:2px;margin-top:2px">{% url charter_submit name=doc.name option='recharter' as recharter_url %}{% if recharter_url %}<span class="first-child"><a href="{{recharter_url}}">Recharter</a></span>{% endif %}</span>
{% url charter_submit name=doc.name option='recharter' as recharter_url %}{% if recharter_url %}<a class="button" href="{{ recharter_url }}">Recharter</a>{% endif %}
{% endif %}
{% endif %}
@ -134,7 +132,7 @@
</h3>
{% if doc.rev != "" %}
<div class="markup_draft">
<div class="document-markup">
{{ content|safe|keep_spacing|sanitize_html|wordwrap:80|safe }}
</div>
{% endif %}

View file

@ -1,4 +1,4 @@
{% extends "idrfc/doc_main.html" %}
{% extends "base.html" %}
{% load ietf_filters %}
@ -107,7 +107,7 @@
</h3>
{% if doc.rev %}
<div class="markup_draft">
<div class="document-markup">
{{ content|fill:"80"|safe|linebreaksbr|keep_spacing|sanitize_html|safe }}
</div>
{% endif %}

View file

@ -0,0 +1,269 @@
{% extends "base.html" %}
{% load ietf_filters %}
{% block title %}{{ name }}-{{ doc.rev }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
<meta name="description" content="{{ doc.title }} (Internet-Draft, {{ doc.time|date:"Y" }})" />
{% endblock %}
{% block content %}
{{ top|safe }}
{% comment %}
<div class="snapshots">
Snapshots:
<span class="revisions">
{% for rev in revisions %}
<a {% if rev != doc.rev %}href="{% url doc_view name=doc.name %}{% if not forloop.last %}{{ rev }}/{% endif %}"{% endif %}>{{ rev }}</a>
{% endfor %}
</span>
</div>
{% endcomment %}
<div class="ietf-box metabox">
<div>
{{ doc.get_state }} {% if not doc.get_state_slug == "rfc" %}Internet-Draft{% endif %}
({{ submission|safe }})
{% if resurrected_by %}- resurrect requested by {{ resurrected_by }}{% endif %}
</div>
<table id="metatable" width="100%">
<tr>
<td>Document Stream:</td>
<td><a {% if can_change_stream %} class="editlink" href="{% url doc_change_stream name=doc.name %}"{% endif %}>
{{ doc.stream|default:"No stream defined" }}</a></td>
</tr>
<tr>
<td>Last updated:</td>
<td>{{ doc.time|date:"Y-m-d" }}</td>
</tr>
{% if replaces %}
<tr>
<td>Replaces:</td>
<td>{{ replaces|join:", "|urlize_ietf_docs }}</td>
</tr>
{% endif %}
{% if replaced_by %}
<tr>
<td>Replaced by:</td>
<td>{{ replaced_by|join:", "|urlize_ietf_docs }}</td>
</tr>
{% endif %}
{% if conflict_reviews %}
<tr>
<td>IETF Conflict Review:</td>
<td>{{ conflict_reviews|join:", "|urlize_ietf_docs }}</td>
</tr>
{% endif %}
<tr>
<td>Intended RFC status:</td>
<td>
<a {% if can_edit %}class="editlink" href="{% url doc_change_intended_status name=doc.name %}"{% endif %}>
{{ doc.intended_std_level|default:"(None)" }}</a>
</td>
</tr>
<tr>
<td>Other versions:</td>
<td>
{% if doc.get_state_slug != "active" %}(expired, archived):{% endif %}
{% for label, url in file_urls %}<a href="{{ url }}">{{ label}}</a>{% if not forloop.last%}, {% endif %}{% endfor %}
</td>
</tr>
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
<tr>
<td>{{ doc.stream }} State:</td>
<td class="stream-state">
<a {% if can_edit_stream_info %}class="editlink" href="{% url edit_state name=doc.name %}"{% endif %}>
{{ stream_state|default:"(None)" }}
</a>
{% if stream_tags %}<br /><i>{% for tag in tags %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}</i>{% endif %}
{% for m in milestones %}
<span title="In {{ m.group.acronym }} milestone: {{ m.desc }}" class="milestone">{{ m.due|date:"M Y" }}</span>
{% endfor %}
</td>
</tr>
{% if consensus %}
<tr>
<td>Consensus:</td>
<td>
<a title="Whether the document is the result of a community consensus process as defined in RFC 5741" {% if can_edit_consensus %}class="editlink" href="{% url doc_edit_consensus name=doc.name %}"{% endif %}>
{{ consensus }}
</a>
</td>
</tr>
{% endif %}
<tr>
<td>Document shepherd:</td>
<td>
{# the shepherd edit page only works for WGs at the moment ... #}
<a {% if can_edit_stream_info and group.type_id == "wg" %}class="editlink" href="{% url doc_managing_shepherd acronym=group.acronym,name=doc.name %}"{% endif %}>
{{ doc.shepherd|default:"(None)" }}
</a>
</td>
</tr>
{# the shepherd write up page only works for WGs at the moment ... #}
{% if group.type_id == "wg" %}
{% if shepherd_writeup or can_edit_shepherd_writeup %}
<tr>
<td>Shepherd Write-Up:</td>
<td>
<a {% if can_edit_shepherd_writeup %}class="editlink"{% endif %} href="{% url doc_managing_writeup acronym=group.acronym,name=doc.name %}">
{% if shepherd_writeup %}Last changed {{ shepherd_writeup.time|date:"Y-m-d"}}{% else %}(None){% endif %}
</a>
</td>
</tr>
{% endif %}
{% endif %}
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
<tr>
<td><a href="/idtracker/help/state/">IESG State</a>:</td>
<td>
<a {% if iesg_state and can_edit %}class="editlink" href="{% url doc_change_state name=doc.name %}"{% endif %}>
{{ doc.friendly_state|safe }}</a>
{% if iana_review_state %}
<div>IANA Review State:
<a {% if can_edit_iana_state %}class="editlink" href="{% url doc_change_iana_state name=doc.name state_type="iana-review" %}"{% endif %}>{{ iana_review_state }}</a>
</div>
{% endif %}
{% if iana_review_state %}
<div>IANA Action State:
<a {% if can_edit_iana_state %}class="editlink" href="{% url doc_change_iana_state name=doc.name state_type="iana-action" %}"{% endif %}>{{ iana_action_state }}</a>
</div>
{% endif %}
{% if rfc_editor_state %}
<div>
RFC Editor State:
<a href="http://www.rfc-editor.org/queue2.html#{{ doc.name }}">{{ rfc_editor_state }}</a></div>
{% endif %}
<div class="telechat">
<a {% if can_edit %}class="editlink" href="{% url doc_change_telechat_date name=doc.name %}"{% endif %}>
{% if telechat %}
On agenda of {{ telechat.telechat_date }} IESG telechat {% if telechat.returning_item %} (returning item){% endif %}
{% else %}
{% if can_edit %}Not on an upcoming telechat agenda{% endif %}
{% endif %}
</a>
</div>
{% if ballot_summary %}<div class="ballot-summary">({{ ballot_summary }})</div>{% endif %}
</td>
</tr>
<tr>
<td>Responsible AD:</td>
<td>
<a {% if can_edit %}class="editlink" href="{% url doc_change_ad name=doc.name %}"{% endif %}>
{{ doc.ad|default:"(None)" }}
</a>
</td>
</tr>
{% if iesg_state %}
{% if doc.note or can_edit %}
<tr>
<td>IESG Note:</td>
<td>
<a {% if can_edit %}class="editlink" href="{% url doc_change_iesg_note name=doc.name %}"{% endif %}>
{{ doc.note|default:"(None)"|format_textarea|safe }}
</a>
</td>
</tr>
{% endif %}
{% endif %}
<tr>
<td>Send notices to:</td>
<td>
<a {% if can_edit %}class="editlink" href="{% url doc_change_notify name=doc.name %}"{% endif %}>
{{ doc.notify|default:"No addresses provided"}}
</a>
</td>
</tr>
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
</table>
<div class="links">
<a href="mailto:{{ doc.name }}@tools.ietf.org?subject=Mail%20regarding%20{{ doc.name }}" rel="nofollow">Email Authors</a>
| <a href="/ipr/search/?option=document_search&amp;id={{ doc.name }}" rel="nofollow">IPR Disclosures</a>
| <a href="http://www.fenron.net/~fenner/ietf/deps/index.cgi?dep={{ doc.name }}" rel="nofollow">Dependencies to this draft</a>
| <a href="http://tools.ietf.org/idnits?url=http://tools.ietf.org/id/{{ doc.filename_with_rev }}" rel="nofollow" target="_blank">Check nits</a>
| <a href="/feed/comments/{{ doc.name }}/">History feed</a>
| <a href="http://www.google.com/search?as_q={{ doc.name }}&as_sitesearch={{ search_archive }}" rel="nofollow" target="_blank">Search Mailing Lists</a>
{% if user|has_role:"Area Director" %}
| <a href="https://www.iesg.org/bin/c5i?mid=6&rid=77&target={{ doc.name }}" rel="nofollow" target="_blank">Search Mailing Lists (ARO)</a>
{% endif %}
</div>
{% if can_edit and iesg_state %}
<div class="links">
<a href="{% url doc_ballot_lastcall name=doc.name %}">Last Call Text</a>
| <a href="{% url doc_ballot_writeupnotes name=doc.name %}">Ballot Text</a>
| <a href="{% url doc_ballot_approvaltext name=doc.name %}">Announcement Text</a>
</div>
{% endif %}
{% if actions %}
<div class="actions">
{% for label, url in actions %}<a class="button" href="{{ url }}">{{ label }}</a> {% endfor %}
</div>
{% endif %}
</div>
{% if doc.get_state_slug == "active" %}
<div class="document-markup">
{{ content|safe }}
</div>
{% if split_content %}
<p><a style="display:inline-block;margin-left:17em;" href="?include_text=1">[include full document text]</a></p>
{% endif %}
{% else %}
<p>This Internet-Draft is no longer active. Unofficial copies of old Internet-Drafts can be found here:<br/>
<a href="http://tools.ietf.org/id/{{ doc.name }}">http://tools.ietf.org/id/{{ doc.name }}</a></p>
<h4>Abstract</h4>
<p>{{ doc.abstract|escape }}</p>
<h4>Authors</h4>
<p>
{% for author in doc.documentauthor_set.all %}
<a {% if not author.author.invalid_address %}href="mailto:{{ author.author.address }}"{% endif %}>{{ author.author.person }} {% if not author.author.invalid_address %}&lt;{{ author.author.address }}&gt;{% endif %}</a>
{% if not forloop.last %}<br/>{% endif %}{% endfor %}
</p>
<p>(Note: The e-mail addresses provided for the authors of this Internet-Draft may no longer be valid)</p>
{% endif %}
{% endblock %}

View file

@ -6,13 +6,14 @@
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
<link rel="alternate" type="application/atom+xml" href="/feed/comments/{{ doc.canonical_name }}/" />
{% endblock %}
{% block content %}
{{ top|safe }}
{% if diff_revisions and diff_revisions|length > 1 %}
<div class="ietf-box diffTool">
<div class="ietf-box diff-tool">
<h2>Diffs</h2>
<form action="http{% if request.is_secure %}s{% endif %}:{{rfcdiff_prefix}}" method="get" target="_blank">
@ -55,7 +56,7 @@
<h2>Document history</h2>
{% if user|has_role:"Area Director,Secretariat,IANA,RFC Editor" %}
<div class="history-actions">
<a href="{% url doc_add_comment name=doc.name %}">Add comment</a>
<a class="button" href="{% url doc_add_comment name=doc.name %}">Add comment</a>
</div>
{% endif %}

View file

@ -0,0 +1,92 @@
{% extends "base.html" %}
{% load ietf_filters %}
{% block title %}RFC {{ rfc_number }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
<meta name="description" content="{{ doc.title }} (RFC {{ rfc_number }}{% if published %}, {{ published.time|date:"F Y" }}{% endif %}{% if obsoleted_by %}; obsoleted by {{ obsoleted_by|join:", " }}{% endif %})" />
{% endblock %}
{% block content %}
{{ top|safe }}
<div class="ietf-box metabox">
<table id="metatable" width="100%">
<tr>
<td>Document type:</td>
<td>
RFC - {{ doc.std_level }} {% if doc.stream %}({{ doc.stream.name }} stream){% endif %}
{% if obsoleted_by %}<br />Obsoleted by {{ obsoleted_by|join:", "|urlize_ietf_docs }}{% endif %}
{% if updated_by %}<br />Updated by {{ updated_by|join:", "|urlize_ietf_docs }}{% endif %}
{% if obsoletes %}<br />Obsoletes {{ obsoletes|join:", "|urlize_ietf_docs }}{% endif %}
{% if updates %}<br />Updates {{ updates|join:", "|urlize_ietf_docs }}{% endif %}
{% if aliases %}<br />Also Known As {{ aliases|join:", "|urlize_ietf_docs }}{% endif %}
{% if draft_name %}<br />Was <a href="/doc/{{ draft_name}}/">{{ draft_name }}</a>{% endif %}
{% if has_errata %}<br /><a href="http://www.rfc-editor.org/errata_search.php?rfc={{ rfc_number }}" rel="nofollow">Errata</a>{% endif %}
</td>
</tr>
<tr>
<td>Published:</td>
<td>{% if published %}{{ published.time|date:"F Y" }}{% else %}Unknown{% endif %}</td>
</tr>
{% comment %}
{% if doc.in_ietf_process %}
<tr class="post-rfc"><td colspan="2">* This information refers to IESG processing after the RFC was initially published</td></tr>
<tr class="post-rfc"><td><a href="/idtracker/help/state/">State</a>:</td><td>
{{ doc.friendly_state|safe }} (IESG: {{ doc.ietf_process.state}})
{% if doc.ietf_process.telechat_date %}<br/>On agenda of {{ doc.ietf_process.telechat_date }} IESG telechat {% if doc.ietf_process.telechat_returning_item %} (returning item){%endif%}{%endif%}
</td></tr>
<tr class="post-rfc"><td>Intended status:</td><td>{% if doc.in_ietf_process %}{{ doc.ietf_process.intended_maturity_level|default:"-" }}{% else %}-{%endif%}</td></tr>
<tr class="post-rfc"><td>Responsible AD:</td><td>{{ doc.ietf_process.ad_name|default:"-"|escape }}</td></tr>
{% if doc.ietf_process.iesg_note %}<tr class="post-rfc"><td>IESG Note:</td><td>{{ doc.ietf_process.iesg_note|escape }}</td></tr>{% endif %}
{% if user|in_group:"Area_Director,Secretariat" %}
<tr class="post-rfc"><td>Send notices to:</td><td>{{ doc.ietf_process.state_change_notice_to}}</td></tr>
{% endif %}{# if user|in_group:... #}
{% endif %}
{% endcomment %}
<tr>
<td>Other versions:</td>
<td>
{% if file_urls %}
{% for label, url in file_urls %}<a href="{{ url }}">{{ label}}</a>{% if not forloop.last%}, {% endif %}{% endfor %}
{% else %}
(not online)
{% endif %}
</td>
</tr>
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
</table>
<div class="links">
<a href="/ipr/search/?option=rfc_search&amp;rfc_search={{ rfc_number }}" rel="nofollow">IPR Disclosures</a>
| <a href="http://www.fenron.net/~fenner/ietf/deps/index.cgi?dep={{ name }}" rel="nofollow">Dependencies to this RFC</a>
</div>
{% if can_edit and iesg_state %}
<div class="links">
<a href="{% url doc_ballot_lastcall name=doc.name %}">Last Call Text</a>
| <a href="{% url doc_ballot_writeupnotes name=doc.name %}">Ballot Text</a>
| <a href="{% url doc_ballot_approvaltext name=doc.name %}">Announcement Text</a>
</div>
{% endif %}
</div>
<div class="document-markup">
{{ content|safe }}
</div>
{% if split_content %}
<p><a style="display:inline-block;margin-left:17em;" href="?include_text=1">[include full document text]</a></p>
{% endif %}
{% endblock %}

View file

@ -9,16 +9,20 @@
{% block content %}
{{ top|safe }}
{% for title, text, url in writeups %}
<div class="writeup">
{% for title, subtitle, writeups in sections %}
<h2>{{ title }}</h2>
{% if can_edit %}<a href="{{ url }}" class="edit">{% if text %}Edit{% else %}Generate{% endif %} {{ title }}</a>{% endif %}
{% if subtitle %}<p>{{ subtitle|safe }}</p>{% endif %}
{% for name, text, url in writeups %}
<div class="writeup">
{% if can_edit %}<a href="{{ url }}" class="edit button">{% if text %}Edit{% else %}Generate{% endif %} {{ name }}</a>{% endif %}
<pre {% if can_edit %}class="editable"{% endif %}>
{{ text }}
</pre>
</div>
{% endfor%}
{% endfor %}
{% endfor %}
{% endblock content %}

View file

@ -3,26 +3,46 @@
#metatable tr { vertical-align: top; }
#metatable tr:first-child td:first-child { width: 15em; }
.markup_draft pre { line-height: 1.2em; margin: 0; }
.m_hdr, .m_ftr { color: #808080; }
.m_ftr { border-bottom: 1px solid #a0a0a0; }
.m_h { font-family: arial; font-weight:bold;}
.document-markup pre { line-height: 1.2em; margin: 0; }
.document-markup .m_hdr, .m_ftr { color: #808080; }
.document-markup .m_ftr { border-bottom: 1px solid #a0a0a0; }
.document-markup .m_h { font-family: arial; font-weight:bold;}
.snapshots { margin: 0.5em 0; }
.snapshots .revisions a:last-child { font-weight: bold; }
.metabox .actions a { display: inline-block; margin-right: 0.4em; }
.metabox .links { margin-bottom: 0.2em; }
.metabox .actions { margin-top: 0.5em; }
.metabox .ballot-summary { font-style: italic; }
.metabox .telechat { margin-top: 0.2em; }
.diffTool { padding: 8px 4px; margin: 8px 0;}
.diffTool h2 { margin-top:0;margin-bottom:4px; }
.diffTool label { display: inline-block; width: 3em; padding: 0 0.5em; }
.diffTool form { margin: 0; }
.diff-tool { padding: 8px 4px; margin: 8px 0;}
.diff-tool h2 { margin-top:0;margin-bottom:4px; }
.diff-tool label { display: inline-block; width: 3em; padding: 0 0.5em; }
.diff-tool form { margin: 0; }
.history-actions { margin-bottom: 1em; padding-left: 1px; }
.writeup pre.editable { background-color: #efefff; min-height: 3em; }
.writeup a.edit { float: right; }
.writeup pre.editable { background-color: #efefff; min-height: 3em; padding: 4px; }
.writeup a.edit { float: right; margin: 4px; }
a.editlink {
background-image: url("/images/pencil.png");
background-size: 10px;
background-position: right top;
background-attachment: scroll;
background-repeat: no-repeat;
padding-right: 12px;
}
a.editlink:link {text-decoration:none; color:inherit;}
a.editlink:visited {text-decoration:none; color:inherit;}
a.editlink:hover {text-decoration:underline;}
a.editlink:active {text-decoration:underline;}
h3 a.edit { font-weight: normal; font-size: 13px; display: inline-block; margin-left: 0.5em;}
h4 { margin-bottom: 0; }
h4 + p { margin-top: 0; max-width: 400px; }