From aa5425080554127684a39b1d4b72620ee14649fb Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Sun, 26 Apr 2009 14:02:30 +0000 Subject: [PATCH] Merged in code from Pasi for new ID/RFC search and per-document pages (under /doc/), and IESG 'discuss report'. - Legacy-Id: 1450 --- changelog | 17 + ietf/idrfc/idrfc_wrapper.py | 519 ++++++++++++++++++++ ietf/idrfc/markup_txt.py | 69 +++ ietf/idrfc/mirror_rfc_editor_queue.py | 2 +- ietf/idrfc/templatetags/__init__.py | 1 + ietf/idrfc/templatetags/ballot_icon.py | 110 +++++ ietf/idrfc/templatetags/wg_menu.py | 78 +++ ietf/idrfc/urls.py | 11 +- ietf/idrfc/views_doc.py | 174 +++++++ ietf/idrfc/views_search.py | 217 ++++++++ ietf/idtracker/templatetags/ietf_filters.py | 13 + ietf/iesg/urls.py | 1 + ietf/iesg/views.py | 33 +- ietf/manage.py | 2 +- ietf/settings.py | 8 + ietf/templates/idrfc/base.html | 111 +++++ ietf/templates/idrfc/base_leftmenu.html | 83 ++++ ietf/templates/idrfc/base_wgmenu.html | 38 ++ ietf/templates/idrfc/doc_ballot.html | 126 +++++ ietf/templates/idrfc/doc_comments.html | 62 +++ ietf/templates/idrfc/doc_main_id.html | 277 +++++++++++ ietf/templates/idrfc/doc_main_rfc.html | 167 +++++++ ietf/templates/idrfc/doc_versions.html | 69 +++ ietf/templates/idrfc/search_form.html | 132 +++++ ietf/templates/idrfc/search_main.html | 54 ++ ietf/templates/idrfc/search_result_row.html | 57 +++ ietf/templates/idrfc/search_results.html | 50 ++ ietf/templates/iesg/discusses.html | 69 +++ static/css/base2.css | 115 +++++ static/images/blue_dot.gif | Bin 0 -> 934 bytes static/images/minus.png | Bin 0 -> 204 bytes static/images/plus.png | Bin 0 -> 208 bytes static/images/square.png | Bin 0 -> 202 bytes static/images/title_line.gif | Bin 0 -> 1115 bytes static/js/base.js | 71 +++ 35 files changed, 2731 insertions(+), 5 deletions(-) create mode 100644 ietf/idrfc/idrfc_wrapper.py create mode 100644 ietf/idrfc/markup_txt.py create mode 100644 ietf/idrfc/templatetags/__init__.py create mode 100644 ietf/idrfc/templatetags/ballot_icon.py create mode 100644 ietf/idrfc/templatetags/wg_menu.py create mode 100644 ietf/idrfc/views_doc.py create mode 100644 ietf/idrfc/views_search.py create mode 100644 ietf/templates/idrfc/base.html create mode 100644 ietf/templates/idrfc/base_leftmenu.html create mode 100644 ietf/templates/idrfc/base_wgmenu.html create mode 100644 ietf/templates/idrfc/doc_ballot.html create mode 100644 ietf/templates/idrfc/doc_comments.html create mode 100644 ietf/templates/idrfc/doc_main_id.html create mode 100644 ietf/templates/idrfc/doc_main_rfc.html create mode 100644 ietf/templates/idrfc/doc_versions.html create mode 100644 ietf/templates/idrfc/search_form.html create mode 100644 ietf/templates/idrfc/search_main.html create mode 100644 ietf/templates/idrfc/search_result_row.html create mode 100644 ietf/templates/idrfc/search_results.html create mode 100644 ietf/templates/iesg/discusses.html create mode 100644 static/css/base2.css create mode 100644 static/images/blue_dot.gif create mode 100644 static/images/minus.png create mode 100644 static/images/plus.png create mode 100644 static/images/square.png create mode 100644 static/images/title_line.gif create mode 100644 static/js/base.js diff --git a/changelog b/changelog index 855fe31c1a..441199f489 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,20 @@ +ietfdb (2.24) + + * Merged in code from Pasi for new ID/RFC search and per-document pages, + and IESG "discuss report". + + * Added missing images for liaison_manager.cgi to static/images/. + + * More sensible error message if settings_local.py is not found. + + * Fix feed problem for non-ascii names. From Pasi Eronen. + + * ** NOTE: This release uses the Django cache framework, and requires + that the cache directory in settings.py (/a/www/ietf-datatracker/cache/) + exists. + + * Fix problem with area model in admin interface + ietfdb (2.23) * Fixed a wrong link in the html agenda (from Henrik) diff --git a/ietf/idrfc/idrfc_wrapper.py b/ietf/idrfc/idrfc_wrapper.py new file mode 100644 index 0000000000..4422edb3db --- /dev/null +++ b/ietf/idrfc/idrfc_wrapper.py @@ -0,0 +1,519 @@ +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# 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. + +from ietf.idtracker.models import InternetDraft, Rfc, IDInternal, BallotInfo, IESGDiscuss, IESGComment, Position, IESGLogin +from ietf.idrfc.models import RfcIndex, RfcEditorQueue, DraftVersions +import re +from datetime import date, timedelta +from django.utils import simplejson +import types + +BALLOT_ACTIVE_STATES = ['In Last Call', + 'Waiting for Writeup', + 'Waiting for AD Go-Ahead', + 'IESG Evaluation', + 'IESG Evaluation - Defer'] + +# A wrapper to make writing templates less painful +# Can represent either an Internet Draft, RFC, or combine both + +class IdRfcWrapper: + # avoid using these in templates + draft = None + idinternal = None + rfc = None + rfcIndex = None + + # Active, RFC, Expired, Replaced, etc. + document_status = None + draft_name = None + draft_revision = 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 + + # must give either draft or rfcIndex! + def __init__(self, draft=None, rfc=None, rfcIndex=None, findRfc=False): + if isinstance(draft, IDInternal): + self.idinternal = draft + self.draft = self.idinternal.draft + elif draft: + 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() + + 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 + 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 + + def rfc_editor_state(self): + try: + if self.draft: + 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 + else: + return None + + def iesg_note(self): + if self.idinternal and self.idinternal.note: + n = self.idinternal.note + # Hide unnecessary note of form "RFC 1234" + if re.match("^RFC\s*\d+$", n): + return None + return n + else: + return None + + def iesg_ballot_approval_text(self): + if self.has_iesg_ballot(): + return self.idinternal.ballot.approval_text + else: + return None + def iesg_ballot_writeup(self): + if self.has_iesg_ballot(): + return self.idinternal.ballot.ballot_writeup + 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: + 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 + else: + return None + + # 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) + return None + + def view_sort_group(self): + if self.is_rfc(): + return 'RFC' + elif self.document_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 + + 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: +# o['telechatReturningItem'] = True +# if idinternal.telechat_date: +# 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 + ballot = None + ballot_active = False + + _positions = None + + position_values = ["Discuss", "Yes", "No Objection", "Abstain", "Recuse", "No Record"] + + def __init__(self, idinternal, ballot_active): + self.idinternal = idinternal + self.ballot = idinternal.ballot + self.ballot_active = ballot_active + + def _init(self): + try: + ads = set() + except NameError: + # for Python 2.3 + from sets import Set as set + ads = set() + + positions = [] + for p in self.ballot.positions.all(): + po = create_position_object(self.ballot, p) + #if not self.ballot_active: + # if 'is_old_ad' in po: + # del po['is_old_ad'] + ads.add(str(p.ad)) + positions.append(po) + if self.ballot_active: + for ad in IESGLogin.active_iesg(): + if str(ad) not in ads: + positions.append({"ad_name":str(ad), "position":"No Record"}) + self._positions = positions + + def position_list(self): + if not self._positions: + self._init() + return self._positions + + def get(self, v): + return [p for p in self.position_list() if p['position']==v] + + def get_discuss(self): + return self.get("Discuss") + def get_yes(self): + return self.get("Yes") + def get_no_objection(self): + return self.get("No Objection") + def get_abstain(self): + return self.get("Abstain") + def get_recuse(self): + return self.get("Recuse") + def get_no_record(self): + return self.get("No Record") + + def get_texts(self): + return [p for p in self.position_list() if ('has_text' in p) and p['has_text']] + +def position_to_string(position): + positions = {"yes":"Yes", + "noobj":"No Objection", + "discuss":"Discuss", + "abstain":"Abstain", + "recuse":"Recuse"} + if not position: + return "No Record" + p = None + for k,v in positions.iteritems(): + if position.__dict__[k] > 0: + p = v + if not p: + p = "No Record" + return p + +def create_position_object(ballot, position): + positions = {"yes":"Yes", + "noobj":"No Objection", + "discuss":"Discuss", + "abstain":"Abstain", + "recuse":"Recuse"} + p = None + for k,v in positions.iteritems(): + if position.__dict__[k] > 0: + p = v + if not p: + p = "No Record" + r = {"ad_name":str(position.ad), "position":p} + if not position.ad.is_current_ad(): + r['is_old_ad'] = True + + was = [v for k,v in positions.iteritems() if position.__dict__[k] < 0] + if len(was) > 0: + r['old_positions'] = was + + try: + comment = ballot.comments.get(ad=position.ad) + if comment and comment.text: + r['has_text'] = True + r['comment_text'] = comment.text + r['comment_date'] = comment.date + r['comment_revision'] = str(comment.revision) + except IESGComment.DoesNotExist: + pass + + if p == "Discuss": + try: + discuss = ballot.discusses.get(ad=position.ad) + if discuss.text: + r['discuss_text'] = discuss.text + else: + r['discuss_text'] = '(empty)' + r['discuss_revision'] = str(discuss.revision) + r['discuss_date'] = discuss.date + except IESGDiscuss.DoesNotExist: + # this should never happen, but unfortunately it does + # fill in something to keep other parts of the code happy + r['discuss_text'] = "(error: discuss text not found)" + r['discuss_revision'] = "00" + r['discuss_date'] = date(2000, 1,1) + r['has_text'] = True + return r + diff --git a/ietf/idrfc/markup_txt.py b/ietf/idrfc/markup_txt.py new file mode 100644 index 0000000000..6e8991bef2 --- /dev/null +++ b/ietf/idrfc/markup_txt.py @@ -0,0 +1,69 @@ +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# 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. + +from django.utils.html import escape +import string +import re + +def markup(content): + # normalize line endings to LF only + content = content.replace("\r\n", "\n") + content = content.replace("\r", "\n") + + # at this point, "content" is normal string + # fix most common non-ASCII characters + t1 = string.maketrans("\x91\x92\x93\x94\x95\x96\x97\xc6\xe8\xe9", "\'\'\"\"o--\'ee") + # map everything except printable ASCII, TAB, LF, FF to "?" + t2 = string.maketrans('','') + t3 = "?"*9 + "\t\n?\f" + "?"*19 + t2[32:127] + "?"*129 + t4 = t1.translate(t3) + content = content.translate(t4) + + # remove leading white space + content = content.lstrip() + # remove runs of blank lines + content = re.sub("\n\n\n+", "\n\n", content) + + # expand tabs + escape + content = escape(content.expandtabs()) + + content = re.sub("\n(.+\[Page \d+\])\n\f\n(.+)\n", """\n\g<1>\n\g<2>\n""", content) + content = re.sub("\n(.+\[Page \d+\])\n\s*$", """\n\g<1>\n""", content) + # TODO: remove remaining FFs (to be valid XHTML) + + content = re.sub("\n\n([0-9]+\\.|[A-Z]\\.[0-9]|Appendix|Status of|Abstract|Table of|Full Copyright|Copyright|Intellectual Property|Acknowled|Author|Index)(.*)(?=\n\n)", """\n\n\g<1>\g<2>""", content) + + n = content.find("\n", 5000) + content1 = "
"+content[:n+1]+"
\n" + content2 = "
"+content[n+1:]+"
\n" + + return (content1, content2) diff --git a/ietf/idrfc/mirror_rfc_editor_queue.py b/ietf/idrfc/mirror_rfc_editor_queue.py index 5b1b06ae31..8626142607 100644 --- a/ietf/idrfc/mirror_rfc_editor_queue.py +++ b/ietf/idrfc/mirror_rfc_editor_queue.py @@ -68,7 +68,7 @@ def getChildText(parentNode, tagName): if event == pulldom.START_ELEMENT and node.tagName == "entry": events.expandNode(node) node.normalize() - draft_name = getChildText(node, "draft") + draft_name = getChildText(node, "draft").strip() if re.search("-\d\d\.txt$", draft_name): draft_name = draft_name[0:-7] date_received = getChildText(node, "date-received") diff --git a/ietf/idrfc/templatetags/__init__.py b/ietf/idrfc/templatetags/__init__.py new file mode 100644 index 0000000000..792d600548 --- /dev/null +++ b/ietf/idrfc/templatetags/__init__.py @@ -0,0 +1 @@ +# diff --git a/ietf/idrfc/templatetags/ballot_icon.py b/ietf/idrfc/templatetags/ballot_icon.py new file mode 100644 index 0000000000..0398773e81 --- /dev/null +++ b/ietf/idrfc/templatetags/ballot_icon.py @@ -0,0 +1,110 @@ +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# 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. + +from django import template +from ietf.idtracker.models import BallotInfo +from ietf.idrfc.idrfc_wrapper import position_to_string + +register = template.Library() + +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'] + else: + adId = None + red = 0 + green = 0 + gray = 0 + blank = 0 + my = None + for p in ballot.active_positions(): + if not p['pos']: + blank = blank + 1 + elif (p['pos'].yes > 0) or (p['pos'].noobj > 0): + green = green + 1 + elif (p['pos'].discuss > 0): + red = red + 1 + else: + 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)+"" + +def render_ballot_icon2(draft_name, tracker_id, red,green,gray,blank,my): + res = '' + for y in range(3): + res = res + "" + for x in range(5): + myMark = False + if red > 0: + c = "ballot_icon_red" + red = red - 1 + myMark = (my == "Discuss") + elif green > 0: + c = "ballot_icon_green" + green = green - 1 + myMark = (my == "Yes") or (my == "No Objection") + elif gray > 0: + c = "ballot_icon_gray" + gray = gray - 1 + myMark = (my == "Abstain") or (my == "Recuse") + else: + c = "" + myMark = (y == 2) and (x == 4) and (my == "No Record") + if myMark: + res = res + '' + res = res + '
' + my = None + else: + res = res + '' + res = res + '
' + return res + + +class BallotIconNode(template.Node): + def __init__(self, doc_var): + self.doc_var = doc_var + def render(self, context): + doc = template.resolve_variable(self.doc_var, context) + return render_ballot_icon(context, doc) + +def do_ballot_icon(parser, token): + try: + tagName, docName = token.split_contents() + except ValueError: + raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0] + return BallotIconNode(docName) + +register.tag('ballot_icon', do_ballot_icon) diff --git a/ietf/idrfc/templatetags/wg_menu.py b/ietf/idrfc/templatetags/wg_menu.py new file mode 100644 index 0000000000..a045c565cd --- /dev/null +++ b/ietf/idrfc/templatetags/wg_menu.py @@ -0,0 +1,78 @@ +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# 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. + +from django import template +from django.core.cache import cache +from django.template import RequestContext, Context, loader +from ietf.idtracker.models import InternetDraft, IETFWG, Area + +register = template.Library() + +area_short_names = { + 'ops':'Ops & Mgmt', + 'rai':'Real-time Apps & Infra' + } + +def get_wgs(): + wgs = IETFWG.objects.filter(group_type__type='WG').filter(status__status='Active').select_related().order_by('acronym.acronym') + areas = [] + for a in Area.objects.filter(status__status='Active').select_related().order_by('acronym.acronym'): + wglist = [] + for w in wgs: + if w.area.area == a: + wglist.append(w) + if len(wglist) > 0: + if a.area_acronym.acronym in area_short_names: + area_name = area_short_names[a.area_acronym.acronym] + else: + area_name = a.area_acronym.name + if area_name.endswith(" Area"): + area_name = area_name[:-5] + areas.append({'areaAcronym':a.area_acronym.acronym, 'areaName':area_name, 'areaObj':a, 'wgs':wglist}) + return areas + +class WgMenuNode(template.Node): + def __init__(self): + pass + def render(self, context): + x = cache.get('idrfc_wgmenu') + if x: + return x + areas = get_wgs() + x = loader.render_to_string('idrfc/base_wgmenu.html', {'areas':areas}) + cache.set('idrfc_wgmenu', x, 30*60) + return x + +def do_wg_menu(parser, token): + return WgMenuNode() + +register.tag('wg_menu', do_wg_menu) diff --git a/ietf/idrfc/urls.py b/ietf/idrfc/urls.py index 1bec6040df..77b7cbc1b2 100644 --- a/ietf/idrfc/urls.py +++ b/ietf/idrfc/urls.py @@ -31,8 +31,15 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from django.conf.urls.defaults import patterns -from ietf.idrfc import views +from ietf.idrfc import views_doc, views_search, views urlpatterns = patterns('', - (r'^test.html$', views.test) + (r'^test/$', views.test), + (r'^/?$', views_search.search_main), + (r'^search/$', views_search.search_results), + (r'^(?P[^/]+)/$', views_doc.document_main), + (r'^(?P[^/]+)/_debug.data$', views_doc.document_debug), + (r'^(?P[^/]+)/_comments.data$', views_doc.document_comments), + (r'^(?P[^/]+)/_ballot.data$', views_doc.document_ballot), + (r'^(?P[^/]+)/_versions.data$', views_doc.document_versions) ) diff --git a/ietf/idrfc/views_doc.py b/ietf/idrfc/views_doc.py new file mode 100644 index 0000000000..e7b242000f --- /dev/null +++ b/ietf/idrfc/views_doc.py @@ -0,0 +1,174 @@ +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# 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. + +import re +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 import markup_txt +from ietf import settings +from django.template import RequestContext +from django.template.defaultfilters import truncatewords_html +from ietf.idtracker.templatetags.ietf_filters import format_textarea, fill + +def document_debug(request, name): + r = re.compile("^rfc([0-9]+)$") + m = r.match(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) + else: + id = get_object_or_404(InternetDraft, filename=name) + doc = IdRfcWrapper(draft=id, findRfc=True) + 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) + + info = {} + content1 = None + content2 = None + f = None + try: + try: + f = open(settings.RFC_PATH+"rfc"+str(rfc_number)+".txt") + content = f.read() + (content1, content2) = markup_txt.markup(content) + except IOError: + content1 = "Error - can't find"+"rfc"+str(rfc_number)+".txt" + content2 = "" + finally: + if f: + f.close() + + return render_to_response('idrfc/doc_main_rfc.html', + {'content1':content1, 'content2':content2, + 'doc':doc, 'info':info}, + context_instance=RequestContext(request)); + +def document_main(request, name): + r = re.compile("^rfc([0-9]+)$") + m = r.match(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) + + info = {} + stream_id = doc.stream_id() + if stream_id == 2: + stream = " (IAB document)" + elif stream_id == 3: + stream = " (IRTF document)" + elif stream_id == 4: + stream = " (Independent submission via RFC Editor)" + elif doc.group_acronym(): + stream = " ("+doc.group_acronym().upper()+" WG document)" + else: + stream = " (Individual document)" + + if id.status.status == "Active": + info['type'] = "Active Internet-Draft"+stream + else: + info['type'] = "Old Internet-Draft"+stream + + info['has_pdf'] = (".pdf" in doc.file_types()) + + content1 = None + content2 = None + if doc.is_active_draft(): + f = None + try: + try: + f = open(settings.INTERNET_DRAFT_PATH+name+"-"+id.revision+".txt") + content = f.read() + (content1, content2) = markup_txt.markup(content) + except IOError: + content1 = "Error - can't find "+name+"-"+id.revision+".txt" + content2 = "" + finally: + if f: + f.close() + + return render_to_response('idrfc/doc_main_id.html', + {'content1':content1, 'content2':content2, + 'doc':doc, 'info':info}, + context_instance=RequestContext(request)); + +def document_comments(request, name): + id = get_object_or_404(IDInternal, draft__filename=name) + results = [] + commentNumber = 0 + for comment in id.public_comments(): + info = {} + r = re.compile(r'^(.*) by (?:)?([A-Z]\w+ [A-Z]\w+)(?:)?$') + m = r.match(comment.comment_text) + if m: + info['text'] = m.group(1) + info['by'] = m.group(2) + else: + info['text'] = comment.comment_text + info['by'] = comment.get_username() + info['textSnippet'] = truncatewords_html(format_textarea(fill(info['text'], 80)), 25) + info['snipped'] = info['textSnippet'][-3:] == "..." + info['commentNumber'] = commentNumber + commentNumber = commentNumber + 1 + results.append({'comment':comment, 'info':info}) + 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) + 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)) + +def document_versions(request, name): + draft = get_object_or_404(InternetDraft, filename=name) + ov = [] + ov.append({"draft_name":draft.filename, "revision":draft.revision, "revision_date":draft.revision_date}) + for d in [draft]+list(draft.replaces_set.all()): + for v in DraftVersions.objects.filter(filename=d.filename).order_by('-revision'): + if (d.filename == draft.filename) and (draft.revision == v.revision): + continue + 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)) diff --git a/ietf/idrfc/views_search.py b/ietf/idrfc/views_search.py new file mode 100644 index 0000000000..73f70bcade --- /dev/null +++ b/ietf/idrfc/views_search.py @@ -0,0 +1,217 @@ +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# 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. + +import re +from django import newforms as forms +from django.shortcuts import render_to_response +from django.db.models import Q +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 ietf.idindex.models import orgs +from ietf.utils import normalize_draftname + +class SearchForm(forms.Form): + name = forms.CharField(required=False) + author = forms.CharField(required=False) + rfcs = forms.BooleanField(required=False,initial=True) + activeDrafts = forms.BooleanField(required=False,initial=True) + oldDrafts = forms.BooleanField(required=False,initial=False) + + group = forms.CharField(required=False) + area = forms.ModelChoiceField(Area.objects.filter(status=Area.ACTIVE), empty_label="any area", required=False) + + ad = forms.ChoiceField(choices=(), required=False) + state = forms.ModelChoiceField(IDState.objects.all(), empty_label="any state", required=False) + subState = forms.ChoiceField(choices=(), required=False) + + def clean_name(self): + value = self.clean_data.get('name','') + return normalize_draftname(value) + def __init__(self, *args, **kwargs): + super(SearchForm, self).__init__(*args, **kwargs) + self.fields['ad'].choices = [('', 'any AD')] + [(ad.id, "%s %s" % (ad.first_name, ad.last_name)) for ad in IESGLogin.objects.filter(user_level=1).order_by('last_name')] + [('-99', '------------------')] + [(ad.id, "%s %s" % (ad.first_name, ad.last_name)) for ad in IESGLogin.objects.filter(user_level=2).order_by('last_name')] + self.fields['subState'].choices = [('', 'any substate'), ('0', 'no substate')] + [(state.sub_state_id, state.sub_state) for state in IDSubState.objects.all()] + +def search_query(query): + drafts = query['activeDrafts'] or query['oldDrafts'] + if (not drafts) and (not query['rfcs']): + return ([], {}) + + # Start by search InternetDrafts + idresults = [] + rfcresults = [] + MAX = 500 + maxReached = False + + prefix = "" + q_objs = [] + if query['ad'] or query['state'] or query['subState']: + prefix = "draft__" + if query['ad']: + q_objs.append(Q(job_owner=query['ad'])) + if query['state']: + q_objs.append(Q(cur_state=query['state'])) + if query['subState']: + q_objs.append(Q(cur_sub_state=query['subState'])) + + if query['name']: + q_objs.append(Q(**{prefix+"filename__icontains":query['name']})|Q(**{prefix+"title__icontains":query['name']})) + if query['author']: + q_objs.append(Q(**{prefix+"authors__person__last_name__icontains":query['author']})) + if query['group']: + q_objs.append(Q(**{prefix+"group__acronym":query['group']})) + if query['area']: + q_objs.append(Q(**{prefix+"group__ietfwg__areagroup__area":query['area']})) + if (not query['rfcs']) and query['activeDrafts'] and (not query['oldDrafts']): + q_objs.append(Q(**{prefix+"status":1})) + elif query['rfcs'] and query['activeDrafts'] and (not query['oldDrafts']): + q_objs.append(Q(**{prefix+"status":1})|Q(**{prefix+"status":3})) + elif query['rfcs'] and (not drafts): + q_objs.append(Q(**{prefix+"status":3})) + if prefix: + q_objs.append(Q(rfc_flag=0)) + matches = IDInternal.objects.filter(*q_objs) + else: + matches = InternetDraft.objects.filter(*q_objs) + if not query['activeDrafts']: + matches = matches.exclude(Q(**{prefix+"status":1})) + if not query['rfcs']: + matches = matches.exclude(Q(**{prefix+"status":3})) + if prefix: + matches = [id.draft for id in matches[:MAX]] + else: + matches = matches[:MAX] + if len(matches) == MAX: + maxReached = True + for id in matches: + if id.status.status == 'RFC': + rfcresults.append([id.rfc_number, id, None, None]) + else: + idresults.append([id]) + + # Next, search RFCs + if query['rfcs'] and not (query['ad'] or query['state'] or query['subState'] or query['area']): + q_objs = [] + searchRfcIndex = True + if query['name']: + r = re.compile("^\s*(?:RFC)?\s*(\d+)\s*$", re.IGNORECASE) + m = r.match(query['name']) + if m: + q_objs.append(Q(rfc_number__contains=m.group(1))|Q(title__icontains=query['name'])) + else: + q_objs.append(Q(title__icontains=query['name'])) + # We prefer searching RfcIndex, but it doesn't have group info + if query['group']: + searchRfcIndex = False + q_objs.append(Q(group_acronym=query['group'])) + if query['area']: + # TODO: not implemented yet + pass + if query['author'] and searchRfcIndex: + q_objs.append(Q(authors__icontains=query['author'])) + elif query['author']: + q_objs.append(Q(authors__person__last_name__icontains=query['author'])) + if searchRfcIndex: + matches = RfcIndex.objects.filter(*q_objs)[:MAX] + else: + matches = Rfc.objects.filter(*q_objs)[:MAX] + if len(matches) == MAX: + maxReached = True + for rfc in matches: + found = False + for r2 in rfcresults: + if r2[0] == rfc.rfc_number: + if searchRfcIndex: + r2[3] = rfc + else: + r2[2] = rfc + found = True + if not found: + if searchRfcIndex: + rfcresults.append([rfc.rfc_number, None, None, rfc]) + else: + rfcresults.append([rfc.rfc_number, None, rfc, None]) + + # Find missing InternetDraft objects + for r in rfcresults: + if not r[1]: + ids = InternetDraft.objects.filter(rfc_number=r[0]) + if len(ids) >= 1: + r[1] = ids[0] + if not r[1] and r[3] and r[3].draft: + ids = InternetDraft.objects.filter(filename=r[3].draft) + if len(ids) >= 1: + r[1] = ids[0] + + # Finally, find missing RFC objects + for r in rfcresults: + if not r[2]: + rfcs = Rfc.objects.filter(rfc_number=r[0]) + if len(rfcs) >= 1: + r[2] = rfcs[0] + if not r[3]: + rfcs = RfcIndex.objects.filter(rfc_number=r[0]) + if len(rfcs) >= 1: + r[3] = rfcs[0] + + results = [] + for res in idresults+rfcresults: + if len(res)==1: + doc = IdRfcWrapper(draft=res[0]) + else: + doc = IdRfcWrapper(draft=res[1], rfc=res[2], rfcIndex=res[3]) + results.append(doc) + results.sort(key=lambda obj: obj.view_sort_key()) + meta = {} + if maxReached: + meta['max'] = MAX + return (results,meta) + +def search_results(request): + form = SearchForm(request.REQUEST) + if not form.is_valid(): + return HttpResponse("form not valid?", mimetype="text/plain") + x = form.clean_data + (results,meta) = search_query(form.clean_data) + if 'ajax' in request.REQUEST and request.REQUEST['ajax']: + return render_to_response('idrfc/search_results.html', {'docs':results, 'meta':meta}, context_instance=RequestContext(request)) + else: + return render_to_response('idrfc/search_main.html', {'form':form, 'docs':results,'meta':meta}, context_instance=RequestContext(request)) + + +def search_main(request): + form = SearchForm() + return render_to_response('idrfc/search_main.html', {'form':form}, context_instance=RequestContext(request)) + diff --git a/ietf/idtracker/templatetags/ietf_filters.py b/ietf/idtracker/templatetags/ietf_filters.py index f24cae821f..6cb2d05371 100644 --- a/ietf/idtracker/templatetags/ietf_filters.py +++ b/ietf/idtracker/templatetags/ietf_filters.py @@ -226,6 +226,14 @@ def inpast(date): return date < datetime.datetime.now() return True +@register.filter(name='timesince_days') +def timesince_days(date): + """Returns the number of days since 'date' (relative to now)""" + if date.__class__ is not datetime.datetime: + date = datetime.datetime(date.year, date.month, date.day) + delta = datetime.datetime.now() - date + return delta.days + @register.filter(name='truncatemore') def truncatemore(text, arg): """Truncate the text if longer than 'words', and if truncated, @@ -278,6 +286,11 @@ def wrap_long_lines(text): filled += [ line.rstrip() ] return "\n".join(filled) +# based on http://www.djangosnippets.org/snippets/847/ by 'whiteinge' +@register.filter +def in_group(user, groups): + return user and user.is_authenticated() and bool(user.groups.filter(name__in=groups.split(',')).values('name')) + def _test(): import doctest doctest.testmod() diff --git a/ietf/iesg/urls.py b/ietf/iesg/urls.py index d933a3cdd8..8e12aa4c16 100644 --- a/ietf/iesg/urls.py +++ b/ietf/iesg/urls.py @@ -66,6 +66,7 @@ urlpatterns += patterns('', (r'^agenda/$', views.telechat_agenda), (r'^agenda/documents.txt$', views.telechat_agenda_documents), + (r'^discusses/$', views.discusses), (r'^ann/ind/$',views.inddocs), (r'^ann/(?P[^/]+)/$',views.wgdocs), ) diff --git a/ietf/iesg/views.py b/ietf/iesg/views.py index a9e1a18e9d..fb03f20f09 100644 --- a/ietf/iesg/views.py +++ b/ietf/iesg/views.py @@ -34,12 +34,15 @@ # Create your views here. #from django.views.generic.date_based import archive_index -from ietf.idtracker.models import IDInternal, InternetDraft,AreaGroup,IETFWG +from ietf.idtracker.models import IDInternal, InternetDraft,AreaGroup,IETFWG, Position from django.views.generic.list_detail import object_list +from django.views.generic.simple import direct_to_template 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 + import datetime def date_threshold(): @@ -169,3 +172,31 @@ def telechat_agenda_documents(request): t = loader.get_template('iesg/agenda_documents.txt') c = Context({'docs':docs}) return HttpResponse(t.render(c), mimetype='text/plain') + +def discusses(request): + positions = Position.objects.filter(discuss=1) + res = [] + try: + ids = set() + except NameError: + # for Python 2.3 + from sets import Set as set + ids = set() + + for p in positions: + try: + draft = p.ballot.drafts.filter(primary_flag=1) + 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}) + 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}) + + diff --git a/ietf/manage.py b/ietf/manage.py index 1e4ce8c9fb..ffeb26be41 100644 --- a/ietf/manage.py +++ b/ietf/manage.py @@ -6,7 +6,7 @@ import settings # Assumed to be in the same directory. except ImportError: import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.stderr.write("Error: Cannot find 'settings.py' or 'settings_local.py'.\nUsually these are in the directory containing %r.\n" % __file__) sys.exit(1) if __name__ == "__main__": diff --git a/ietf/settings.py b/ietf/settings.py index 77a4487348..5114dcab93 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -166,6 +166,14 @@ INTERNET_DRAFT_PATH = '/a/www/ietf-ftp/internet-drafts/' RFC_PATH = '/a/www/ietf-ftp/rfc/' +# Override this in settings_local.py if needed +if SERVER_MODE == 'production': + CACHE_BACKEND= 'file://'+'/a/www/ietf-datatracker/cache/' +else: + # Default to no caching in development/test, so that every developer + # doesn't have to set CACHE_BACKEND in settings_local + CACHE_BACKEND = 'dummy:///' + IPR_EMAIL_TO = ['ietf-ipr@ietf.org', ] # The number of days for which a password-request URL is valid diff --git a/ietf/templates/idrfc/base.html b/ietf/templates/idrfc/base.html new file mode 100644 index 0000000000..3827f950a8 --- /dev/null +++ b/ietf/templates/idrfc/base.html @@ -0,0 +1,111 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %} + + + +{% block title %}No title{% endblock %} + + + + +{% block pagehead %}{% endblock %} + + + + +
+datatracker.ietf.org +
+
+{% if user.is_authenticated %} +{{ user }} | Sign out +{% else %} +Sign in +{% endif %} +
+ + + + +
+
+{% include "idrfc/base_leftmenu.html" %} +
+
+ +
+ +{% block content %} +{% endblock %} + + + + + + + + + + + +{% block scripts %} +{% endblock %} + +{% block content_end %} +{% endblock %} +
+ +
+ +
+{% include "debug.html" %} + + + + diff --git a/ietf/templates/idrfc/base_leftmenu.html b/ietf/templates/idrfc/base_leftmenu.html new file mode 100644 index 0000000000..abcf4a453d --- /dev/null +++ b/ietf/templates/idrfc/base_leftmenu.html @@ -0,0 +1,83 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 wg_menu %} +{% load ietf_filters %} + diff --git a/ietf/templates/idrfc/base_wgmenu.html b/ietf/templates/idrfc/base_wgmenu.html new file mode 100644 index 0000000000..74c4af4e54 --- /dev/null +++ b/ietf/templates/idrfc/base_wgmenu.html @@ -0,0 +1,38 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %} +{% for area in areas %} +
  • {{area.areaName|escape }}
  • +{% endfor %} diff --git a/ietf/templates/idrfc/doc_ballot.html b/ietf/templates/idrfc/doc_ballot.html new file mode 100644 index 0000000000..ba16b8f50c --- /dev/null +++ b/ietf/templates/idrfc/doc_ballot.html @@ -0,0 +1,126 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 ietf_filters %} + + + + + + +
    + +

    Discuss
    +{% if ballot.get_discuss %} +{% for p in ballot.get_discuss %} +{{p.ad_name}} {% if p.has_text %}*{% endif %}
    +{% endfor %} +{% else %} +none +{% endif %} +

    + +

    Yes
    +{% if ballot.get_yes %} +{% for p in ballot.get_yes %} +{% if p.is_old_ad %}[{%endif%}{{p.ad_name}}{% if p.is_old_ad %}]{%endif%} {% if p.has_text %}*{% endif %}
    +{% endfor %} +{% else %} +none +{% endif %} +

    + +

    No Objection
    +{% if ballot.get_no_objection %} +{% for p in ballot.get_no_objection %} +{% if p.is_old_ad %}[{%endif%}{{p.ad_name}}{% if p.is_old_ad %}]{%endif%} {% if p.has_text %}*{% endif %}
    +{% endfor %} +{% else %} +none +{% endif %} +

    + +

    Abstain
    +{% if ballot.get_abstain %} +{% for p in ballot.get_abstain %} +{% if p.is_old_ad %}[{%endif%}{{p.ad_name}}{% if p.is_old_ad %}]{%endif%} {% if p.has_text %}*{% endif %}
    +{% endfor %} +{% else %} +none +{% endif %} +

    + +

    Recuse
    +{% if ballot.get_recuse %} +{% for p in ballot.get_recuse %} +{% if p.is_old_ad %}[{%endif%}{{p.ad_name}}{% if p.is_old_ad %}]{%endif%} {% if p.has_text %}*{% endif %}
    +{% endfor %} +{% else %} +none +{% endif %} +

    + +

    No Record
    +{% if ballot.get_no_record %} +{% for p in ballot.get_no_record %} +{% if p.is_old_ad %}[{%endif%}{{p.ad_name}}{% if p.is_old_ad %}]{%endif%} {% if p.has_text %}*{% endif %}
    +{% endfor %} +{% else %} +none +{% endif %} +

    + + +
    + +

    Discusses and other comments

    + +{% for pos in ballot.get_texts %} + +

    {{pos.ad_name|escape}}

    + +{% ifequal pos.position "Discuss" %} +

    Discuss ({{pos.discuss_date}})

    +
    {{pos.discuss_text|fill:"80"|escape }}
    +{% endifequal %} + +{% if pos.comment_text %} +

    Comment ({{pos.comment_date}})

    +
    {{pos.comment_text|fill:"80"|escape }}
    +{% endif %} + +{% endfor %} + + +
    \ No newline at end of file diff --git a/ietf/templates/idrfc/doc_comments.html b/ietf/templates/idrfc/doc_comments.html new file mode 100644 index 0000000000..e6d9ffe1b3 --- /dev/null +++ b/ietf/templates/idrfc/doc_comments.html @@ -0,0 +1,62 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 ietf_filters %} + +

    Document history

    + + + +{% for c in comments %} + + + + + + +{% endfor %} + +
    DateVersionByText
    {{ c.comment.date }}{{ c.comment.version }}{{ c.info.by|escape }}{% if c.comment.ballot %} +[Ballot {{ c.comment.get_ballot_display }}]
    +{% endif %} +{% if c.info.snipped %} +
    {{ c.info.textSnippet }}
    +[show all] + +{% else %} +{{ c.info.text|fill:"80"|format_textarea}} +{% endif %} +
    \ No newline at end of file diff --git a/ietf/templates/idrfc/doc_main_id.html b/ietf/templates/idrfc/doc_main_id.html new file mode 100644 index 0000000000..d486b760df --- /dev/null +++ b/ietf/templates/idrfc/doc_main_id.html @@ -0,0 +1,277 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %}{{ doc.draft_name_and_revision }}{% endblock %} + +{% block morecss %} + +#metabox { width: 99%; border:1px solid #cccccc; background:#edf5ff;margin-top:8px; padding:4px; margin-bottom:1em; } +#metatable { border: 0; border-spacing: 0; } +#metatable tr { vertical-align:top ;} +#metatools { padding:4px; border: 1px solid #cccccc; } + +#commentLog { margin-bottom: 1.5ex; } +.commentToggle { text-decoration: underline; color: blue; } + +.comment_date { white-space: nowrap; } + +div.diffTool { border: 1px solid #cccccc; background: #edf5ff; padding: 8px 4px; margin: 8px 0;} +.diffTool label { float:left; width:100px; } + +table.ietfTable { border-collapse:collapse; border:1px solid #7f7f7f; } +.ietfTable tr.evenrow { background-color: #EDF5FF; } +.ietfTable tr.oddrow {background-color: white; } +.ietfTable td { border-right: 1px solid #cbcbcb; padding:3px 6px; } +.ietfTable th { color:white; background: #2647A0; text-align:left; padding:3px 6px; border-right: 1px solid #7f7f7f; } + +.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;} +{% endblock %} + +{% block pagehead %} + +{%endblock %} + +{% block content %} +

    {{ doc.title|escape }}
    {{ doc.draft_name_and_revision }}

    + +
    + +
    + +
    + +
    + + + + + + +{% if doc.iesg_note %}{% endif %} + +{% if doc.is_active_draft %} + +{% else %} +{% endif %} + +{% comment %} +{% if doc.replaces %}
    Replaces {% for rep in doc.replaces %}{{rep}} {% endfor %}{% endif %} +{% endcomment %} +
    Document type:{{ info.type|escape }}
    State: +{{ 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 %}{{rep}} {% endfor %} {%endif %} +{% if doc.rfc_editor_state %}
    RFC Editor State: {{ doc.rfc_editor_state|escape }} {% endif %} +
    Last updated: {{ doc.revision_date|default:"(data missing)" }}
    Responsible AD:{{ doc.ad_name|default:"-"|escape }}
    IESG Note:{{ doc.iesg_note|escape }}
    Other versions: +plain text +{% for ext in doc.file_types %} +{% ifnotequal ext ".txt" %} +{{ext|cut:"."}} +{% endifnotequal %} +{% endfor %} +{% if not info.has_pdf %} +pdf +{% endif %} +
    + +
    +Email authors   + Dependencies to this draft   + IPR Disclosures   + Check nits   +{% if doc.in_iesg_tracker %} +Edit state (IESG Tracker) +{% else %} +Add to IESG Tracker +{% endif %} +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +
    + +
    +{% if doc.is_active_draft %} +
    +{{ content1 }} +
    +{% else %} +

    This Internet-Draft is no longer active. Unofficial copies of old Internet-Drafts can be found here:
    +http://tools.ietf.org/id/{{doc.draft_name}}.

    + +

    Abstract:
    {{ doc.abstract|escape }}

    + +

    Authors:
    +{% for author in doc.draft.authors.all %} + +{% if author.email %} +{{ author.person }} <{{author.email}}> +{% else %} +{% if author.person %} +{{ author.person }} +{% else %} +Missing author info #{{ author.person_id }} +{% endif %} +{% endif %}
    + +{% endfor %}

    + +

    (Note: The e-mail addresses provided for the authors of this Internet-Draft may no longer be valid)

    + +{% endif %} +
    +{% endblock %} + +{% block scripts %} + + + +{% endblock %} + +{% block content_end %} +
    +{% if doc.is_active_draft %} +
    +{{ content2 }} +
    +{% endif %} +
    +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/idrfc/doc_main_rfc.html b/ietf/templates/idrfc/doc_main_rfc.html new file mode 100644 index 0000000000..3ca3ba35ff --- /dev/null +++ b/ietf/templates/idrfc/doc_main_rfc.html @@ -0,0 +1,167 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %}RFC {{ doc.rfc_number }}{% endblock %} + +{% block morecss %} + +#metabox { width: 99%; border:1px solid #cccccc; background:#edf5ff;margin-top:8px; padding:4px; margin-bottom:1em; } +#metatable { border: 0; border-spacing: 0; } +#metatable tr { vertical-align:top ;} +#metatools { padding:4px; border: 1px solid #cccccc; } + +#commentLog { margin-bottom: 1.5ex; } +.commentToggle { text-decoration: underline; color: blue; } + +.comment_date { white-space: nowrap; } + +div.diffTool { border: 1px solid #cccccc; background: #edf5ff; padding: 8px 4px; margin: 8px 0;} +.diffTool label { float:left; width:100px; } + +table.ietfTable { border-collapse:collapse; border:1px solid #7f7f7f; } +.ietfTable tr.evenrow { background-color: #EDF5FF; } +.ietfTable tr.oddrow {background-color: white; } +.ietfTable td { border-right: 1px solid #cbcbcb; padding:3px 6px; } +.ietfTable th { color:white; background: #2647A0; text-align:left; padding:3px 6px; border-right: 1px solid #7f7f7f; } + +.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;} +{% endblock %} + +{% block pagehead %} + +{%endblock %} + +{% block content %} +

    {{ doc.title|escape }}
    RFC {{ doc.rfc_number }}

    + +
    + +
    + +
    + +
    + + + +
    Document type:RFC - {{ doc.rfc_maturity_level }}
    Published: {{ doc.revision_date|default:"(data missing)" }}
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    +{{ content1 }} +
    +
    +{% endblock %} + +{% block scripts %} + + + +{% endblock %} + +{% block content_end %} +
    +
    +{{ content2 }} +
    +
    +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/idrfc/doc_versions.html b/ietf/templates/idrfc/doc_versions.html new file mode 100644 index 0000000000..2335699a88 --- /dev/null +++ b/ietf/templates/idrfc/doc_versions.html @@ -0,0 +1,69 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %} + +

    Old versions and diffs

    + +
    +
    + +
    + +
    + + + +Side-by-side +Before-after +Change bars +Wdiff
    + + + +
    +
    + + + +{% for id in versions %} + +{% endfor %} +
    DateDocument
    {{id.revision_date}}{{id.draft_name}}-{{id.revision}}.txt
    diff --git a/ietf/templates/idrfc/search_form.html b/ietf/templates/idrfc/search_form.html new file mode 100644 index 0000000000..4dbca6102c --- /dev/null +++ b/ietf/templates/idrfc/search_form.html @@ -0,0 +1,132 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %} + +
    + +
    + {{ form.name }} +
    + +
    + + + + + +
    {{ form.rfcs }} RFCs
    {{ form.activeDrafts }} Internet-Drafts (active)
    {{ form.oldDrafts }} Internet-Drafts (expired/replaced/withdrawn)
    +
    + +[+] Advanced + + + +
    + + + + + + +
    + +
    + + \ No newline at end of file diff --git a/ietf/templates/idrfc/search_main.html b/ietf/templates/idrfc/search_main.html new file mode 100644 index 0000000000..ecc1e4bcc3 --- /dev/null +++ b/ietf/templates/idrfc/search_main.html @@ -0,0 +1,54 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 +{% endblock %} + +{% block content %} + +

    Internet-Drafts and RFCs

    + +
    +{% include "idrfc/search_form.html" %} +
    + +
    +{% if docs %} +{% include "idrfc/search_results.html" %} +{% endif %} +
    + +{% endblock %} diff --git a/ietf/templates/idrfc/search_result_row.html b/ietf/templates/idrfc/search_result_row.html new file mode 100644 index 0000000000..f6c0f3685a --- /dev/null +++ b/ietf/templates/idrfc/search_result_row.html @@ -0,0 +1,57 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 ietf_filters %} +{% load ballot_icon %} + + +{% if doc.is_rfc %}RFC {{doc.rfc_number}} +{% if doc.draft_name %}
    ({{doc.draft_name}}){%endif%} +{% else %}{{doc.draft_name_and_revision}}{% endif %} +{{ doc.title|escape }} +{{ doc.revision_date }} + +{{ doc.friendly_state|escape }} +{% if doc.is_rfc %} +{% if doc.has_rfc_errata %}
    Errata{% endif %} +{% else %} + {% if doc.draft_replaced_by %} by {% for rep in doc.draft_replaced_by %}{{rep}} {% endfor %} {%endif %} + {% if doc.last_call_ends %} (ends {{doc.last_call_ends}}){%endif%} + {% if doc.rfc_editor_state %}
    RFC Editor State: {{ doc.rfc_editor_state|escape }}{% endif %} +{% endif %} + +{% ballot_icon doc %} +{% if doc.ad_name %}{{ doc.ad_name|escape }}{% else %} {% endif %} + + \ No newline at end of file diff --git a/ietf/templates/idrfc/search_results.html b/ietf/templates/idrfc/search_results.html new file mode 100644 index 0000000000..6d9871a25f --- /dev/null +++ b/ietf/templates/idrfc/search_results.html @@ -0,0 +1,50 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %} + +{% if meta.max %} +

    Too many documents match the query! Returning partial result only.

    +{% endif %} +{% regroup docs by view_sort_group as grouped_docs %} + + + +{% for doc_group in grouped_docs %} + + +{% for doc in doc_group.list %} +{% include "idrfc/search_result_row.html" %} +{% endfor %} + +{% endfor %} +
    DocumentTitleDateStatusArea Director
    {{doc_group.grouper}}s
    diff --git a/ietf/templates/iesg/discusses.html b/ietf/templates/iesg/discusses.html new file mode 100644 index 0000000000..b6d856c270 --- /dev/null +++ b/ietf/templates/iesg/discusses.html @@ -0,0 +1,69 @@ +{% comment %} +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +All rights reserved. Contact: Pasi Eronen + +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 %}IESG Discuss Positions +{% endblock %} + +{% block morecss %} +{% endblock %} + +{% block content %} + +

    IESG Discuss Positions

    + +
    + + +{% for row in docs %} + + + + + + + +{% endfor %} +
    DocumentStatusArea DirectorDiscusses
    +{{row.doc.draft_name_and_revision}} +{{ row.doc.friendly_state|escape }}{% ballot_icon row.doc %}{% if row.doc.ad_name %}{{ row.doc.ad_name|escape }}{% else %} {% endif %} +{% 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}})
    +{% endfor %}
    +
    + +{% endblock %} \ No newline at end of file diff --git a/static/css/base2.css b/static/css/base2.css new file mode 100644 index 0000000000..192e827a13 --- /dev/null +++ b/static/css/base2.css @@ -0,0 +1,115 @@ +/* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. Contact: Pasi Eronen +* +* 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. +*/ + +body { margin: 0; } +.yui-skin-sam h1 {margin: 0.5em 0; font-size: 167%;} +.yui-skin-sam .yui-navset .yui-content { + background: white; + border:0px; + border-top:1px solid #243356; + padding:0.5em 0; +} +.yui-navset .disabled a em {color:#a0a0a0;} + +#ietf-login { color: white; } +#ietf-login a, #ietf-login a:visited { color: white; } + +.ballotTable .left { background: #edf5ff; width:150px; padding-left: 10px; } +.ballotTable .right { padding-left: 15px; padding-right:15px; width:610px;padding-top:0px;} +.ballotTable h2.ballot_ad { background: #2647A0; color:white; padding: 2px 4px; font-size: 108%; margin-top: 0;} +.ballotTable .right { background: white; } + +.mydialog button { margin-left: 8px; } +.mybutton { background-color:white; border: 1px outset #808080; padding: 1px 3px; } +.mybutton a { text-decoration: none; color: black; } + +.leftmenu { background-color: #edf5ff; padding:0; border: 1px solid #89d; } +.leftmenu ul { padding: 0; margin: 0; } +.leftmenu ul li { list-style: none; padding: 0; margin: 0; font-size: 90%; } +.leftmenu ul li a { display:block; padding: 2px 2px 2px 10px; } +.leftmenu ul li.sect { font-weight:bold; color:#fff; background:#2647A0; margin-top:2px; text-indent:2px; padding: 2px 0;} +.leftmenu ul li.first { margin-top: 0px; } +.leftmenu ul li a:hover { color:#fff; background: #e60; } + +.leftmenu .yuimenuitemlabel { font-size: 12px; padding: 0 10px; } +.leftmenu a.yuimenuitemlabel { color:#0000ee; /*text-decoration: underline;*/ } +.leftmenu #wgs .bd { background-color: #ecf5fa; } +.leftmenu #wgs > .bd { border: 0;} + +#search_form_box {width: 99.5%; border: 0px solid #cccccc; background:#edf5ff;margin-top:8px; padding:4px; margin-bottom:1em; padding-left:8px;} + +form#search_form { padding-top: 4px; padding-bottom: 4px; } +#search_form input { padding: 0; padding-left: 2px; border: 1px solid #89d;} +#search_form select { border: 1px solid #89d; } +#search_form div.search_field { margin-top:2px; } +#search_form label { width: 130px; float: left; } + +/* 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;} +/* give checkbox a fixed width so that IE6 aligns the left edge correctly */ + +#search_form #id_filename, +#search_form #id_author { width: 244px; } +#search_form #id_state, +#search_form #id_ad, +#search_form #id_positionAd { width:248px; } +#search_form #id_group {width: 120px; margin-right:4px; } +#search_form #id_area {width:120px; } + +.search_results table { border: 1px solid #7f7f7f; border-collapse:collapse; } +.search_results tr.header { border-top: 1px solid #7f7f7f; border-bottom: 1px solid #7f7f7f; border-left: 1px solid white; border-right:2px solid white;} +.search_results tr.header td {padding: 6px 6px; font-weight: bold; } +.search_results td { border-right: 1px solid #cbcbcb; padding: 3px 6px; } +.search_results th { border-right: 1px solid #7f7f7f; padding: 3px 6px; } +.search_results th { color: white; background:#2647A0; text-align: left; } +.search_results tr.evenrow { background-color: #EDF5FF; } +.search_results {} + +.search_results table { max-width: 1200px; } +.search_results th.doc, .search_results td.title { min-width:20em; max-width: 35em; } +.search_results th.title, .search_results td.title { min-width: 20em; max-width: 35em; } +.search_results th.date, .search_results td.date { white-space:nowrap; min-width: 6em;} +.search_results th.status, .search_results td.status { min-width: 20em;} +.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 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; } +td.ballot_icon_gray { background: #c0c0c0; } +table.ballot_icon td.ballot_icon_my { border: 3px outset black;} diff --git a/static/images/blue_dot.gif b/static/images/blue_dot.gif new file mode 100644 index 0000000000000000000000000000000000000000..6db2e1ac71fcfa9543558a46c4f340c16d620f76 GIT binary patch literal 934 zcmZ?wbhEHblwc5G_|Cv!xc9l`-seHbo+lrBo_+3lH3+@$x%Pa@wfA#?=-&IK_uj9) z_x{-P@7Lac|NegzjE2Cl3IQDkAOPhB299n9MGhH{4GRu7Gt25|C@eU@#LgtIpz=e( z5vamgZGuLjQVWZubCQq4#|6w2m6$DFbO<;eW8{@HP?+$s!JUKI$V}n}LvjP7xqed3 zg^!NM7|e^4QVx86>M)HZHc3Tbb7K&Lne99mNg*Yc6|DRPM`wI}*31;cEwEQ|;=zV) U``sfbq)@06^qAHf)4`sfbq)@073QG%yPg1r5de5^oU55GPKd7%;Ar@6ol+pqnmV=S y&bq2Hb&fT92CW=SryuV2EEbsc@bB?IyZ8-fYbM?D_hSND#^CAd=d#Wzp$PzAN`sfbq)@0RgODhLApSpXipc%kcwNrXE*X5au8v;SpJARuxIuH zSMw)lL@%&1I*CW@di;koM^P=xcSG={{tY&LrgxvtVJ~J|JVDCw`K?>C6ZQxC+rLV` tVRbP3^=>|L4L`47q literal 0 HcmV?d00001 diff --git a/static/images/title_line.gif b/static/images/title_line.gif new file mode 100644 index 0000000000000000000000000000000000000000..cbce33182409911131bef883d0af2e3a1a04842e GIT binary patch literal 1115 zcmZ?wbhEHbmx%gzl)<4|c{$0!OjKs#rN7IgLad_?A^z`%$S3JeYB z7dUsz`R>~C^74w{)p2KcZGC-xLvlZ#!|rWwZ|^9+FLq$}_V@P>G;_=Q-TB^d@AyQ1 zi+wda8=hTQ>^ +// +// 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. + +function showBallot(draftName, trackerId) { + + var handleEditPosition = function() { + IETF_DOCS.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(); + }; + var el; + + if (!IETF_DOCS.ballotDialog) { + el = document.createElement("div"); + el.innerHTML = ''; + 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", { + visible:false, draggable:false, close:true, modal:true, + width:"850px", fixedcenter:true, constraintoviewport:true, + buttons: buttons}); + IETF_DOCS.ballotDialog.render(); + } + document.getElementById("doc_ballot_dialog_name").innerHTML = draftName; + document.getElementById("doc_ballot_dialog_id").innerHTML = trackerId; + + IETF_DOCS.ballotDialog.show(); + + el = document.getElementById("doc_ballot_dialog_12"); + el.innerHTML = "Loading..."; + YAHOO.util.Connect.asyncRequest('GET', + "/doc/"+draftName+"/_ballot.data", + { success: function(o) { el.innerHTML = (o.responseText !== undefined) ? o.responseText : "?"; }, + failure: function(o) { el.innerHTML = "Error: "+o.status+" "+o.statusText; }, + argument: null + }, null); +}