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], + ] + )