From d33a6f3c0c8ff4f01c824ec4cca35a7badf8c514 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 2 Jun 2023 16:40:52 -0300 Subject: [PATCH 1/2] fix: Handle missing date fields in XML submissions (#5744) * refactor: Eliminate _construct_creation_date helper * fix: Use xml2rfc method for filling in missing date fields * fix: Set options.date for xml2rfc writers * test: Test handling of missing date element/fields --- ietf/submit/tests.py | 20 +++++++++++++- ietf/submit/utils.py | 4 +++ ietf/utils/draft.py | 62 ++++++++++++++---------------------------- ietf/utils/xmldraft.py | 22 +++++++++++---- 4 files changed, 60 insertions(+), 48 deletions(-) diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 2e9f2da71..e8972195c 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -3347,7 +3347,8 @@ class AsyncSubmissionTests(BaseSubmitTestCase): "test_submission.xml", title="Correct Draft Title", ) - xml_path.write_text(xml.read()) + xml_contents = xml.read() + xml_path.write_text(xml_contents) output = process_submission_xml("draft-somebody-test", "00") self.assertEqual(output["filename"], "draft-somebody-test") self.assertEqual(output["rev"], "00") @@ -3362,6 +3363,23 @@ class AsyncSubmissionTests(BaseSubmitTestCase): self.assertIsNone(output["formal_languages"]) self.assertEqual(output["xml_version"], "3") + # Should behave on missing or partial elements + xml_path.write_text(re.sub(r"", "", xml_contents)) # strip entirely + output = process_submission_xml("draft-somebody-test", "00") + self.assertEqual(output["document_date"], None) + + xml_path.write_text(re.sub(r")", r"\1 day=\2", xml_contents)) # remove month + output = process_submission_xml("draft-somebody-test", "00") + self.assertEqual(output["document_date"], date_today()) + + xml_path.write_text(re.sub(r"", r"", xml_contents)) # remove day + output = process_submission_xml("draft-somebody-test", "00") + self.assertEqual(output["document_date"], date_today()) + # name mismatch xml, _ = submission_file( "draft-somebody-wrong-name-00", # name that appears in the file diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py index 4ad441ae4..ec5af8efe 100644 --- a/ietf/submit/utils.py +++ b/ietf/submit/utils.py @@ -941,8 +941,10 @@ def render_missing_formats(submission): xmltree.tree = v2v3.convert2to3() # --- Prep the xml --- + today = date_today() prep = xml2rfc.PrepToolWriter(xmltree, quiet=True, liberal=True, keep_pis=[xml2rfc.V3_PI_TARGET]) prep.options.accept_prepped = True + prep.options.date = today xmltree.tree = prep.prep() if xmltree.tree == None: raise SubmissionError(f'Error from xml2rfc (prep): {prep.errors}') @@ -952,6 +954,7 @@ def render_missing_formats(submission): if not txt_path.exists(): writer = xml2rfc.TextWriter(xmltree, quiet=True) writer.options.accept_prepped = True + writer.options.date = today writer.write(txt_path) log.log( 'In %s: xml2rfc %s generated %s from %s (version %s)' % ( @@ -966,6 +969,7 @@ def render_missing_formats(submission): # --- Convert to html --- html_path = staging_path(submission.name, submission.rev, '.html') writer = xml2rfc.HtmlWriter(xmltree, quiet=True) + writer.options.date = today writer.write(str(html_path)) log.log( 'In %s: xml2rfc %s generated %s from %s (version %s)' % ( diff --git a/ietf/utils/draft.py b/ietf/utils/draft.py index ee2a129fb..a1e79760e 100755 --- a/ietf/utils/draft.py +++ b/ietf/utils/draft.py @@ -190,46 +190,6 @@ class Draft: def get_wordcount(self): raise NotImplementedError - @staticmethod - def _construct_creation_date(year, month, day=None): - """Construct a date for the document - - Roughly follows RFC 7991 section 2.17, but only allows missing day and - assumes the 15th if day is not specified month/year are not current. - - year: integer or string with 4-digit year - month: integer or string with numeric or English month. Some abbreviations recognized. - day: integer or string with numeric day of month. Optional. - - Raises ValueError if there is a problem interpreting the data - """ - year = int(year) - day = int(day) - if isinstance(month, str): - month = month.lower() - if month in month_names: - month = month_names.index(month) + 1 - elif month in month_names_abbrev3: - month = month_names_abbrev3.index(month) + 1 - elif month in month_names_abbrev4: - month = month_names_abbrev4.index(month) + 1 - elif month.isdigit() and int(month) in range(1, 13): - month = int(month) - else: - raise ValueError("Unrecognized month") - today = date_today() - if not day: - # if the date was given with only month and year, use - # today's date if month and year is today's month and - # year, otherwise pick the middle of the month. - # Don't use today's day for month and year in the past - if month == today.month and year == today.year: - day = today.day - else: - day = 15 - return datetime.date(year, month, day) - - # ---------------------------------------------------------------------- class PlaintextDraft(Draft): @@ -500,7 +460,27 @@ class PlaintextDraft(Draft): day = int( md.get( 'day', 0 ) ) year = int( md['year'] ) try: - self._creation_date = self._construct_creation_date(year, mon, day) + if mon in month_names: + month = month_names.index( mon ) + 1 + elif mon in month_names_abbrev3: + month = month_names_abbrev3.index( mon ) + 1 + elif mon in month_names_abbrev4: + month = month_names_abbrev4.index( mon ) + 1 + elif mon.isdigit() and int(mon) in range(1,13): + month = int(mon) + else: + continue + today = date_today() + if day==0: + # if the date was given with only month and year, use + # today's date if month and year is today's month and + # year, otherwise pick the middle of the month. + # Don't use today's day for month and year in the past + if month==today.month and year==today.year: + day = today.day + else: + day = 15 + self._creation_date = datetime.date(year, month, day) return self._creation_date except ValueError: # mon abbreviation not in _MONTH_NAMES diff --git a/ietf/utils/xmldraft.py b/ietf/utils/xmldraft.py index c0f5021bd..bdd10f813 100644 --- a/ietf/utils/xmldraft.py +++ b/ietf/utils/xmldraft.py @@ -1,5 +1,6 @@ # Copyright The IETF Trust 2022, All Rights Reserved # -*- coding: utf-8 -*- +import datetime import io import re import xml2rfc @@ -7,6 +8,8 @@ import xml2rfc import debug # pyflakes: ignore from contextlib import ExitStack +from xml2rfc.util.date import augment_date, extract_date +from ietf.utils.timezone import date_today from .draft import Draft @@ -136,12 +139,19 @@ class XMLDraft(Draft): def get_creation_date(self): date_elt = self.xmlroot.find("front/date") if date_elt is not None: - try: - year = date_elt.get("year") - month = date_elt.get("month") - return self._construct_creation_date(year, month, date_elt.get("day", None)) - except ValueError: - pass + # ths mimics handling of date elements in the xml2rfc text/html writers + today = date_today() + year, month, day = extract_date(date_elt, today) + year, month, day = augment_date(year, month, day, today) + if day is None: + # Must choose a day for a datetime.date. Per RFC 7991 sect 2.17, we use + # today's date if it is consistent with the rest of the date. Otherwise, + # arbitrariy (and consistent with the text parser) assume the 15th. + if year == today.year and month == today.month: + day = today.day + else: + day = 15 + return datetime.date(year, month, day) return None # todo fix the implementation of XMLDraft.get_abstract() From b77c5cd145c3a30cc8896b310de5d9d97fd4b1b9 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Fri, 2 Jun 2023 15:50:05 -0400 Subject: [PATCH 2/2] ci: fix semver not using release branch --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6b112ba62..356ba30d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,7 +62,7 @@ jobs: uses: ietf-tools/semver-action@v1 with: token: ${{ github.token }} - branch: main + branch: release skipInvalidTags: true - name: Set Next Version Env Var