Merged personal/rjs/v4.70@6042:

* Made reporting IPR consistant across document searches, IPR searches, AD document queues, last calls, and agendas. All these points now report on the document(s) being directly queried, and the documents those transitively replace or obsolete.

  * Brought search results against WGs and document titles into consistency with results from searching for individual documents

  * Added the IPR count to the link on the documents main page (when not zero)

  * Built on Henrik's reimplementation of all_related_*, making the *_related_* functions return DocAlias? lists consistently, and added corresponding _relations_ functions to get lists of actual RelatedDocument? objects.

  * Added getting the DocAlias? with the same name to Document

  * Added getting related IPR disclosures (as described in the first bullet) to Document

  * Simplified ipr/related.py

  * Removed the use of DraftLikeDocAlias? and IETFWG from ipr/search.py. Retooled the various search functions and templates to use DocAlias? and IprDocAlias? directly.

  * Removed dead code from ipr/search.py

  * Removed the special handling of WG 2000 from ipr/search.py 

  This fixes bug #1071
 - Legacy-Id: 6083
This commit is contained in:
Henrik Levkowetz 2013-09-02 18:34:54 +00:00
commit 38b0a59ba3
13 changed files with 138 additions and 267 deletions

View file

@ -235,51 +235,66 @@ class Document(DocumentInfo):
return "charter-ietf-%s" % self.chartered_group.acronym
return name
def canonical_docalias(self):
return self.docalias_set.get(name=self.name)
def display_name(self):
name = self.canonical_name()
if name.startswith('rfc'):
name = name.upper()
return name
def related_that(self, relationship):
"""Return the documents that are source of relationship targeting self."""
def relations_that(self, relationship):
"""Return the related-document objects that describe a given relationship targeting self."""
if isinstance(relationship, str):
relationship = [ relationship ]
if isinstance(relationship, tuple):
relationship = list(relationship)
if not isinstance(relationship, list):
raise TypeError("Expected a string, tuple or list, received %s" % type(relationship))
return Document.objects.filter(relateddocument__target__document=self, relateddocument__relationship__in=relationship)
return RelatedDocument.objects.filter(target__document=self, relationship__in=relationship).select_related('source')
def related_that_doc(self, relationship):
"""Return the doc aliases that are target of relationship originating from self."""
def all_relations_that(self, relationship, related=None):
if not related:
related = []
rels = self.relations_that(relationship)
for r in rels:
if not r in related:
related += [ r ]
related = r.source.all_relations_that(relationship, related)
return related
def relations_that_doc(self, relationship):
"""Return the related-document objects that describe a given relationship from self to other documents."""
if isinstance(relationship, str):
relationship = [ relationship ]
if isinstance(relationship, tuple):
relationship = list(relationship)
if not isinstance(relationship, list):
raise TypeError("Expected a string, tuple or list, received %s" % type(relationship))
return DocAlias.objects.filter(relateddocument__source=self, relateddocument__relationship__in=relationship)
return RelatedDocument.objects.filter(source=self, relationship__in=relationship).select_related('target__document')
def all_relations_that_doc(self, relationship, related=None):
if not related:
related = []
rels = self.relations_that_doc(relationship)
for r in rels:
if not r in related:
related += [ r ]
related = r.target.document.all_relations_that_doc(relationship, related)
return related
def related_that(self, relationship):
return list(set([x.source.docalias_set.get(name=x.source.name) for x in self.relations_that(relationship)]))
def all_related_that(self, relationship, related=None):
if related is None:
related = []
rel = self.related_that(relationship)
for doc in rel:
if not doc in related:
related += [ doc ]
related = doc.document.all_related_that(relationship, related)
return related
return list(set([x.source.docalias_set.get(name=x.source.name) for x in self.all_relations_that(relationship)]))
def related_that_doc(self, relationship):
return list(set([x.target for x in self.relations_that_doc(relationship)]))
def all_related_that_doc(self, relationship, related=None):
if related is None:
related = []
rel = self.related_that_doc(relationship)
for alias in rel:
if not alias in related:
related += [ alias ]
related = alias.document.all_related_that_doc(relationship, related)
return related
return list(set([x.target for x in self.all_relations_that_doc(relationship)]))
def telechat_date(self, e=None):
if not e:
@ -352,7 +367,7 @@ class Document(DocumentInfo):
elif state.slug == "repl":
rs = self.related_that("replaces")
if rs:
return mark_safe("Replaced by " + ", ".join("<a href=\"%s\">%s</a>" % (urlreverse('doc_view', kwargs=dict(name=name)), name) for name in rs))
return mark_safe("Replaced by " + ", ".join("<a href=\"%s\">%s</a>" % (urlreverse('doc_view', kwargs=dict(name=alias.document)), alias.document) for alias in rs))
else:
return "Replaced"
elif state.slug == "active":
@ -383,6 +398,12 @@ class Document(DocumentInfo):
from ietf.ipr.models import IprDocAlias
return IprDocAlias.objects.filter(doc_alias__document=self)
def related_ipr(self):
"""Returns the IPR disclosures against this document and those documents this
document directly or indirectly obsoletes or replaces
"""
from ietf.ipr.models import IprDocAlias
return IprDocAlias.objects.filter(doc_alias__in=list(self.docalias_set.all())+self.all_related_that_doc(['obs','replaces']))
class RelatedDocHistory(models.Model):

View file

@ -49,6 +49,7 @@ from ietf.utils.history import find_history_active_at
from ietf.ietfauth.utils import *
from ietf.doc.views_status_change import RELATION_SLUGS as status_change_relationships
from ietf.wgcharter.utils import historic_milestones_for_charter
from ietf.ipr.models import IprDocAlias
def render_document_top(request, doc, tab, name):
tabs = []
@ -92,7 +93,7 @@ def document_main(request, name, rev=None):
group = doc.group
if doc.type_id == 'conflrev':
conflictdoc = doc.related_that_doc('conflrev').get().document
conflictdoc = doc.related_that_doc('conflrev')[0].document
revisions = []
for h in doc.history_set.order_by("time", "id"):
@ -278,11 +279,11 @@ def document_main(request, name, rev=None):
search_archive = urllib.quote(search_archive, safe="~")
# conflict reviews
conflict_reviews = [d.name for d in doc.related_that("conflrev")]
conflict_reviews = [d.document.name for d in doc.related_that("conflrev")]
status_change_docs = doc.related_that(status_change_relationships)
status_changes = [ rel for rel in status_change_docs if rel.get_state_slug() in ('appr-sent','appr-pend')]
proposed_status_changes = [ rel for rel in status_change_docs if rel.get_state_slug() in ('needshep','adrev','iesgeval','defer','appr-pr')]
status_changes = [ rel.document for rel in status_change_docs if rel.document.get_state_slug() in ('appr-sent','appr-pend')]
proposed_status_changes = [ rel.document for rel in status_change_docs if rel.document.get_state_slug() in ('needshep','adrev','iesgeval','defer','appr-pr')]
# remaining actions
actions = []
@ -345,9 +346,9 @@ def document_main(request, name, rev=None):
replaces=[d.name for d in doc.related_that_doc("replaces")],
replaced_by=[d.name for d in doc.related_that("replaces")],
updates=[prettify_std_name(d.name) for d in doc.related_that_doc("updates")],
updated_by=[prettify_std_name(d.canonical_name()) for d in doc.related_that("updates")],
updated_by=[prettify_std_name(d.document.canonical_name()) for d in doc.related_that("updates")],
obsoletes=[prettify_std_name(d.name) for d in doc.related_that_doc("obs")],
obsoleted_by=[prettify_std_name(d.canonical_name()) for d in doc.related_that("obs")],
obsoleted_by=[prettify_std_name(d.document.canonical_name()) for d in doc.related_that("obs")],
conflict_reviews=conflict_reviews,
status_changes=status_changes,
proposed_status_changes=proposed_status_changes,

View file

@ -147,7 +147,7 @@ def generate_last_call_announcementREDESIGN(request, doc):
doc.filled_title = textwrap.fill(doc.title, width=70, subsequent_indent=" " * 3)
iprs, _ = iprs_from_docs(related_docs(DocAlias.objects.get(name=doc.canonical_name()),[]))
iprs, _ = iprs_from_docs(related_docs(DocAlias.objects.get(name=doc.canonical_name())))
if iprs:
ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(ipr_id=i.ipr_id)) for i in iprs]
ipr_links = [ settings.IDTRACKER_BASE_URL+url if not url.startswith("http") else url for url in ipr_links ]

View file

@ -44,6 +44,7 @@ from ietf.doc.models import *
from ietf.person.models import *
from ietf.group.models import *
from ietf.ipr.models import IprDocAlias
from ietf.ipr.search import related_docs
from ietf.idindex.index import active_drafts_index_by_group
class SearchForm(forms.Form):
@ -135,9 +136,32 @@ def fill_in_search_attributes(docs):
for d in docs:
d.iprs = []
# Consider reworking the following block using all_relations_that_doc? That might simplify the final assembly
# down to the code at "if a not in docs_dict"...
rel_docs = []
rel_id_camefrom = {}
for d in docs:
if isinstance(d,DocAlias):
d = d.document
rel_this_doc = d.all_related_that_doc(['replaces','obs'])
for rel in rel_this_doc:
rel_id_camefrom.setdefault(rel.document.pk,[]).append(d.pk)
rel_docs += [x.document for x in rel_this_doc]
ipr_docaliases = IprDocAlias.objects.filter(doc_alias__document__in=doc_ids).select_related('doc_alias')
for a in ipr_docaliases:
docs_dict[a.doc_alias.document_id].iprs.append(a)
rel_docs_dict = dict((d.pk, d) for d in rel_docs)
rel_doc_ids = rel_docs_dict.keys()
rel_ipr_docaliases = IprDocAlias.objects.filter(doc_alias__document__in=rel_doc_ids).select_related('doc_alias')
for a in rel_ipr_docaliases:
if a.doc_alias.document_id in rel_id_camefrom:
for k in rel_id_camefrom[a.doc_alias.document_id]:
if a not in docs_dict[k].iprs:
docs_dict[k].iprs.append(a)
# telechat date, can't do this with above query as we need to get TelechatDocEvents out
seen = set()

View file

@ -1,137 +1,15 @@
# Copyright The IETF Trust 2007, All Rights Reserved
from django.conf import settings
from django.db.models import Q
from ietf.idtracker.models import InternetDraft, Rfc
inverse = {
'updates': 'is_updated_by',
'is_updated_by': 'updates',
'obsoletes': 'is_obsoleted_by',
'is_obsoleted_by': 'obsoletes',
'replaces': 'is_replaced_by',
'is_replaced_by': 'replaces',
'is_rfc_of': 'is_draft_of',
'is_draft_of': 'is_rfc_of',
}
display_relation = {
'updates': 'that updated',
'is_updated_by': 'that was updated by',
'obsoletes': 'that obsoleted',
'is_obsoleted_by': 'that was obsoleted by',
'replaces': 'that replaced',
'is_replaced_by': 'that was replaced by',
'is_rfc_of': 'which came from',
'is_draft_of': 'that was published as',
}
def set_related(obj, rel, target):
#print obj, rel, target
# remember only the first relationship we find.
if not hasattr(obj, "related"):
obj.related = target
obj.relation = display_relation[rel]
return obj
def set_relation(first, rel, second):
set_related(first, rel, second)
set_related(second, inverse[rel], first)
def related_docs(doc, found = []):
"""Get a list of document related to the given document.
"""
#print "\nrelated_docs(%s, %s)" % (doc, found)
found.append(doc)
if isinstance(doc, Rfc):
try:
item = InternetDraft.objects.get(rfc_number=doc.rfc_number)
if not item in found:
set_relation(doc, 'is_rfc_of', item)
found = related_docs(item, found)
except InternetDraft.DoesNotExist:
pass
for entry in doc.updated_or_obsoleted_by.all():
item = entry.rfc
if not item in found:
action = inverse[entry.action.lower()]
set_relation(doc, action, item)
found = related_docs(item, found)
for entry in doc.updates_or_obsoletes.all():
item = entry.rfc_acted_on
if not item in found:
action = entry.action.lower()
set_relation(doc, action, item)
found = related_docs(item, found)
if isinstance(doc, InternetDraft):
if doc.replaced_by_id:
item = doc.replaced_by
if not item in found:
set_relation(doc, 'is_replaced_by', item)
found = related_docs(item, found)
for item in doc.replaces_set.all():
if not item in found:
set_relation(doc, 'replaces', item)
found = related_docs(item, found)
if doc.rfc_number:
item = Rfc.objects.get(rfc_number=doc.rfc_number)
if not item in found:
set_relation(doc, 'is_draft_of', item)
found = related_docs(item, found)
return found
def related_docsREDESIGN(alias, _):
"""Get related document aliases to given alias through depth-first search."""
from ietf.doc.models import RelatedDocument
from ietf.doc.proxy import DraftLikeDocAlias
mapping = dict(
updates='that updated',
obs='that obsoleted',
replaces='that replaced',
)
inverse_mapping = dict(
updates='that was updated by',
obs='that was obsoleted by',
replaces='that was replaced by',
)
def related_docs(alias):
results = list(alias.document.docalias_set.all())
res = [ alias ]
remaining = [ alias ]
while remaining:
a = remaining.pop()
related = RelatedDocument.objects.filter(relationship__in=mapping.keys()).filter(Q(source=a.document) | Q(target=a))
for r in related:
if r.source == a.document:
found = DraftLikeDocAlias.objects.filter(pk=r.target_id)
inverse = True
else:
found = DraftLikeDocAlias.objects.filter(document=r.source)
inverse = False
rels = alias.document.all_relations_that_doc(['replaces','obs'])
for x in found:
if not x in res:
x.related = a
x.relation = (inverse_mapping if inverse else mapping)[r.relationship_id]
res.append(x)
remaining.append(x)
# there's one more source of relatedness, a draft can have been published
aliases = DraftLikeDocAlias.objects.filter(document=a.document).exclude(pk__in=[x.pk for x in res])
for oa in aliases:
rel = None
if a.name.startswith("rfc") and oa.name.startswith("draft"):
rel = "that was published as"
elif a.name.startswith("draft") and oa.name.startswith("rfc"):
rel = "which came from"
if rel:
oa.related = a
oa.relation = rel
res.append(oa)
remaining.append(oa)
return res
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
related_docs = related_docsREDESIGN
for rel in rels:
rel_aliases = list(rel.target.document.docalias_set.all())
for x in rel_aliases:
x.related = rel
x.relation = rel.relationship.revname
results += rel_aliases
return list(set(results))

View file

@ -3,15 +3,15 @@
import codecs
import re
import os.path
import django.utils.html
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import render_to_response as render
from django.template import RequestContext
from django.conf import settings
from django.http import Http404
from ietf.idtracker.models import IETFWG, InternetDraft, Rfc
from ietf.ipr.models import IprRfc, IprDraft, IprDetail
from ietf.ipr.models import IprDraft, IprDetail
from ietf.ipr.related import related_docs
from ietf.utils import log, normalize_draftname
from ietf.group.models import Group
from ietf.doc.models import DocAlias
def mark_last_doc(iprs):
@ -24,16 +24,9 @@ def mark_last_doc(iprs):
def iprs_from_docs(docs):
iprs = []
for doc in docs:
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.ipr.models import IprDocAlias
disclosures = [ x.ipr for x in IprDocAlias.objects.filter(doc_alias=doc, ipr__status__in=[1,3]) ]
elif isinstance(doc, InternetDraft):
disclosures = [ item.ipr for item in IprDraft.objects.filter(document=doc, ipr__status__in=[1,3]) ]
elif isinstance(doc, Rfc):
disclosures = [ item.ipr for item in IprRfc.objects.filter(document=doc, ipr__status__in=[1,3]) ]
else:
raise ValueError("Doc type is neither draft nor rfc: %s" % doc)
from ietf.ipr.models import IprDocAlias
disclosures = [ x.ipr for x in IprDocAlias.objects.filter(doc_alias=doc, ipr__status__in=[1,3]) ]
doc.iprs = None
if disclosures:
doc.iprs = disclosures
iprs += disclosures
@ -54,11 +47,7 @@ def patent_file_search(url, q):
return False
def search(request, type="", q="", id=""):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.group.models import Group
wgs = Group.objects.filter(type="wg").exclude(acronym="2000").select_related().order_by("acronym")
else:
wgs = IETFWG.objects.filter(group_type__group_type_id=1).exclude(group_acronym__acronym='2000').select_related().order_by('acronym.acronym')
wgs = Group.objects.filter(type="wg").select_related().order_by("acronym")
args = request.REQUEST.items()
if args:
for key, value in args:
@ -78,40 +67,22 @@ def search(request, type="", q="", id=""):
if type == "document_search":
if q:
q = normalize_draftname(q)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.doc.proxy import DraftLikeDocAlias
start = DraftLikeDocAlias.objects.filter(name__contains=q, name__startswith="draft")
else:
start = InternetDraft.objects.filter(filename__contains=q)
start = DocAlias.objects.filter(name__contains=q, name__startswith="draft")
if id:
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.doc.proxy import DraftLikeDocAlias
start = DraftLikeDocAlias.objects.filter(name=id)
else:
try:
id = int(id,10)
except:
id = -1
start = InternetDraft.objects.filter(id_document_tag=id)
start = DocAlias.objects.filter(name=id)
if type == "rfc_search":
if q:
try:
q = int(q, 10)
except:
q = -1
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.doc.proxy import DraftLikeDocAlias
start = DraftLikeDocAlias.objects.filter(name__contains=q, name__startswith="rfc")
else:
start = Rfc.objects.filter(rfc_number=q)
start = DocAlias.objects.filter(name__contains=q, name__startswith="rfc")
if start.count() == 1:
first = start[0]
doc = str(first)
# get all related drafts, then search for IPRs on all
docs = related_docs(first, [])
#docs = get_doclist.get_doclist(first)
docs = related_docs(first)
iprs, docs = iprs_from_docs(docs)
iprs.sort(key=lambda x:(x.submitted_date,x.ipr_id))
return render("ipr/search_doc_result.html", {"q": q, "first": first, "iprs": iprs, "docs": docs, "doc": doc },
context_instance=RequestContext(request) )
elif start.count():
@ -162,23 +133,16 @@ def search(request, type="", q="", id=""):
# Search by wg acronym
# Document list with IPRs
elif type == "wg_search":
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.doc.proxy import DraftLikeDocAlias
try:
docs = list(DraftLikeDocAlias.objects.filter(document__group__acronym=q))
docs += list(DraftLikeDocAlias.objects.filter(document__relateddocument__target__in=docs, document__relateddocument__relationship="replaces"))
except:
docs = []
else:
try:
docs = list(InternetDraft.objects.filter(group__acronym=q))
except:
docs = []
docs += [ draft.replaced_by for draft in docs if draft.replaced_by_id ]
docs += list(Rfc.objects.filter(group_acronym=q))
docs = list(DocAlias.objects.filter(document__group__acronym=q))
related = []
for doc in docs:
doc.product_of_this_wg = True
related += related_docs(doc)
docs = [ doc for doc in docs if doc.ipr.count() ]
iprs, docs = iprs_from_docs(docs)
iprs, docs = iprs_from_docs(list(set(docs+related)))
docs = [ doc for doc in docs if doc.iprs ]
docs = sorted(docs,key=lambda x: max([ipr.submitted_date for ipr in x.iprs]),reverse=True)
count = len(iprs)
return render("ipr/search_wg_result.html", {"q": q, "docs": docs, "count": count },
context_instance=RequestContext(request) )
@ -186,21 +150,15 @@ def search(request, type="", q="", id=""):
# Search by rfc and id title
# Document list with IPRs
elif type == "title_search":
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
from ietf.doc.proxy import DraftLikeDocAlias
try:
docs = list(DraftLikeDocAlias.objects.filter(document__title__icontains=q))
except:
docs = []
else:
try:
docs = list(InternetDraft.objects.filter(title__icontains=q))
except:
docs = []
docs += list(Rfc.objects.filter(title__icontains=q))
docs = list(DocAlias.objects.filter(document__title__icontains=q))
related = []
for doc in docs:
related += related_docs(doc)
iprs, docs = iprs_from_docs(list(set(docs+related)))
docs = [ doc for doc in docs if doc.iprs ]
docs = sorted(docs,key=lambda x: max([ipr.submitted_date for ipr in x.iprs]),reverse=True)
docs = [ doc for doc in docs if doc.ipr.count() ]
iprs, docs = iprs_from_docs(docs)
count = len(iprs)
return render("ipr/search_doctitle_result.html", {"q": q, "docs": docs, "count": count },
context_instance=RequestContext(request) )
@ -220,9 +178,6 @@ def search(request, type="", q="", id=""):
else:
raise Http404("Unexpected search type in IPR query: %s" % type)
return django.http.HttpResponseRedirect(request.path)
return HttpResponseRedirect(request.path)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
for wg in wgs:
wg.group_acronym = wg # proxy group_acronym for select box
return render("ipr/search.html", {"wgs": wgs}, context_instance=RequestContext(request))

View file

@ -131,14 +131,6 @@ def show(request, ipr_id=None, removed=None):
context_instance=RequestContext(request))
def form(request):
wgs = IETFWG.objects.filter(group_type__group_type_id=1).exclude(group_acronym__acronym='2000').select_related().order_by('acronym.acronym')
log("Search form")
return render("ipr/search.html", {"wgs": wgs}, context_instance=RequestContext(request))
# ---- Helper functions ------------------------------------------------------
def get_section_list(ipr):

View file

@ -222,7 +222,7 @@
<div class="links">
<a href="mailto:{{ doc.name }}@tools.ietf.org?subject=Mail%20regarding%20{{ doc.name }}" rel="nofollow">Email Authors</a>
| <a href="{% url ipr_search %}?option=document_search&amp;id={{ doc.name }}" rel="nofollow">IPR Disclosures</a>
| <a href="{% url ipr_search %}?option=document_search&amp;id={{ doc.name }}" rel="nofollow">IPR Disclosures{% if doc.related_ipr %} ({{doc.related_ipr.count}}){% endif %}</a>
| <a href="http://www.fenron.net/~fenner/ietf/deps/index.cgi?dep={{ name }}" rel="nofollow">Dependencies to this document</a>
| <a href="http://tools.ietf.org/idnits?url=http://tools.ietf.org/id/{{ doc.filename_with_rev }}" rel="nofollow" target="_blank">Check nits</a>
| <a href="/feed/document-changes/{{ name }}/">History feed</a>

View file

@ -81,7 +81,7 @@ label { float:left; width: 200px; }
<select name="wg_search">
<option value="">--Select WG</option>
{% for wg in wgs %}
<option value="{{ wg.group_acronym.acronym }}">{{ wg.group_acronym.acronym }}</option>{% endfor %}
<option value="{{ wg.acronym }}">{{ wg.acronym }}</option>{% endfor %}
</select>
<input type="submit" value="SEARCH" width="15">
</form>

View file

@ -7,8 +7,8 @@
<h3>Please select one of following I-Ds</h3>
<ul>
{% for doc in docs %}
<li><a href="?option=document_search&id_document_tag={{ doc.id_document_tag }}">{{ doc.filename }}</a></li>
{% for docalias in docs %}
<li><a href="?option=document_search&id_document_tag={{ docalias.document }}">{{ docalias.document }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -5,7 +5,7 @@
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3">Total number of IPR disclosures found: {{ iprs|length }} </td></tr>
{% for ipr in iprs|dictsort:"submitted_date" %}
{% for ipr in iprs %}
<tr valign="top" bgcolor="#dadada">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
@ -18,7 +18,7 @@
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr >
<td colspan="3">
Search result on {{ doc|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.title|escape }}"{% ifnotequal doc first %}{% if doc.related %}, {{ doc.relation }} {{ doc.related|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.related.title }}"{% endif %}
Search result on {{ doc.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.document.title|escape }}"{% ifnotequal doc first %}{% if doc.related %}, that was {{ doc.relation|lower }} {{ doc.related.source|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.related.source.title }}"{% endif %}
{% endifnotequal %}
</td>
</tr>
@ -34,7 +34,7 @@
<tr>
<td></td>
<td colspan="2">
No IPR disclosures have been submitted directly on <i>{{ doc|rfcspace|lstrip:"0" }}</i>{% if iprs %},
No IPR disclosures have been submitted directly on <i>{{ doc.name|rfcspace|lstrip:"0" }}</i>{% if iprs %},
but there are disclosures on {% ifequal docs|length 2 %}a related document{% else %}related documents{% endifequal %}, listed on this page{% endif %}.
</b>
</td>

View file

@ -3,7 +3,7 @@
{% load ietf_filters %}
{% block search_result %}
<table cellpadding="1" cellspacing="0" border="0">
<tr><td colspan="3"><b>{% block search_header %}{% if not count %}Search result on {{ q }}{% else %}Document Title Search Result{% endif %}{% endblock %}</b></td></tr>
<tr><td colspan="3"><b>{% block search_header %}Search result on {{ q }}{% endblock %}</b></td></tr>
{% if not count %}
<tr>
<td></td>
@ -15,16 +15,16 @@
<tr><td colspan="3">Total number of IPR disclosures found: {{ count }} </td></tr>
{% block iprlist %}
{% for doc in docs %}
{% for alias in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr >
<td colspan="3">
IPR that is related to <b><i>{{ doc|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.title|escape }}"{% if doc.related %}, {{ doc.relation }} {{ doc.related|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.related.title }}"{% endif %},
</i></b>which has the string <b>"<i>{{ q }}</i>"</b> within the document title.
IPR that is related to <b><i>{{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title|escape }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title }}"{% endif %}
</i><!--,</b> which has the string <b>"<i>{{ q }}</i>"</b> within the document title.-->
</td>
</tr>
{% if doc.iprs %}
{% for ipr in doc.iprs %}
{% if alias.iprs %}
{% for ipr in alias.iprs %}
<tr valign="top">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
@ -41,7 +41,7 @@
{% else %}
<tr>
<td></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ doc|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ alias.name|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
</tr>
{% endif %}
</tbody>

View file

@ -16,16 +16,16 @@
<tr><td colspan="3">Total number of IPR disclosures found: {{ count }} </td></tr>
{% block iprlist %}
{% for doc in docs %}
{% for alias in docs %}
<tbody bgcolor="#{% cycle dadada,eaeaea as bgcolor %}">
<tr >
<td colspan="3">
IPR that is related to <b><i>{{ doc|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.title|escape }}"{% if doc.related %}, {{ doc.relation }} {{ doc.related|rfcspace|lstrip:"0"|rfcnospace }}, "{{ doc.related.title|escape }}"{% endif %}
</i></b> which is a product of Working Group <b><i>{{ q }}</i></b>
IPR that is related to <b><i>{{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title|escape }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title|escape }}"{% endif %}
</i></b>{% if alias.product_of_this_wg %} which is a product of Working Group <b><i>{{ q }}</i></b>{% endif %}
</td>
</tr>
{% if doc.iprs %}
{% for ipr in doc.iprs %}
{% if alias.iprs %}
{% for ipr in alias.iprs %}
<tr valign="top">
<td width="100">{{ ipr.submitted_date }}</td>
<td width="90"><li>ID # {{ ipr.ipr_id }}</li></td>
@ -42,7 +42,7 @@
{% else %}
<tr>
<td></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ doc|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
<td colspan="2"><b>No IPR disclosures related to <i>{{ alias.name|rfcspace|lstrip:"0" }}</i> have been submitted</b></td>
</tr>
{% endif %}
</tbody>