commit
adf2a99a68
|
@ -700,6 +700,8 @@ class RelatedDocument(models.Model):
|
|||
|
||||
if self.source.type_id == "rfc":
|
||||
source_lvl = self.source.std_level_id
|
||||
elif self.source.type_id in ["bcp","std"]:
|
||||
source_lvl = self.source.type_id
|
||||
else:
|
||||
source_lvl = self.source.intended_std_level_id
|
||||
|
||||
|
@ -711,6 +713,8 @@ class RelatedDocument(models.Model):
|
|||
target_lvl = 'unkn'
|
||||
else:
|
||||
target_lvl = self.target.std_level_id
|
||||
elif self.target.type_id in ["bcp", "std"]:
|
||||
target_lvl = self.target.type_id
|
||||
else:
|
||||
if not self.target.intended_std_level:
|
||||
target_lvl = 'unkn'
|
||||
|
|
|
@ -309,6 +309,12 @@ class MiscTests(TestCase):
|
|||
found = fuzzy_find_documents(draft.name, '22')
|
||||
self.assertCountEqual(found.documents, [draft],
|
||||
'Should find document even if rev does not exist')
|
||||
|
||||
# by rfc name mistakenly trying to provide a revision
|
||||
found = fuzzy_find_documents(rfc.name+"-22")
|
||||
self.assertCountEqual(found.documents, [rfc], "Should ignore versions when fuzzyfinding RFCs" )
|
||||
found = fuzzy_find_documents(rfc.name,"22")
|
||||
self.assertCountEqual(found.documents, [rfc], "Should ignore versions when fuzzyfinding RFCs" )
|
||||
|
||||
|
||||
def test_fuzzy_find_documents(self):
|
||||
|
|
|
@ -1209,14 +1209,15 @@ def fuzzy_find_documents(name, rev=None):
|
|||
|
||||
if name.startswith("rfc"):
|
||||
sought_type = "rfc"
|
||||
log.assertion("rev is None")
|
||||
name = name.split("-")[0] # strip any noise (like a revision) at and after the first hyphen
|
||||
rev = None # If someone is looking for an RFC and supplies a version, ignore it.
|
||||
else:
|
||||
sought_type = "draft"
|
||||
|
||||
# see if we can find a document using this name
|
||||
docs = Document.objects.filter(name=name, type_id=sought_type)
|
||||
if rev and not docs.exists():
|
||||
# No document found, see if the name/rev split has been misidentified.
|
||||
if sought_type == "draft" and rev and not docs.exists():
|
||||
# No draft found, see if the name/rev split has been misidentified.
|
||||
# Handles some special cases, like draft-ietf-tsvwg-ieee-802-11.
|
||||
name = '%s-%s' % (name, rev)
|
||||
docs = Document.objects.filter(name=name, type_id='draft')
|
||||
|
|
|
@ -740,14 +740,31 @@ def dependencies(request, acronym, group_type=None):
|
|||
source__type="draft",
|
||||
relationship__slug__startswith="ref",
|
||||
)
|
||||
|
||||
both_rfcs = Q(source__type_id="rfc", target__type_id="rfc")
|
||||
inactive = Q(source__states__slug__in=["expired", "repl"])
|
||||
rfc_or_subseries = {"rfc", "bcp", "fyi", "std"}
|
||||
both_rfcs = Q(source__type_id="rfc", target__type_id__in=rfc_or_subseries)
|
||||
pre_rfc_draft_to_rfc = Q(
|
||||
source__states__type="draft",
|
||||
source__states__slug="rfc",
|
||||
target__type_id__in=rfc_or_subseries,
|
||||
)
|
||||
both_pre_rfcs = Q(
|
||||
source__states__type="draft",
|
||||
source__states__slug="rfc",
|
||||
target__type_id="draft",
|
||||
target__states__type="draft",
|
||||
target__states__slug="rfc",
|
||||
)
|
||||
inactive = Q(
|
||||
source__states__type="draft",
|
||||
source__states__slug__in=["expired", "repl"],
|
||||
)
|
||||
attractor = Q(target__name__in=["rfc5000", "rfc5741"])
|
||||
removed = Q(source__states__slug__in=["auth-rm", "ietf-rm"])
|
||||
removed = Q(source__states__type="draft", source__states__slug__in=["auth-rm", "ietf-rm"])
|
||||
relations = (
|
||||
RelatedDocument.objects.filter(references)
|
||||
.exclude(both_rfcs)
|
||||
.exclude(pre_rfc_draft_to_rfc)
|
||||
.exclude(both_pre_rfcs)
|
||||
.exclude(inactive)
|
||||
.exclude(attractor)
|
||||
.exclude(removed)
|
||||
|
@ -755,8 +772,8 @@ def dependencies(request, acronym, group_type=None):
|
|||
|
||||
links = set()
|
||||
for x in relations:
|
||||
target_state = x.target.get_state_slug("draft")
|
||||
if target_state != "rfc" or x.is_downref():
|
||||
always_include = x.target.type_id not in rfc_or_subseries and x.target.get_state_slug("draft") != "rfc"
|
||||
if always_include or x.is_downref():
|
||||
links.add(x)
|
||||
|
||||
replacements = RelatedDocument.objects.filter(
|
||||
|
@ -771,13 +788,12 @@ def dependencies(request, acronym, group_type=None):
|
|||
graph = {
|
||||
"nodes": [
|
||||
{
|
||||
"id": x.name,
|
||||
"rfc": x.get_state("draft").slug == "rfc",
|
||||
"post-wg": not x.get_state("draft-iesg").slug
|
||||
in ["idexists", "watching", "dead"],
|
||||
"expired": x.get_state("draft").slug == "expired",
|
||||
"replaced": x.get_state("draft").slug == "repl",
|
||||
"group": x.group.acronym if x.group.acronym != "none" else "",
|
||||
"id": x.became_rfc().name if x.became_rfc() else x.name,
|
||||
"rfc": x.type_id == "rfc" or x.became_rfc() is not None,
|
||||
"post-wg": x.get_state_slug("draft-iesg") not in ["idexists", "watching", "dead"],
|
||||
"expired": x.get_state_slug("draft") == "expired",
|
||||
"replaced": x.get_state_slug("draft") == "repl",
|
||||
"group": x.group.acronym if x.group and x.group.acronym != "none" else "",
|
||||
"url": x.get_absolute_url(),
|
||||
"level": x.intended_std_level.name
|
||||
if x.intended_std_level
|
||||
|
@ -789,8 +805,8 @@ def dependencies(request, acronym, group_type=None):
|
|||
],
|
||||
"links": [
|
||||
{
|
||||
"source": x.source.name,
|
||||
"target": x.target.name,
|
||||
"source": x.source.became_rfc().name if x.source.became_rfc() else x.source.name,
|
||||
"target": x.target.became_rfc().name if x.target.became_rfc() else x.target.name,
|
||||
"rel": "downref" if x.is_downref() else x.relationship.slug,
|
||||
}
|
||||
for x in links
|
||||
|
|
|
@ -14,7 +14,7 @@ from collections import defaultdict
|
|||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.cache import cache
|
||||
from django.db.models import Count, Q
|
||||
from django.db.models import Count, Q, Subquery, OuterRef
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.urls import reverse as urlreverse
|
||||
|
@ -34,7 +34,7 @@ from ietf.group.models import Role, Group
|
|||
from ietf.person.models import Person
|
||||
from ietf.name.models import ReviewResultName, CountryName, DocRelationshipName, ReviewAssignmentStateName
|
||||
from ietf.person.name import plain_name
|
||||
from ietf.doc.models import Document, State, DocEvent
|
||||
from ietf.doc.models import Document, RelatedDocument, State, DocEvent
|
||||
from ietf.meeting.models import Meeting
|
||||
from ietf.stats.models import MeetingRegistration, CountryAlias
|
||||
from ietf.stats.utils import get_aliased_affiliations, get_aliased_countries, compute_hirsch_index
|
||||
|
@ -607,15 +607,31 @@ def document_stats(request, stats_type=None):
|
|||
|
||||
doc_years = defaultdict(set)
|
||||
|
||||
docevent_qs = DocEvent.objects.filter(
|
||||
draftevent_qs = DocEvent.objects.filter(
|
||||
doc__type="draft",
|
||||
type__in=["published_rfc", "new_revision"],
|
||||
).values_list("doc", "time").order_by("doc")
|
||||
type = "new_revision",
|
||||
).values_list("doc","time").order_by("doc")
|
||||
|
||||
for doc_id, time in docevent_qs.iterator():
|
||||
for doc_id, time in draftevent_qs.iterator():
|
||||
# RPC_TZINFO is used to match the timezone handling in Document.pub_date()
|
||||
doc_years[doc_id].add(time.astimezone(RPC_TZINFO).year)
|
||||
|
||||
rfcevent_qs = (
|
||||
DocEvent.objects.filter(doc__type="rfc", type="published_rfc")
|
||||
.annotate(
|
||||
draft=Subquery(
|
||||
RelatedDocument.objects.filter(
|
||||
target=OuterRef("doc__pk"), relationship_id="became_rfc"
|
||||
).values_list("source", flat=True)[:1]
|
||||
)
|
||||
)
|
||||
.values_list("draft", "time")
|
||||
.order_by("draft")
|
||||
)
|
||||
|
||||
for doc_id, time in rfcevent_qs.iterator():
|
||||
doc_years[doc_id].add(time.astimezone(RPC_TZINFO).year)
|
||||
|
||||
person_qs = Person.objects.filter(person_filters)
|
||||
|
||||
if document_type == "rfc":
|
||||
|
|
Loading…
Reference in a new issue