#!/usr/bin/env python3 import re import xml.etree.ElementTree as etree from datetime import datetime, timedelta from xeplib import load_xepinfos, Status def get_deferred(accepted): now = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) threshold = now.replace(year=now.year - 1) for number, info in sorted(accepted.items()): if info["status"] == Status.EXPERIMENTAL and "last_revision" in info: last_update = info["last_revision"]["date"] if last_update <= threshold: 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:] version.append("0"") 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 parser = argparse.ArgumentParser( description="Show the XEPs which need to be changed to deferred." ) parser.add_argument( "-l", "--xeplist", type=argparse.FileType("rb"), default=None, help="XEP list to use (defaults to ./build/xeplist.xml)" ) parser.add_argument( "-v", "--verbose", help="Print additional metadata for deferred XEPs", action="store_true", default=False, ) 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() if args.xeplist is None: args.xeplist = open("./build/xeplist.xml", "rb") with args.xeplist as f: tree = etree.parse(f) accepted, _ = load_xepinfos(tree) deferred = list(get_deferred(accepted)) for deferred_info in deferred: 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__": main()