From 0fe90cc291350fe513cc6804acf5c2fbecc768d7 Mon Sep 17 00:00:00 2001 From: Jonas Wielicki Date: Mon, 11 Sep 2017 17:40:47 +0200 Subject: [PATCH] tools: Implement modification of XEPs in deferrals.py --- tools/deferrals.py | 74 +++++++++++++++++++++++++++++++++++++++++-- tools/send-updates.py | 19 ++++++++++- tools/xeplib.py | 5 +-- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/tools/deferrals.py b/tools/deferrals.py index 6674385c..f2b70a13 100755 --- a/tools/deferrals.py +++ b/tools/deferrals.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +import re + import xml.etree.ElementTree as etree from datetime import datetime, timedelta @@ -17,6 +19,51 @@ def get_deferred(accepted): yield info +EXPERIMENTAL_STATUS = "Experimental" +DEFERRED_STATUS = "Deferred" +REVISION_RE = re.compile(r"\s+") +REVISION_TEMPLATE = """ + + {version} + {now:%Y-%m-%d} + XEP Editor ({initials}) + Defer due to lack of activity. + """ + + +def defer_xep(number, last_version, initials): + filename = "xep-{:04d}.xml".format(number) + with open(filename, "r") as f: + xep_text = f.read() + + if EXPERIMENTAL_STATUS not in xep_text: + raise ValueError("cannot find experimental status in XEP text") + + # this is so incredibly evil ... + xep_text = xep_text.replace(EXPERIMENTAL_STATUS, DEFERRED_STATUS, 1) + revision_match = REVISION_RE.search(xep_text) + + version = last_version.split(".") + if len(version) == 1: + version.append("1") + else: + version[1] = str(int(version[1]) + 1) + del version[2:] + + xep_text = ( + xep_text[:revision_match.start()] + + REVISION_TEMPLATE.format( + now=datetime.utcnow(), + version=".".join(version), + initials=initials, + ) + xep_text[revision_match.start():] + ) + + with open(filename, "w") as f: + f.write(xep_text) + f.flush() + + def main(): import argparse @@ -32,10 +79,18 @@ def main(): ) parser.add_argument( - "-m", "--modify", + "-v", "--verbose", + help="Print additional metadata for deferred XEPs", action="store_true", default=False, - help="Modify the XEP files in-place." + ) + + parser.add_argument( + "-m", "--modify", + default=False, + metavar="INITIALS", + help="Modify the to-be-deferred XEPs in-place and use the given " + "INITIALS in the remarks." ) args = parser.parse_args() @@ -50,7 +105,20 @@ def main(): deferred = list(get_deferred(accepted)) for deferred_info in deferred: - print(deferred_info["number"]) + if args.modify: + defer_xep(deferred_info["number"], + deferred_info["last_revision"]["version"], + args.modify) + + if args.verbose: + print( + "XEP-{info[number]:04d}: {info[title]} " + "(last update {info[last_revision][date]:%Y-%m-%d})".format( + info=deferred_info + ) + ) + else: + print(deferred_info["number"]) if __name__ == "__main__": diff --git a/tools/send-updates.py b/tools/send-updates.py index 065e93b3..09ac9c26 100755 --- a/tools/send-updates.py +++ b/tools/send-updates.py @@ -68,6 +68,19 @@ Changelog: URL: {url}""" +MAIL_DEFER_TEMPLATE = """\ +XEP-{info[number]:04d} ({info[title]}) has been Deferred because of inactivity. + +Abstract: +{info[abstract]} + +URL: {url} + +If and when a new revision of this XEP is published, its status will be \ +changed back to Experimental. +""" + + SUBJECT_NONPROTO_TEMPLATE = \ "{action.value}: XEP-{info[number]:04d} ({info[title]})" @@ -152,6 +165,10 @@ def make_nonproto_mail(action, info): ), } + body_template = MAIL_NONPROTO_TEMPLATE + if action == Action.DEFER: + body_template = MAIL_DEFER_TEMPLATE + mail = email.message.EmailMessage() mail["Subject"] = SUBJECT_NONPROTO_TEMPLATE.format(**kwargs) mail["XSF-XEP-Action"] = action.value @@ -161,7 +178,7 @@ def make_nonproto_mail(action, info): mail["XSF-XEP-Number"] = "{:04d}".format(info["number"]) mail["XSF-XEP-Url"] = kwargs["url"] mail.set_content( - wraptext(MAIL_NONPROTO_TEMPLATE.format(**kwargs)), + wraptext(body_template.format(**kwargs)), "plain", "utf-8", ) diff --git a/tools/xeplib.py b/tools/xeplib.py index 5a250041..93065f78 100644 --- a/tools/xeplib.py +++ b/tools/xeplib.py @@ -35,6 +35,7 @@ class Action(enum.Enum): OBSOLETE = "OBSOLETED" DEFER = "DEFERRED" UPDATE = "UPDATED" + DEPRECATE = "DEPRECATED" @classmethod def fromstatus(cls, status): @@ -44,9 +45,9 @@ class Action(enum.Enum): Status.ACTIVE: cls.ACTIVE, Status.FINAL: cls.FINAL, Status.RETRACTED: cls.RETRACT, - Status.OBSOLETED: cls.OBSOLETE, + Status.OBSOLETE: cls.OBSOLETE, Status.DEPRECATED: cls.DEPRECATE, - Status.DEFERRED: cls.DEFERRED, + Status.DEFERRED: cls.DEFER, }[status]