diff --git a/ietf/sync/bibxml.py b/ietf/sync/bibxml.py
index 43018d37d4..b273b06524 100644
--- a/ietf/sync/bibxml.py
+++ b/ietf/sync/bibxml.py
@@ -81,6 +81,25 @@ def get_fyi_bibxml(fyi_number):
return f"""{rfc_bibxml}"""
+def get_id_bibxml(draft_name, doc):
+ """Return BibXML entry for the given I-D doc"""
+ name = "-".join(draft_name.split("-", 2)[1:])
+ date = ""
+ if doc.is_dochistory():
+ latest_event = doc.latest_event(type="new_revision", rev=doc.rev)
+ if latest_event:
+ doc.pub_date = latest_event.time
+ date = doc.pub_date.strftime('')
+ else:
+ date = doc.pub_date().strftime('')
+ link = f"https://datatracker.ietf.org/doc/html/{draft_name}-{doc.rev}"
+ authors = ""
+ for author in doc.author_persons_or_names():
+ authors += f""""""
+
+ return f"""{doc.title}{date}{authors}{doc.abstract}"""
+
+
def save_bibxml(bibxml, filename):
"""Prettify and save given BibXML"""
@@ -156,3 +175,31 @@ def recreate_rfcsubseries_bibxml():
filename = f"bibxml-rfcsubseries/fyi{fyi_number}.xml"
bibxml = get_fyi_bibxml(fyi_number)
save_bibxml(bibxml, filename)
+
+
+def recreate_id_bibxml_by_draft_name(draft_name):
+ """Creates BibXML for given draft_name."""
+ doc = Document.objects.get(name=draft_name)
+ name = "-".join(draft_name.split("-", 2)[1:])
+
+ # revision less BibXML
+ bibxml = get_id_bibxml(draft_name, doc)
+ filename = f"bibxml-ids/reference.I-D.{name}.xml"
+ save_bibxml(bibxml, filename)
+
+ # draft BibXML for each revision
+ for revision in reversed(doc.revisions_by_newrevisionevent()):
+ doc_rev = doc.history_set.order_by("-time").filter(rev=revision).first()
+ bibxml = get_id_bibxml(draft_name, doc_rev)
+ filename = f"bibxml-ids/reference.I-D.{draft_name}-{revision}.xml"
+ save_bibxml(bibxml, filename)
+
+
+def recreate_id_bibxml():
+ """Creates BibXML for all Internet Drafts."""
+ for draft_name in (
+ Document.objects.filter(type_id="draft")
+ .values_list("name", flat=True)
+ .order_by("-time")
+ ):
+ recreate_id_bibxml_by_draft_name(draft_name)
diff --git a/ietf/sync/tests_bibxml.py b/ietf/sync/tests_bibxml.py
index 264bf450f2..e35f5d754f 100644
--- a/ietf/sync/tests_bibxml.py
+++ b/ietf/sync/tests_bibxml.py
@@ -11,12 +11,16 @@
FyiFactory,
PublishedRfcDocEventFactory,
StdFactory,
+ WgDraftFactory,
)
from ietf.sync.bibxml import (
get_bcp_bibxml,
get_fyi_bibxml,
+ get_id_bibxml,
get_rfc_bibxml,
get_std_bibxml,
+ recreate_id_bibxml,
+ recreate_id_bibxml_by_draft_name,
recreate_rfc_bibxml,
recreate_rfcsubseries_bibxml,
save_bibxml,
@@ -48,6 +52,9 @@ def setUp(self):
# Create a FYI with non-April Fools RFC
self.fyi = FyiFactory(contains=[self.rfc], name="fyi3")
+ # Create a draft with multiple revisions
+ self.draft = WgDraftFactory(create_revisions=(0, 1, 2))
+
def test_get_rfc_bibxml(self):
bibxml = get_rfc_bibxml(self.rfc.rfc_number)
self.assertIsNotNone(ElementTree.fromstring(bibxml))
@@ -93,6 +100,25 @@ def test_get_fyi_bibxml(self):
)
self.assertIn('', bibxml)
+ def test_get_id_bibxml(self):
+ draft_name = self.draft.name
+
+ # revisionless test
+ bibxml = get_id_bibxml(draft_name, self.draft)
+ self.assertIsNotNone(ElementTree.fromstring(bibxml))
+ self.assertIn(draft_name, bibxml)
+ self.assertIn(f"{draft_name}-02", bibxml)
+
+ # revision test
+ for revision in self.draft.revisions_by_newrevisionevent():
+ draft_rev = (
+ self.draft.history_set.order_by("-time").filter(rev=revision).first()
+ )
+ bibxml = get_id_bibxml(draft_name, draft_rev)
+ self.assertIsNotNone(ElementTree.fromstring(bibxml))
+ self.assertIn(draft_name, bibxml)
+ self.assertIn(f"{draft_name}-{revision}", bibxml)
+
def test_save_to_bucket(self):
bibxml_bucket = storages["bibxml_bucket"]
with override_settings(BIBXML_DELETE_THEN_WRITE=False):
@@ -185,3 +211,39 @@ def test_recreate_rfcsubseries_bibxml(self, mock_save_bibxml):
call(ANY, fyi_filename),
]
)
+
+ @patch("ietf.sync.bibxml.save_bibxml")
+ def test_recreate_id_bibxml_by_draft_name(self, mock_save_bibxml):
+ draft_name = self.draft.name
+ name = "-".join(draft_name.split("-", 2)[1:])
+
+ recreate_id_bibxml_by_draft_name(draft_name)
+ revision_less_filename = f"bibxml-ids/reference.I-D.{name}.xml"
+ revisioned_file_names = [
+ f"bibxml-ids/reference.I-D.{draft_name}-{r}.xml"
+ for r in reversed(self.draft.revisions_by_newrevisionevent())
+ ]
+ mock_save_bibxml.assert_has_calls(
+ [
+ call(ANY, revision_less_filename),
+ *[call(ANY, file_name) for file_name in revisioned_file_names],
+ ]
+ )
+
+ @patch("ietf.sync.bibxml.save_bibxml")
+ def test_recreate_id_bibxml(self, mock_save_bibxml):
+ draft_name = self.draft.name
+ name = "-".join(draft_name.split("-", 2)[1:])
+
+ recreate_id_bibxml()
+ revision_less_filename = f"bibxml-ids/reference.I-D.{name}.xml"
+ revisioned_file_names = [
+ f"bibxml-ids/reference.I-D.{draft_name}-{r}.xml"
+ for r in reversed(self.draft.revisions_by_newrevisionevent())
+ ]
+ mock_save_bibxml.assert_has_calls(
+ [
+ call(ANY, revision_less_filename),
+ *[call(ANY, file_name) for file_name in revisioned_file_names],
+ ]
+ )