From d7915cc758f7406e0e42933517cdb46c50207685 Mon Sep 17 00:00:00 2001 From: Pasit Sangprachathanarak Date: Wed, 6 May 2026 17:30:23 +0800 Subject: [PATCH 1/4] Add RemoveTeam CLI util --- cmscontrib/RemoveTeam.py | 61 ++++++++++++++++++++++++++++++++++++++++ setup.py | 1 + 2 files changed, 62 insertions(+) create mode 100644 cmscontrib/RemoveTeam.py diff --git a/cmscontrib/RemoveTeam.py b/cmscontrib/RemoveTeam.py new file mode 100644 index 0000000000..f96d6ebf10 --- /dev/null +++ b/cmscontrib/RemoveTeam.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 + +# Contest Management System - http://cms-dev.github.io/ +# Copyright © 2026 Pasit Sangprachathanarak +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +"""Utility to remove a team. + +""" + +import argparse +import logging +import sys + +from cms import utf8_decoder +from cms.db import SessionGen, Team + + +logger = logging.getLogger(__name__) + + +def remove_team(code: str) -> bool: + with SessionGen() as session: + if team is None: + logger.error("Team %s does not exist.", code) + return False + + session.delete(team) + session.commit() + + return True + + +def main(): + """Parse arguments and launch process. + + """ + parser = argparse.ArgumentParser( + description="Remove a team from CMS.") + parser.add_argument("code", action="store", type=utf8_decoder, + help="code of the team, e.g. country code") + args = parser.parse_args() + + success = remove_team(code=args.code) + return 0 if success is True else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/setup.py b/setup.py index 76ac8b01d4..6e66ef0e9b 100755 --- a/setup.py +++ b/setup.py @@ -144,6 +144,7 @@ class build_with_l10n(build): "cmsRemoveParticipation=cmscontrib.RemoveParticipation:main", "cmsRemoveSubmissions=cmscontrib.RemoveSubmissions:main", "cmsRemoveTask=cmscontrib.RemoveTask:main", + "cmsRemoveTeam=cmscontrib.RemoveTeam:main", "cmsRemoveUser=cmscontrib.RemoveUser:main", "cmsSolutionChecker=cmscontrib.SolutionChecker:main", "cmsSpoolExporter=cmscontrib.SpoolExporter:main", From 1dcf938fade350c7d9f978d8038e1426c4d86f3e Mon Sep 17 00:00:00 2001 From: Pasit Sangprachathanarak Date: Wed, 6 May 2026 17:39:41 +0800 Subject: [PATCH 2/4] Update RemoveTeam.py --- cmscontrib/RemoveTeam.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmscontrib/RemoveTeam.py b/cmscontrib/RemoveTeam.py index f96d6ebf10..5c794a83d0 100644 --- a/cmscontrib/RemoveTeam.py +++ b/cmscontrib/RemoveTeam.py @@ -33,6 +33,7 @@ def remove_team(code: str) -> bool: with SessionGen() as session: + team = session.query(Team).filter(Team.code == code).first() if team is None: logger.error("Team %s does not exist.", code) return False @@ -48,9 +49,9 @@ def main(): """ parser = argparse.ArgumentParser( - description="Remove a team from CMS.") + description="Remove a team from CMS .") parser.add_argument("code", action="store", type=utf8_decoder, - help="code of the team, e.g. country code") + help="the team code") args = parser.parse_args() success = remove_team(code=args.code) From 62267c41febcb8408737f56b60205aee51976ed3 Mon Sep 17 00:00:00 2001 From: Pasit Sangprachathanarak Date: Thu, 7 May 2026 00:01:19 +0800 Subject: [PATCH 3/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- cmscontrib/RemoveTeam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmscontrib/RemoveTeam.py b/cmscontrib/RemoveTeam.py index 5c794a83d0..2981e34599 100644 --- a/cmscontrib/RemoveTeam.py +++ b/cmscontrib/RemoveTeam.py @@ -49,7 +49,7 @@ def main(): """ parser = argparse.ArgumentParser( - description="Remove a team from CMS .") + description="Remove a team from CMS.") parser.add_argument("code", action="store", type=utf8_decoder, help="the team code") args = parser.parse_args() From 21f02c96d76e3635e42c90863bbcad417300dcef Mon Sep 17 00:00:00 2001 From: Pasit Sangprachathanarak Date: Thu, 7 May 2026 00:03:39 +0800 Subject: [PATCH 4/4] Update RemoveTeam.py --- cmscontrib/RemoveTeam.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmscontrib/RemoveTeam.py b/cmscontrib/RemoveTeam.py index 2981e34599..a5a8ae3f0f 100644 --- a/cmscontrib/RemoveTeam.py +++ b/cmscontrib/RemoveTeam.py @@ -25,7 +25,7 @@ import sys from cms import utf8_decoder -from cms.db import SessionGen, Team +from cms.db import Participation, SessionGen, Team logger = logging.getLogger(__name__) @@ -38,6 +38,10 @@ def remove_team(code: str) -> bool: logger.error("Team %s does not exist.", code) return False + session.query(Participation).filter(Participation.team_id == team.id).update( + {Participation.team_id: None} + ) + session.delete(team) session.commit()