From 370c3b24edf164e1fdb1be0fb88311c8c59fea0c Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Thu, 18 Apr 2024 10:25:02 -0500 Subject: [PATCH] chore: remove alreay used on-shot import commands (#7333) --- .../commands/import_iesg_appeals.py | 294 -------------- .../commands/import_iesg_statements.py | 274 ------------- .../commands/import_iesg_minutes.py | 364 ------------------ 3 files changed, 932 deletions(-) delete mode 100644 ietf/group/management/commands/import_iesg_appeals.py delete mode 100644 ietf/group/management/commands/import_iesg_statements.py delete mode 100644 ietf/meeting/management/commands/import_iesg_minutes.py diff --git a/ietf/group/management/commands/import_iesg_appeals.py b/ietf/group/management/commands/import_iesg_appeals.py deleted file mode 100644 index 1c4ebe3f8..000000000 --- a/ietf/group/management/commands/import_iesg_appeals.py +++ /dev/null @@ -1,294 +0,0 @@ -# Copyright The IETF Trust 2023, All Rights Reserved - -import csv -import datetime -import re -import shutil -import subprocess -import tempfile - -from pathlib import Path -import dateutil - -from django.conf import settings -from django.core.management import BaseCommand - -from ietf.group.models import Appeal, AppealArtifact - - -class Command(BaseCommand): - help = "Performs a one-time import of IESG appeals" - - def handle(self, *args, **options): - old_appeals_root = ( - "/a/www/www6/iesg/appeal" - if settings.SERVER_MODE == "production" - else "/assets/www6/iesg/appeal" - ) - tmpdir = tempfile.mkdtemp() - process = subprocess.Popen( - ["git", "clone", "https://github.com/kesara/iesg-scraper.git", tmpdir], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - sub_stdout, sub_stderr = process.communicate() - if not (Path(tmpdir) / "iesg_appeals" / "anderson-2006-03-08.md").exists(): - self.stdout.write( - "Git clone of the iesg-scraper directory did not go as expected" - ) - self.stdout.write("stdout:", sub_stdout) - self.stdout.write("stderr:", sub_stderr) - self.stdout.write(f"Clean up {tmpdir} manually") - exit(-1) - titles = [ - "Appeal: IESG Statement on Guidance on In-Person and Online Interim Meetings (John Klensin, 2023-08-15)", - "Appeal of current Guidance on in-Person and Online meetings (Ted Hardie, Alan Frindell, 2023-07-19)", - "Appeal re: URI Scheme Application and draft-mcsweeney-drop-scheme (Tim McSweeney, 2020-07-08)", - "Appeal to the IESG re WGLC of draft-ietf-spring-srv6-network-programming (Fernando Gont, Andrew Alston, and Sander Steffann, 2020-04-22)", - "Appeal re Protocol Action: 'URI Design and Ownership' to Best \nCurrent Practice (draft-nottingham-rfc7320bis-03.txt) (John Klensin; 2020-02-04)", - "Appeal of IESG Conflict Review process and decision on draft-mavrogiannopoulos-pkcs8-validated-parameters-02 (John Klensin; 2018-07-07)", - "Appeal of IESG decision to defer action and request that ISE publish draft-klensin-dns-function-considerations (John Klensin; 2017-11-29)", - 'Appeal to the IESG concerning its approval of the "draft-ietf-ianaplan-icg-response" (PDF file) (JFC Morfin; 2015-03-11)', - "Appeal re tzdist mailing list moderation (Tobias Conradi; 2014-08-28) / Withdrawn by Submitter", - "Appeal re draft-masotta-tftpexts-windowsize-opt (Patrick Masotta; 2013-11-14)", - "Appeal re draft-ietf-manet-nhdp-sec-threats (Abdussalam Baryun; 2013-06-19)", - "Appeal of decision to advance RFC6376 (Douglas Otis; 2013-05-30)", - "Appeal to the IESG in regards to RFC 6852 (PDF file) (JFC Morfin; 2013-04-05)", - "Appeal to the IESG concerning the approbation of the IDNA2008 document set (PDF file) (JFC Morfin; 2010-03-10)", - "Authentication-Results Header Field Appeal (Douglas Otis, David Rand; 2009-02-16) / Withdrawn by Submitter", - "Appeal to the IAB of IESG rejection of Appeal to Last Call draft-ietf-grow-anycast (Dean Anderson; 2008-11-14)", - "Appeal to the IESG Concerning the Way At Large Internet Lead Users Are Not Permitted To Adequately Contribute to the IETF Deliverables (JFC Morfin; 2008-09-10)", - "Appeal over suspension of posting rights for Todd Glassey (Todd Glassey; 2008-07-28)", - "Appeal against IESG blocking DISCUSS on draft-klensin-rfc2821bis (John C Klensin; 2008-06-13)", - "Appeal: Continued Abuse of Process by IPR-WG Chair (Dean Anderson; 2007-12-26)", - "Appeal to the IESG from Todd Glassey (Todd Glassey; 2007-11-26)", - "Appeal Against the Removal of the Co-Chairs of the GEOPRIV Working Group (PDF file) (Randall Gellens, Allison Mankin, and Andrew Newton; 2007-06-22)", - "Appeal concerning the WG-LTRU rechartering (JFC Morfin; 2006-10-24)", - "Appeal against decision within July 10 IESG appeal dismissal (JFC Morfin; 2006-09-09)", - "Appeal: Mandatory to implement HTTP authentication mechanism in the Atom Publishing Protocol (Robert Sayre; 2006-08-29)", - "Appeal Against IESG Decisions Regarding the draft-ietf-ltru-matching (PDF file) (JFC Morfin; 2006-08-16)", - "Amended Appeal Re: grow: Last Call: 'Operation of Anycast Services' to BCP (draft-ietf-grow-anycast) (Dean Anderson; 2006-06-14)", - "Appeal Against an IESG Decision Denying Me IANA Language Registration Process by way of PR-Action (PDF file) (JFC Morfin; 2006-05-17)", - "Appeal to the IESG of PR-Action against Dean Anderson (Dean Anderson; 2006-03-08)", - "Appeal to IESG against AD decision: one must clear the confusion opposing the RFC 3066 Bis consensus (JFC Morfin; 2006-02-20)", - "Appeal to the IESG of an IESG decision (JFC Morfin; 2006-02-17)", - "Appeal to the IESG in reference to the ietf-languages@alvestrand.no mailing list (JFC Morfin; 2006-02-07)", - "Appeal to the IESG against an IESG decision concerning RFC 3066 Bis Draft (JFC Morfin; 2006-01-14)", - "Appeal over a key change in a poor RFC 3066 bis example (JFC Morfin; 2005-10-19)", - "Additional appeal against publication of draft-lyon-senderid-* in regards to its recommended use of Resent- header fields in the way that is inconsistant with RFC2822(William Leibzon; 2005-08-29)", - "Appeal: Publication of draft-lyon-senderid-core-01 in conflict with referenced draft-schlitt-spf-classic-02 (Julian Mehnle; 2005-08-25)", - 'Appeal of decision to standardize "Mapping Between the Multimedia Messaging Service (MMS) and Internet Mail" (John C Klensin; 2005-06-10)', - "Appeal regarding IESG decision on the GROW WG (David Meyer; 2003-11-15)", - "Appeal: Official notice of appeal on suspension rights (Todd Glassey; 2003-08-06)", - "Appeal: AD response to Site-Local Appeal (Tony Hain; 2003-07-31)", - "Appeal against IESG decision for draft-chiba-radius-dynamic-authorization-05.txt (Glen Zorn; 2003-01-15)", - "Appeal Against moving draft-ietf-ipngwg-addr-arch-v3 to Draft Standard (Robert Elz; 2002-11-05)", - ] - date_re = re.compile(r"\d{4}-\d{2}-\d{2}") - dates = [ - datetime.datetime.strptime(date_re.search(t).group(), "%Y-%m-%d").date() - for t in titles - ] - - parts = [ - ["klensin-2023-08-15.txt", "response-to-klensin-2023-08-15.txt"], - [ - "hardie-frindell-2023-07-19.txt", - "response-to-hardie-frindell-2023-07-19.txt", - ], - ["mcsweeney-2020-07-08.txt", "response-to-mcsweeney-2020-07-08.pdf"], - ["gont-2020-04-22.txt", "response-to-gont-2020-06-02.txt"], - ["klensin-2020-02-04.txt", "response-to-klensin-2020-02-04.txt"], - ["klensin-2018-07-07.txt", "response-to-klensin-2018-07-07.txt"], - ["klensin-2017-11-29.txt", "response-to-klensin-2017-11-29.md"], - ["morfin-2015-03-11.pdf", "response-to-morfin-2015-03-11.md"], - ["conradi-2014-08-28.txt"], - ["masotta-2013-11-14.txt", "response-to-masotta-2013-11-14.md"], - ["baryun-2013-06-19.txt", "response-to-baryun-2013-06-19.md"], - ["otis-2013-05-30.txt", "response-to-otis-2013-05-30.md"], - ["morfin-2013-04-05.pdf", "response-to-morfin-2013-04-05.md"], - ["morfin-2010-03-10.pdf", "response-to-morfin-2010-03-10.txt"], - ["otis-2009-02-16.txt"], - ["anderson-2008-11-14.md", "response-to-anderson-2008-11-14.txt"], - ["morfin-2008-09-10.txt", "response-to-morfin-2008-09-10.txt"], - ["glassey-2008-07-28.txt", "response-to-glassey-2008-07-28.txt"], - ["klensin-2008-06-13.txt", "response-to-klensin-2008-06-13.txt"], - ["anderson-2007-12-26.txt", "response-to-anderson-2007-12-26.txt"], - ["glassey-2007-11-26.txt", "response-to-glassey-2007-11-26.txt"], - ["gellens-2007-06-22.pdf", "response-to-gellens-2007-06-22.txt"], - ["morfin-2006-10-24.txt", "response-to-morfin-2006-10-24.txt"], - ["morfin-2006-09-09.txt", "response-to-morfin-2006-09-09.txt"], - ["sayre-2006-08-29.txt", "response-to-sayre-2006-08-29.txt"], - [ - "morfin-2006-08-16.pdf", - "response-to-morfin-2006-08-17.txt", - "response-to-morfin-2006-08-17-part2.txt", - ], - ["anderson-2006-06-13.txt", "response-to-anderson-2006-06-14.txt"], - ["morfin-2006-05-17.pdf", "response-to-morfin-2006-05-17.txt"], - ["anderson-2006-03-08.md", "response-to-anderson-2006-03-08.txt"], - ["morfin-2006-02-20.txt", "response-to-morfin-2006-02-20.txt"], - ["morfin-2006-02-17.txt", "response-to-morfin-2006-02-17.txt"], - ["morfin-2006-02-07.txt", "response-to-morfin-2006-02-07.txt"], - ["morfin-2006-01-14.txt", "response-to-morfin-2006-01-14.txt"], - ["morfin-2005-10-19.txt", "response-to-morfin-2005-10-19.txt"], - ["leibzon-2005-08-29.txt", "response-to-leibzon-2005-08-29.txt"], - ["mehnle-2005-08-25.txt", "response-to-mehnle-2005-08-25.txt"], - ["klensin-2005-06-10.txt", "response-to-klensin-2005-06-10.txt"], - ["meyer-2003-11-15.txt", "response-to-meyer-2003-11-15.txt"], - ["glassey-2003-08-06.txt", "response-to-glassey-2003-08-06.txt"], - ["hain-2003-07-31.txt", "response-to-hain-2003-07-31.txt"], - ["zorn-2003-01-15.txt", "response-to-zorn-2003-01-15.txt"], - ["elz-2002-11-05.txt", "response-to-elz-2002-11-05.txt"], - ] - - assert len(titles) == len(dates) - assert len(titles) == len(parts) - - part_times = dict() - part_times["klensin-2023-08-15.txt"] = "2023-08-15 15:03:55 -0400" - part_times["response-to-klensin-2023-08-15.txt"] = "2023-08-24 18:54:13 +0300" - part_times["hardie-frindell-2023-07-19.txt"] = "2023-07-19 07:17:16PDT" - part_times["response-to-hardie-frindell-2023-07-19.txt"] = ( - "2023-08-15 11:58:26PDT" - ) - part_times["mcsweeney-2020-07-08.txt"] = "2020-07-08 14:45:00 -0400" - part_times["response-to-mcsweeney-2020-07-08.pdf"] = "2020-07-28 12:54:04 -0000" - part_times["gont-2020-04-22.txt"] = "2020-04-22 22:26:20 -0400" - part_times["response-to-gont-2020-06-02.txt"] = "2020-06-02 20:44:29 -0400" - part_times["klensin-2020-02-04.txt"] = "2020-02-04 13:54:46 -0500" - # part_times["response-to-klensin-2020-02-04.txt"]="2020-03-24 11:49:31EDT" - part_times["response-to-klensin-2020-02-04.txt"] = "2020-03-24 11:49:31 -0400" - part_times["klensin-2018-07-07.txt"] = "2018-07-07 12:40:43PDT" - # part_times["response-to-klensin-2018-07-07.txt"]="2018-08-16 10:46:45EDT" - part_times["response-to-klensin-2018-07-07.txt"] = "2018-08-16 10:46:45 -0400" - part_times["klensin-2017-11-29.txt"] = "2017-11-29 09:35:02 -0500" - part_times["response-to-klensin-2017-11-29.md"] = "2017-11-30 11:33:04 -0500" - part_times["morfin-2015-03-11.pdf"] = "2015-03-11 18:03:44 -0000" - part_times["response-to-morfin-2015-03-11.md"] = "2015-04-16 15:18:09 -0000" - part_times["conradi-2014-08-28.txt"] = "2014-08-28 22:28:06 +0300" - part_times["masotta-2013-11-14.txt"] = "2013-11-14 15:35:19 +0200" - part_times["response-to-masotta-2013-11-14.md"] = "2014-01-27 07:39:32 -0800" - part_times["baryun-2013-06-19.txt"] = "2013-06-19 06:29:51PDT" - part_times["response-to-baryun-2013-06-19.md"] = "2013-07-02 15:24:42 -0700" - part_times["otis-2013-05-30.txt"] = "2013-05-30 19:35:18 +0000" - part_times["response-to-otis-2013-05-30.md"] = "2013-06-27 11:56:48 -0700" - part_times["morfin-2013-04-05.pdf"] = "2013-04-05 17:31:19 -0700" - part_times["response-to-morfin-2013-04-05.md"] = "2013-04-17 08:17:29 -0700" - part_times["morfin-2010-03-10.pdf"] = "2010-03-10 21:40:58 +0100" - part_times["response-to-morfin-2010-03-10.txt"] = "2010-04-07 14:26:06 -0700" - part_times["otis-2009-02-16.txt"] = "2009-02-16 15:47:15 -0800" - part_times["anderson-2008-11-14.md"] = "2008-11-14 00:16:58 -0500" - part_times["response-to-anderson-2008-11-14.txt"] = "2008-12-15 11:00:02 -0800" - part_times["morfin-2008-09-10.txt"] = "2008-09-10 04:10:13 +0200" - part_times["response-to-morfin-2008-09-10.txt"] = "2008-09-28 10:00:01PDT" - part_times["glassey-2008-07-28.txt"] = "2008-07-28 08:34:52 -0700" - part_times["response-to-glassey-2008-07-28.txt"] = "2008-09-02 11:00:01PDT" - part_times["klensin-2008-06-13.txt"] = "2008-06-13 21:14:38 -0400" - part_times["response-to-klensin-2008-06-13.txt"] = "2008-07-07 10:00:01 PDT" - # part_times["anderson-2007-12-26.txt"]="2007-12-26 17:19:34EST" - part_times["anderson-2007-12-26.txt"] = "2007-12-26 17:19:34 -0500" - part_times["response-to-anderson-2007-12-26.txt"] = "2008-01-15 17:21:05 -0500" - part_times["glassey-2007-11-26.txt"] = "2007-11-26 08:13:22 -0800" - part_times["response-to-glassey-2007-11-26.txt"] = "2008-01-23 17:38:43 -0500" - part_times["gellens-2007-06-22.pdf"] = "2007-06-22 21:45:41 -0400" - part_times["response-to-gellens-2007-06-22.txt"] = "2007-09-20 14:01:27 -0400" - part_times["morfin-2006-10-24.txt"] = "2006-10-24 05:03:17 +0200" - part_times["response-to-morfin-2006-10-24.txt"] = "2006-11-07 12:56:02 -0500" - part_times["morfin-2006-09-09.txt"] = "2006-09-09 02:54:55 +0200" - part_times["response-to-morfin-2006-09-09.txt"] = "2006-09-15 12:56:31 -0400" - part_times["sayre-2006-08-29.txt"] = "2006-08-29 17:05:03 -0400" - part_times["response-to-sayre-2006-08-29.txt"] = "2006-10-16 13:07:18 -0400" - part_times["morfin-2006-08-16.pdf"] = "2006-08-16 18:28:19 -0400" - part_times["response-to-morfin-2006-08-17.txt"] = "2006-08-22 12:05:42 -0400" - part_times["response-to-morfin-2006-08-17-part2.txt"] = ( - "2006-11-07 13:00:58 -0500" - ) - # part_times["anderson-2006-06-13.txt"]="2006-06-13 21:51:18EDT" - part_times["anderson-2006-06-13.txt"] = "2006-06-13 21:51:18 -0400" - part_times["response-to-anderson-2006-06-14.txt"] = "2006-07-10 14:31:08 -0400" - part_times["morfin-2006-05-17.pdf"] = "2006-05-17 06:46:18 +0200" - part_times["response-to-morfin-2006-05-17.txt"] = "2006-07-10 14:18:10 -0400" - part_times["anderson-2006-03-08.md"] = "2006-03-08 09:42:44 +0100" - part_times["response-to-anderson-2006-03-08.txt"] = "2006-03-20 14:55:38 -0500" - part_times["morfin-2006-02-20.txt"] = "2006-02-20 19:18:24 +0100" - part_times["response-to-morfin-2006-02-20.txt"] = "2006-03-06 13:08:39 -0500" - part_times["morfin-2006-02-17.txt"] = "2006-02-17 18:59:38 +0100" - part_times["response-to-morfin-2006-02-17.txt"] = "2006-07-10 14:05:15 -0400" - part_times["morfin-2006-02-07.txt"] = "2006-02-07 19:38:57 -0500" - part_times["response-to-morfin-2006-02-07.txt"] = "2006-02-21 19:09:26 -0500" - part_times["morfin-2006-01-14.txt"] = "2006-01-14 15:05:24 +0100" - part_times["response-to-morfin-2006-01-14.txt"] = "2006-02-21 12:23:38 -0500" - part_times["morfin-2005-10-19.txt"] = "2005-10-19 17:12:11 +0200" - part_times["response-to-morfin-2005-10-19.txt"] = "2005-11-15 11:42:30 -0500" - part_times["leibzon-2005-08-29.txt"] = "2005-08-29 08:28:52PDT" - part_times["response-to-leibzon-2005-08-29.txt"] = "2005-12-08 14:04:47 -0500" - part_times["mehnle-2005-08-25.txt"] = "2005-08-25 00:45:26 +0200" - part_times["response-to-mehnle-2005-08-25.txt"] = "2005-12-08 13:37:38 -0500" - part_times["klensin-2005-06-10.txt"] = "2005-06-10 14:49:17 -0400" - part_times["response-to-klensin-2005-06-10.txt"] = "2005-07-22 18:14:06 -0400" - part_times["meyer-2003-11-15.txt"] = "2003-11-15 09:47:11 -0800" - part_times["response-to-meyer-2003-11-15.txt"] = "2003-11-25 10:56:06 -0500" - part_times["glassey-2003-08-06.txt"] = "2003-08-06 02:14:24 +0000" - part_times["response-to-glassey-2003-08-06.txt"] = "2003-09-24 09:54:51 -0400" - part_times["hain-2003-07-31.txt"] = "2003-07-31 16:44:19 -0700" - part_times["response-to-hain-2003-07-31.txt"] = "2003-09-30 14:44:30 -0400" - part_times["zorn-2003-01-15.txt"] = "2003-01-15 01:22:28 -0800" - part_times["elz-2002-11-05.txt"] = "2002-11-05 10:51:13 +0700" - # No time could be found for this one: - part_times["response-to-zorn-2003-01-15.txt"] = "2003-02-08" - # This one was issued sometime between 2002-12-27 (when IESG minutes note that the - # appeal response was approved) and 2003-01-04 (when the appeal was escalated to - # the IAB) - we're using the earlier end of the window - part_times["response-to-elz-2002-11-05.txt"] = "2002-12-27" - for name in part_times: - part_times[name] = dateutil.parser.parse(part_times[name]).astimezone( - datetime.timezone.utc - ) - - redirects = [] - for index, title in enumerate(titles): - # IESG is group 2 - appeal = Appeal.objects.create( - name=titles[index], date=dates[index], group_id=2 - ) - for part in parts[index]: - if part.endswith(".pdf"): - content_type = "application/pdf" - else: - content_type = "text/markdown;charset=utf-8" - if part.endswith(".md"): - source_path = Path(tmpdir) / "iesg_appeals" / part - else: - source_path = Path(old_appeals_root) / part - with source_path.open("rb") as source_file: - bits = source_file.read() - if part == "morfin-2008-09-10.txt": - bits = bits.decode("macintosh") - bits = bits.replace("\r", "\n") - bits = bits.encode("utf8") - elif part in ["morfin-2006-02-07.txt", "morfin-2006-01-14.txt"]: - bits = bits.decode("windows-1252").encode("utf8") - artifact_type_id = ( - "response" if part.startswith("response") else "appeal" - ) - artifact = AppealArtifact.objects.create( - appeal=appeal, - artifact_type_id=artifact_type_id, - date=part_times[part].date(), - content_type=content_type, - bits=bits, - ) - redirects.append( - [ - f'www6.ietf.org/iesg/appeal/{part.replace(".md", ".html") if part.endswith(".md") else part}', - f"https://datatracker.ietf.org/group/iesg/appeals/artifact/{artifact.pk}", - 302, - ] - ) - - shutil.rmtree(tmpdir) - with open("iesg_appeal_redirects.csv", "w", newline="") as f: - csvwriter = csv.writer(f) - for row in redirects: - csvwriter.writerow(row) diff --git a/ietf/group/management/commands/import_iesg_statements.py b/ietf/group/management/commands/import_iesg_statements.py deleted file mode 100644 index 93fdcec16..000000000 --- a/ietf/group/management/commands/import_iesg_statements.py +++ /dev/null @@ -1,274 +0,0 @@ -# Copyright The IETF Trust 2024, All Rights Reserved - -import debug # pyflakes:ignore - -import csv -import datetime -import os -import shutil -import subprocess -import tempfile - -from collections import namedtuple, Counter -from pathlib import Path - -from django.conf import settings -from django.core.management.base import BaseCommand - -from ietf.doc.models import Document, DocEvent, State -from ietf.utils.text import xslugify - - -class Command(BaseCommand): - help = "Performs a one-time import of IESG statements" - - def handle(self, *args, **options): - if Document.objects.filter(type="statement", group__acronym="iesg").exists(): - self.stdout.write("IESG statement documents already exist - exiting") - exit(-1) - tmpdir = tempfile.mkdtemp() - process = subprocess.Popen( - ["git", "clone", "https://github.com/kesara/iesg-scraper.git", tmpdir], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - sub_stdout, sub_stderr = process.communicate() - if not Path(tmpdir).joinpath("iesg_statements", "2000-08-29-0.md").exists(): - self.stdout.write( - "Git clone of the iesg-scraper directory did not go as expected" - ) - self.stdout.write("stdout:", sub_stdout) - self.stdout.write("stderr:", sub_stderr) - self.stdout.write(f"Clean up {tmpdir} manually") - exit(-1) - - redirects = [] - for item in self.get_work_items(): - replaced = item.title.endswith( - " SUPERSEDED" - ) or item.doc_time.date() == datetime.date(2007, 7, 30) - title = item.title - if title.endswith(" - SUPERSEDED"): - title = title[: -len(" - SUPERSEDED")] - name = f"statement-iesg-{xslugify(title)}-{item.doc_time:%Y%m%d}" - dest_filename = f"{name}-00.md" - # Create Document - doc = Document.objects.create( - name=name, - type_id="statement", - title=title, - group_id=2, # The IESG group - rev="00", - uploaded_filename=dest_filename, - ) - doc.set_state( - State.objects.get( - type_id="statement", - slug="replaced" if replaced else "active", - ) - ) - e1 = DocEvent.objects.create( - time=item.doc_time, - type="published_statement", - doc=doc, - rev="00", - by_id=1, # (System) - desc="Statement published (note: The exact time of day is inaccurate - the actual time of day is not known)", - ) - e2 = DocEvent.objects.create( - type="added_comment", - doc=doc, - rev="00", - by_id=1, # (System) - desc="Statement moved into datatracker from www.ietf.org", - ) - doc.save_with_history([e1, e2]) - - # Put file in place - source = Path(tmpdir).joinpath("iesg_statements", item.source_filename) - dest = Path(settings.DOCUMENT_PATH_PATTERN.format(doc=doc)).joinpath( - dest_filename - ) - if dest.exists(): - self.stdout.write( - f"WARNING: {dest} already exists - not overwriting it." - ) - else: - os.makedirs(dest.parent, exist_ok=True) - shutil.copy(source, dest) - - redirects.append( - [ - f"www.ietf.org/about/groups/iesg/statements/{item.slug}", - f"https://datatracker.ietf.org/doc/{name}", - 302, - ] - ) - - shutil.rmtree(tmpdir) - with open("iesg_statement_redirects.csv", "w", newline="") as f: - csvwriter = csv.writer(f) - for row in redirects: - csvwriter.writerow(row) - - def get_work_items(self): - Item = namedtuple("Item", "doc_time source_filename title slug") - items = [] - dressed_rows = " ".join( - self.cut_paste_from_www().expandtabs(1).split(" ") - ).split("\n") - old_slugs = self.get_old_slugs() - # Rube-Goldberg-esque dance to deal with conflicting directions of the scrape and - # what order we want the result to sort to - dressed_rows.reverse() - old_slugs.reverse() - total_times_date_seen = Counter([row.split(" ")[0] for row in dressed_rows]) - count_date_seen_so_far = Counter() - for row, slug in zip(dressed_rows, old_slugs): - date_part = row.split(" ")[0] - title_part = row[len(date_part) + 1 :] - datetime_args = list(map(int, date_part.replace("-0", "-").split("-"))) - # Use the minutes in timestamps to preserve order of statements - # on the same day as they currently appear at www.ietf.org - datetime_args.extend([12, count_date_seen_so_far[date_part]]) - count_date_seen_so_far[date_part] += 1 - doc_time = datetime.datetime(*datetime_args, tzinfo=datetime.timezone.utc) - items.append( - Item( - doc_time, - f"{date_part}-{total_times_date_seen[date_part] - count_date_seen_so_far[date_part]}.md", - title_part, - slug, - ) - ) - return items - - def cut_paste_from_www(self): - return """2023-08-24 Support Documents in IETF Working Groups -2023-08-14 Guidance on In-Person and Online Interim Meetings -2023-05-01 IESG Statement on EtherTypes -2023-03-15 Second Report on the RFC 8989 Experiment -2023-01-27 Guidance on In-Person and Online Interim Meetings - SUPERSEDED -2022-10-31 Statement on Restricting Access to IETF IT Systems -2022-01-21 Handling Ballot Positions -2021-09-01 Report on the RFC 8989 experiment -2021-07-21 IESG Statement on Allocation of Email Addresses in the ietf.org Domain -2021-05-11 IESG Statement on Inclusive Language -2021-05-10 IESG Statement on Internet-Draft Authorship -2021-05-07 IESG Processing of RFC Errata for the IETF Stream -2021-04-16 Last Call Guidance to the Community -2020-07-23 IESG Statement On Oppressive or Exclusionary Language -2020-05-01 Guidance on Face-to-Face and Virtual Interim Meetings - SUPERSEDED -2018-03-16 IETF Meeting Photography Policy -2018-01-11 Guidance on Face-to-Face and Virtual Interim Meetings - SUPERSEDED -2017-02-09 License File for Open Source Repositories -2016-11-13 Support Documents in IETF Working Groups - SUPERSEDED -2016-02-05 Guidance on Face-to-Face and Virtual Interim Meetings - SUPERSEDED -2016-01-11 Guidance on Face-to-Face and Virtual Interim Meetings - SUPERSEDED -2015-08-20 IESG Statement on Maximizing Encrypted Access To IETF Information -2015-06-11 IESG Statement on Internet-Draft Authorship - SUPERSEDED -2014-07-20 IESG Statement on Designating RFCs as Historic -2014-05-07 DISCUSS Criteria in IESG Review -2014-03-02 Writable MIB Module IESG Statement -2013-11-03 IETF Anti-Harassment Policy -2012-10-25 IESG Statement on Ethertypes - SUPERSEDED -2012-10-25 IESG Statement on Removal of an Internet-Draft from the IETF Web Site -2011-10-20 IESG Statement on Designating RFCs as Historic - SUPERSEDED -2011-06-27 IESG Statement on Designating RFCs as Historic - SUPERSEDED -2011-06-13 IESG Statement on IESG Processing of RFC Errata concerning RFC Metadata -2010-10-11 IESG Statement on Document Shepherds -2010-05-24 IESG Statement on the Usage of Assignable Codepoints, Addresses and Names in Specification Examples -2010-05-24 IESG Statement on NomCom Eligibility and Day Passes -2009-09-08 IESG Statement on Copyright -2009-01-20 IESG Statement on Proposed Status for IETF Documents Reserving Resources for Example Purposes -2008-09-02 Guidance on Interim Meetings, Conference Calls and Jabber Sessions - SUPERSEDED -2008-07-30 IESG Processing of RFC Errata for the IETF Stream -2008-04-14 IESG Statement on Spam Control on IETF Mailing Lists -2008-03-03 IESG Statement on Registration Requests for URIs Containing Telephone Numbers -2008-02-27 IESG Statement on RFC3406 and URN Namespaces Registry Review -2008-01-23 Advice for WG Chairs Dealing with Off-Topic Postings -2007-10-04 On Appeals of IESG and Area Director Actions and Decisions -2007-07-05 Experimental Specification of New Congestion Control Algorithms -2007-03-20 Guidance on Area Director Sponsoring of Documents -2007-01-15 Last Call Guidance to the Community - SUPERSEDED -2006-04-19 IESG Statement: Normative and Informative References -2006-02-17 IESG Statement on Disruptive Posting -2006-01-09 Guidance for Spam Control on IETF Mailing Lists - SUPERSEDED -2006-01-05 IESG Statement on AUTH48 State -2005-05-12 Syntax for Format Definitions -2003-02-11 IESG Statement on IDN -2002-11-27 Copyright Statement in MIB and PIB Modules -2002-03-13 Guidance for Spam Control on IETF Mailing Lists - SUPERSEDED -2001-12-21 On Design Teams -2001-10-01 Guidelines for the Use of Formal Languages in IETF Specifications -2001-03-21 Establishment of Temporary Sub-IP Area -2000-12-06 Plans to Organize "Sub-IP" Technologies in the IETF -2000-11-20 A New IETF Work Area -2000-08-29 Guidance on Interim IETF Working Group Meetings and Conference Calls - SUPERSEDED -2000-08-29 IESG Guidance on the Moderation of IETF Working Group Mailing Lists""" - - def get_old_slugs(self): - return [ - "support-documents", - "interim-meetings-guidance", - "ethertypes", - "second-report-on-the-rfc-8989-experiment", - "interim-meetings-guidance-2023-01-27", - "statement-on-restricting-access", - "handling-ballot-positions", - "report-on-rfc8989-experiment", - "email-addresses-ietf-domain", - "on-inclusive-language", - "internet-draft-authorship", - "processing-errata-ietf-stream", - "last-call-guidance", - "statement-on-oppressive-exclusionary-language", - "interim-meetings-guidance-2020-05-01", - "meeting-photography-policy", - "interim-meetings-guidance-2018-01-11", - "open-source-repositories-license", - "support-documents-2016-11-13", - "interim-meetings-guidance-2016-02-05", - "interim-meetings-guidance-2016-01-11", - "maximizing-encrypted-access", - "internet-draft-authorship-2015-06-11", - "designating-rfcs-historic", - "iesg-discuss-criteria", - "writable-mib-module", - "anti-harassment-policy", - "ethertypes-2012-10-25", - "internet-draft-removal", - "designating-rfcs-historic-2011-10-20", - "designating-rfcs-historic-2011-06-27", - "rfc-metadata-errata", - "document-shepherds", - "assignable-codepoints-addresses-names", - "nomcom-eligibility-day-passes", - "copyright-2009-09-08", - "reserving-resources-examples", - "interim-meetings-guidance-2008-09-02", - "processing-rfc-errata", - "spam-control-2008-04-14", - "registration-requests-uris", - "urn-namespaces-registry", - "off-topic-postings", - "appeals-actions-decisions", - "experimental-congestion-control", - "area-director-sponsoring-documents", - "last-call-guidance-2007-01-15", - "normative-informative-references", - "disruptive-posting", - "spam-control-2006-01-09", - "auth48", - "syntax-format-definitions", - "idn", - "copyright-2002-11-27", - "spam-control-2002-03-13", - "design-teams", - "formal-languages-use", - "sub-ip-area-2001-03-21", - "sub-ip-area-2000-11-20", - "sub-ip-area-2000-12-06", - "interim-meetings-guidance-2000-08-29", - "mailing-lists-moderation", - ] diff --git a/ietf/meeting/management/commands/import_iesg_minutes.py b/ietf/meeting/management/commands/import_iesg_minutes.py deleted file mode 100644 index d62e5058e..000000000 --- a/ietf/meeting/management/commands/import_iesg_minutes.py +++ /dev/null @@ -1,364 +0,0 @@ -# Copyright The IETF Trust 2023, All Rights Reserved - -from collections import namedtuple -import csv -import datetime -import os -import re -import shutil - -from django.conf import settings -from django.core.management import BaseCommand - -from pathlib import Path -from zoneinfo import ZoneInfo -from ietf.doc.models import DocEvent, Document - -from ietf.meeting.models import ( - Meeting, - SchedTimeSessAssignment, - Schedule, - SchedulingEvent, - Session, - TimeSlot, -) -from ietf.name.models import DocTypeName - - -def add_time_of_day(bare_datetime): - """Add a time for the iesg meeting based on a date and make it tzaware - - From the secretariat - the telechats happened at these times: - 2015-04-09 to present: 0700 PT America/Los Angeles - 1993-02-01 to 2015-03-12: 1130 ET America/New York - 1991-07-30 to 1993-01-25: 1200 ET America/New York - """ - dt = None - if bare_datetime.year > 2015: - dt = bare_datetime.replace(hour=7).replace( - tzinfo=ZoneInfo("America/Los_Angeles") - ) - elif bare_datetime.year == 2015: - if bare_datetime.month >= 4: - dt = bare_datetime.replace(hour=7).replace( - tzinfo=ZoneInfo("America/Los_Angeles") - ) - else: - dt = bare_datetime.replace(hour=11, minute=30).replace( - tzinfo=ZoneInfo("America/New_York") - ) - elif bare_datetime.year > 1993: - dt = bare_datetime.replace(hour=11, minute=30).replace( - tzinfo=ZoneInfo("America/New_York") - ) - elif bare_datetime.year == 1993: - if bare_datetime.month >= 2: - dt = bare_datetime.replace(hour=11, minute=30).replace( - tzinfo=ZoneInfo("America/New_York") - ) - else: - dt = bare_datetime.replace(hour=12).replace( - tzinfo=ZoneInfo("America/New_York") - ) - else: - dt = bare_datetime.replace(hour=12).replace(tzinfo=ZoneInfo("America/New_York")) - - return dt.astimezone(datetime.timezone.utc) - - -def build_bof_coord_data(): - CoordTuple = namedtuple("CoordTuple", "meeting_number source_name") - - def utc_from_la_time(time): - return time.replace(tzinfo=ZoneInfo("America/Los_Angeles")).astimezone( - datetime.timezone.utc - ) - - data = dict() - data[utc_from_la_time(datetime.datetime(2016, 6, 10, 7, 0))] = CoordTuple( - 96, "2015/bof-minutes-ietf-96.txt" - ) - data[utc_from_la_time(datetime.datetime(2016, 10, 6, 7, 0))] = CoordTuple( - 97, "2016/BoF-Minutes-2016-10-06.txt" - ) - data[utc_from_la_time(datetime.datetime(2017, 2, 15, 8, 0))] = CoordTuple( - 98, "2017/bof-minutes-ietf-98.txt" - ) - data[utc_from_la_time(datetime.datetime(2017, 6, 7, 8, 0))] = CoordTuple( - 99, "2017/bof-minutes-ietf-99.txt" - ) - data[utc_from_la_time(datetime.datetime(2017, 10, 5, 7, 0))] = CoordTuple( - 100, "2017/bof-minutes-ietf-100.txt" - ) - data[utc_from_la_time(datetime.datetime(2018, 2, 5, 11, 0))] = CoordTuple( - 101, "2018/bof-minutes-ietf-101.txt" - ) - data[utc_from_la_time(datetime.datetime(2018, 6, 5, 8, 0))] = CoordTuple( - 102, "2018/bof-minutes-ietf-102.txt" - ) - data[utc_from_la_time(datetime.datetime(2018, 9, 26, 7, 0))] = CoordTuple( - 103, "2018/bof-minutes-ietf-103.txt" - ) - data[utc_from_la_time(datetime.datetime(2019, 2, 15, 9, 0))] = CoordTuple( - 104, "2019/bof-minutes-ietf-104.txt" - ) - data[utc_from_la_time(datetime.datetime(2019, 6, 11, 7, 30))] = CoordTuple( - 105, "2019/bof-minutes-ietf-105.txt" - ) - data[utc_from_la_time(datetime.datetime(2019, 10, 9, 6, 30))] = CoordTuple( - 106, "2019/bof-minutes-ietf-106.txt" - ) - data[utc_from_la_time(datetime.datetime(2020, 2, 13, 8, 0))] = CoordTuple( - 107, "2020/bof-minutes-ietf-107.txt" - ) - data[utc_from_la_time(datetime.datetime(2020, 6, 15, 8, 0))] = CoordTuple( - 108, "2020/bof-minutes-ietf-108.txt" - ) - data[utc_from_la_time(datetime.datetime(2020, 10, 9, 7, 0))] = CoordTuple( - 109, "2020/bof-minutes-ietf-109.txt" - ) - data[utc_from_la_time(datetime.datetime(2021, 1, 14, 13, 30))] = CoordTuple( - 110, "2021/bof-minutes-ietf-110.txt" - ) - data[utc_from_la_time(datetime.datetime(2021, 6, 1, 8, 0))] = CoordTuple( - 111, "2021/bof-minutes-ietf-111.txt" - ) - data[utc_from_la_time(datetime.datetime(2021, 9, 15, 9, 0))] = CoordTuple( - 112, "2021/bof-minutes-ietf-112.txt" - ) - data[utc_from_la_time(datetime.datetime(2022, 1, 28, 7, 0))] = CoordTuple( - 113, "2022/bof-minutes-ietf-113.txt" - ) - data[utc_from_la_time(datetime.datetime(2022, 6, 2, 10, 0))] = CoordTuple( - 114, "2022/bof-minutes-ietf-114.txt" - ) - data[utc_from_la_time(datetime.datetime(2022, 9, 13, 9, 0))] = CoordTuple( - 115, "2022/bof-minutes-ietf-115.txt" - ) - data[utc_from_la_time(datetime.datetime(2023, 2, 1, 9, 0))] = CoordTuple( - 116, "2023/bof-minutes-ietf-116.txt" - ) - data[utc_from_la_time(datetime.datetime(2023, 6, 1, 7, 0))] = CoordTuple( - 117, "2023/bof-minutes-ietf-117.txt" - ) - data[utc_from_la_time(datetime.datetime(2023, 9, 15, 8, 0))] = CoordTuple( - 118, "2023/bof-minutes-ietf-118.txt" - ) - return data - - -class Command(BaseCommand): - help = "Performs a one-time import of IESG minutes, creating Meetings to attach them to" - - def handle(self, *args, **options): - old_minutes_root = ( - "/a/www/www6/iesg/minutes" - if settings.SERVER_MODE == "production" - else "/assets/www6/iesg/minutes" - ) - minutes_dir = Path(old_minutes_root) - date_re = re.compile(r"\d{4}-\d{2}-\d{2}") - meeting_times = set() - redirects = [] - for file_prefix in ["minutes", "narrative"]: - paths = list(minutes_dir.glob(f"[12][09][0129][0-9]/{file_prefix}*.txt")) - paths.extend( - list(minutes_dir.glob(f"[12][09][0129][0-9]/{file_prefix}*.html")) - ) - for path in paths: - s = date_re.search(path.name) - if s: - meeting_times.add( - add_time_of_day( - datetime.datetime.strptime(s.group(), "%Y-%m-%d") - ) - ) - bof_coord_data = build_bof_coord_data() - bof_times = set(bof_coord_data.keys()) - assert len(bof_times.intersection(meeting_times)) == 0 - meeting_times.update(bof_times) - year_seen = None - for dt in sorted(meeting_times): - if dt.year != year_seen: - counter = 1 - year_seen = dt.year - meeting_name = f"interim-{dt.year}-iesg-{counter:02d}" - meeting = Meeting.objects.create( - number=meeting_name, - type_id="interim", - date=dt.date(), - days=1, - time_zone=dt.tzname(), - ) - schedule = Schedule.objects.create( - meeting=meeting, - owner_id=1, # the "(System)" person - visible=True, - public=True, - ) - meeting.schedule = schedule - meeting.save() - session = Session.objects.create( - meeting=meeting, - group_id=2, # The IESG group - type_id="regular", - purpose_id="regular", - name=( - f"IETF {bof_coord_data[dt].meeting_number} BOF Coordination Call" - if dt in bof_times - else "Formal Telechat" - ), - ) - SchedulingEvent.objects.create( - session=session, - status_id="sched", - by_id=1, # (System) - ) - timeslot = TimeSlot.objects.create( - meeting=meeting, - type_id="regular", - time=dt, - duration=datetime.timedelta(seconds=2 * 60 * 60), - ) - SchedTimeSessAssignment.objects.create( - timeslot=timeslot, session=session, schedule=schedule - ) - - if dt in bof_times: - source = minutes_dir / bof_coord_data[dt].source_name - if source.exists(): - doc_name = ( - f"minutes-interim-{dt.year}-iesg-{counter:02d}-{dt:%Y%m%d%H%M}" - ) - doc_filename = f"{doc_name}-00.txt" - doc = Document.objects.create( - name=doc_name, - type_id="minutes", - title=f"Minutes IETF {bof_coord_data[dt].meeting_number} BOF coordination {meeting_name} {dt:%Y-%m-%d %H:%M}", - group_id=2, # the IESG group - rev="00", - uploaded_filename=doc_filename, - ) - e = DocEvent.objects.create( - type="comment", - doc=doc, - rev="00", - by_id=1, # "(System)" - desc="Minutes moved into datatracker", - ) - doc.save_with_history([e]) - session.presentations.create(document=doc, rev=doc.rev) - dest = ( - Path(settings.AGENDA_PATH) - / meeting_name - / "minutes" - / doc_filename - ) - if dest.exists(): - self.stdout.write( - f"WARNING: {dest} already exists - not overwriting it." - ) - else: - os.makedirs(dest.parent, exist_ok=True) - shutil.copy(source, dest) - redirects.append( - [ - f"www6.ietf.org/iesg/minutes/{dt.year}/{bof_coord_data[dt].source_name}", - f"https://datatracker.ietf.org/doc/{doc_name}", - 302, - ] - ) - else: - for type_id in ["minutes", "narrativeminutes"]: - source_file_prefix = ( - "minutes" if type_id == "minutes" else "narrative-minutes" - ) - txt_source = ( - minutes_dir - / f"{dt.year}" - / f"{source_file_prefix}-{dt:%Y-%m-%d}.txt" - ) - html_source = ( - minutes_dir - / f"{dt.year}" - / f"{source_file_prefix}-{dt:%Y-%m-%d}.html" - ) - if txt_source.exists() and html_source.exists(): - self.stdout.write( - f"WARNING: Both {txt_source} and {html_source} exist." - ) - if txt_source.exists() or html_source.exists(): - prefix = DocTypeName.objects.get(slug=type_id).prefix - doc_name = f"{prefix}-interim-{dt.year}-iesg-{counter:02d}-{dt:%Y%m%d%H%M}" - suffix = "html" if html_source.exists() else "txt" - doc_filename = f"{doc_name}-00.{suffix}" - verbose_type = ( - "Minutes" if type_id == "minutes" else "Narrative Minutes" - ) - doc = Document.objects.create( - name=doc_name, - type_id=type_id, - title=f"{verbose_type} {meeting_name} {dt:%Y-%m-%d %H:%M}", - group_id=2, # the IESG group - rev="00", - uploaded_filename=doc_filename, - ) - e = DocEvent.objects.create( - type="comment", - doc=doc, - rev="00", - by_id=1, # "(System)" - desc=f"{verbose_type} moved into datatracker", - ) - doc.save_with_history([e]) - session.presentations.create(document=doc, rev=doc.rev) - dest = ( - Path(settings.AGENDA_PATH) - / meeting_name - / type_id - / doc_filename - ) - if dest.exists(): - self.stdout.write( - f"WARNING: {dest} already exists - not overwriting it." - ) - else: - os.makedirs(dest.parent, exist_ok=True) - if html_source.exists(): - html_content = html_source.read_text(encoding="utf-8") - html_content = html_content.replace( - f'href="IESGnarrative-{dt:%Y-%m-%d}.html#', - 'href="#', - ) - html_content = re.sub( - r']*>([^<]*)', - r"\1", - html_content, - ) - html_content = re.sub( - r'([^<]*)', - r"\1", - html_content, - ) - html_content = re.sub( - '