Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions ietf/sync/rfcindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from ietf.utils.log import log

FORMATS_FOR_INDEX = ["txt", "html", "pdf", "xml", "ps"]
SS_TXT_MARGIN = 3
SS_TXT_CUE_COL_WIDTH = 14


def format_rfc_number(n):
Expand Down Expand Up @@ -267,6 +269,87 @@ def get_rfc_text_index_entries():
return entries


def subseries_text_line(line, first=False):
"""Return subseries text entry line"""
indent = " " * SS_TXT_CUE_COL_WIDTH
if first:
initial_indent = " " * SS_TXT_MARGIN
else:
initial_indent = indent
return fill(
line,
initial_indent=initial_indent,
subsequent_indent=indent,
width=80,
break_on_hyphens=False,
)


def get_bcp_text_index_entries():
"""Returns BCP entries for bcp-index.txt"""
entries = []

highest_bcp_number = (
Document.objects.filter(type_id="bcp")
.annotate(
number=Cast(
Substr("name", 4, None),
output_field=models.IntegerField(),
)
)
.order_by("-number")
.first()
.number
)

for bcp_number in range(1, highest_bcp_number + 1):
bcp_name = f"BCP{bcp_number}"
bcp = Document.objects.filter(type_id="bcp", name=f"{bcp_name.lower()}").first()

if bcp:
entry = subseries_text_line(
(
f"[{bcp_name}]"
f"{' ' * (SS_TXT_CUE_COL_WIDTH - len(bcp_name) - 2 - SS_TXT_MARGIN)}"
f"Best Current Practice {bcp_number},"
),
first=True,
)
entry += "\n"
entry += subseries_text_line(
f"<{settings.RFC_EDITOR_INFO_BASE_URL}{bcp_name.lower()}>."
)
entry += "\n"
entry += subseries_text_line(
"At the time of writing, this BCP comprises the following:"
)
entry += "\n\n"
rfcs = sorted(bcp.contains(), key=lambda x: x.rfc_number)
for rfc in rfcs:
authors = ", ".join(
author.format_for_titlepage() for author in rfc.rfcauthor_set.all()
)
entry += subseries_text_line(
(
f'{authors}, "{rfc.title}", BCP¶{bcp_number}, RFC¶{rfc.rfc_number}, '
f"DOI¶{rfc.doi}, {rfc.pub_date().strftime('%B %Y')}, "
f"<{settings.RFC_EDITOR_INFO_BASE_URL}rfc{rfc.rfc_number}>."
)
).replace("¶", " ")
entry += "\n\n"
else:
entry = subseries_text_line(
(
f"[{bcp_name}]"
f"{' ' * (SS_TXT_CUE_COL_WIDTH - len(bcp_name) - 2 - SS_TXT_MARGIN)}"
f"Best Current Practice {bcp_number} currently contains no RFCs"
),
first=True,
)
entries.append(entry)
return entries


def add_subseries_xml_index_entries(rfc_index, ss_type, include_all=False):
"""Add subseries entries for rfc-index.xml"""
# subseries docs annotated with numeric number
Expand Down Expand Up @@ -481,3 +564,18 @@ def create_rfc_xml_index():
pretty_print=4,
)
save_to_red_bucket("rfc-index.xml", pretty_index)


def create_bcp_txt_index():
"""Create text index of BCPs"""
DATE_FMT = "%m/%d/%Y"
created_on = timezone.now().strftime(DATE_FMT)
log("Creating bcp-index.txt")
index = render_to_string(
"sync/bcp-index.txt",
{
"created_on": created_on,
"bcps": get_bcp_text_index_entries(),
},
)
save_to_red_bucket("bcp-index.txt", index)
69 changes: 65 additions & 4 deletions ietf/sync/tests_rfcindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@
from django.test.utils import override_settings
from lxml import etree

from ietf.doc.factories import PublishedRfcDocEventFactory, IndividualRfcFactory
from ietf.doc.factories import (
BcpFactory,
IndividualRfcFactory,
PublishedRfcDocEventFactory,
)
from ietf.name.models import DocTagName
from ietf.sync.rfcindex import (
create_bcp_txt_index,
create_rfc_txt_index,
create_rfc_xml_index,
format_rfc_number,
save_to_red_bucket,
get_unusable_rfc_numbers,
get_april1_rfc_numbers,
get_publication_std_levels,
get_unusable_rfc_numbers,
save_to_red_bucket,
subseries_text_line,
)
from ietf.utils.test_utils import TestCase

Expand Down Expand Up @@ -69,6 +75,9 @@ def setUp(self):
).doc
self.rfc.tags.add(DocTagName.objects.get(slug="errata"))

# Create a BCP with non-April Fools RFC
self.bcp = BcpFactory(contains=[self.rfc], name="bcp11")

# Set up a publication-std-levels.json file to indicate the publication
# standard of self.rfc as different from its current value
red_bucket.save(
Expand Down Expand Up @@ -137,7 +146,7 @@ def test_create_rfc_xml_index(self, mock_save):

children = list(index) # elements as list
# Should be one rfc-not-issued-entry
self.assertEqual(len(children), 3)
self.assertEqual(len(children), 14)
self.assertEqual(
[
c.find(f"{ns}doc-id").text
Expand Down Expand Up @@ -184,6 +193,53 @@ def test_create_rfc_xml_index(self, mock_save):
[(f"{ns}month", "April"), (f"{ns}year", "2021")],
)

@override_settings(RFCINDEX_INPUT_PATH="input/")
@mock.patch("ietf.sync.rfcindex.save_to_red_bucket")
def test_create_bcp_txt_index(self, mock_save):
create_bcp_txt_index()
self.assertEqual(mock_save.call_count, 1)
self.assertEqual(mock_save.call_args[0][0], "bcp-index.txt")
contents = mock_save.call_args[0][1]
self.assertTrue(isinstance(contents, str))
# starts from 1
self.assertIn(
"[BCP1]",
contents,
)
# fill up to 11
self.assertIn(
"[BCP10]",
contents,
)
# but not to 12
self.assertNotIn(
"[BCP12]",
contents,
)
# Test empty BCPs
self.assertIn(
"Best Current Practice 9 currently contains no RFCs",
contents,
)
# No zero prefix!
self.assertNotIn(
"[BCP0001]",
contents,
)
# Has BCP11 with a RFC
self.assertIn(
"Best Current Practice 11,",
contents,
)
self.assertIn(
f'"{self.rfc.title}"',
contents,
)
self.assertIn(
f'BCP 11, RFC {self.rfc.rfc_number},',
contents,
)


class HelperTests(TestCase):
def test_format_rfc_number(self):
Expand Down Expand Up @@ -234,3 +290,8 @@ def test_get_publication_std_levels_raises(self):
with self.assertRaises(json.JSONDecodeError):
get_publication_std_levels()
red_bucket.delete("publication-std-levels.json")

def test_subseries_text_line(self):
text = "foobar"
self.assertEqual(subseries_text_line(line=text, first=True), f" {text}")
self.assertEqual(subseries_text_line(line=text), f" {text}")
52 changes: 52 additions & 0 deletions ietf/templates/sync/bcp-index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BCP INDEX
-------------

(CREATED ON: {{created_on}}.)

This file contains citations for all BCPs in numeric order. The BCPs
form a sub-series of the RFC document series, specifically those RFCs
with the status BEST CURRENT PRACTICE.

BCP citations appear in this format:

[BCP#] Best Current Practice #,
<BCP URL>.
At the time of writing, this BCP comprises the following:

Author 1, Author 2, "Title of the RFC", BCP #, RFC №,
DOI DOI string, Issue date,
<RFC URL>.

For example:

[BCP3] Best Current Practice 3,
<https://www.rfc-editor.org/info/bcp3>.
At the time of writing, this BCP comprises the following:

F. Kastenholz, "Variance for The PPP Compression Control Protocol
and The PPP Encryption Control Protocol", BCP 3, RFC 1915,
DOI 10.17487/RFC1915, February 1996,
<https://www.rfc-editor.org/info/rfc1915>.

Key to fields:

# is the BCP number.

№ is the RFC number.

BCPs and other RFCs may be obtained from https://www.rfc-editor.org.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BCP INDEX
---------



{% for bcp in bcps %}{{bcp|safe}}

{% endfor %}
Loading