diff --git a/README.md b/README.md index ddc9e41..3a10c5c 100644 --- a/README.md +++ b/README.md @@ -37,60 +37,77 @@ pytest -svv ## Commands & Features ### `archive-all-repos` + archive all repos in gitea organization ### `check-issues` + check the existence of issue by title on gitea ### `checkout-releases` + checkout git repo to git tag fetched from gitea by release name, with due date ### `clone-all-repos` + clone all gitea repos to local ### `close-all-issues` + close all issues and pull requests in gitea organization ### `create-channels-on-mm` -create channels for student groups according to group information on gitea. Optionally specify a prefix to ignore all repos whose names do not start with it. -Example: `python3 -m joint_teapot create_channels_for_groups p1` will fetch all repos whose names start with `"p1"` and create same-name channels on mm for these repos. Members of a repo will be added to the corresponding channel. +create channels for student groups according to group information on gitea. Optionally specify a prefix to ignore all repos whose names do not start with it. Optionally specify a suffix to add to all channels created. + +Example: `python3 -m joint_teapot create_channels_for_groups --prefix p1 -suffix -private` will fetch all repos whose names start with `"p1"` and create channels on mm for these repos like "p1team1-private". Members of a repo will be added to the corresponding channel. ### `create-issues` + create issues on gitea ### `create-personal-repos` + create personal repos on gitea for all canvas students ### `create-teams` + create teams on gitea by canvas groups ### `create-webhooks-for-mm` + Create a pair of webhooks on gitea and mm for all student groups on gitea, and configure them so that updates on gitea will be pushed to the mm channel. Optionally specify a prefix to ignore all repos whose names do not start with it. Example: `python3 -m joint_teapot create-webhooks-for-mm p1` will fetch all repos whose names start with `"p1"` and create two-way webhooks for these repos. All repos should already have same-name mm channels. If not, use `create-channels-on-mm` to create them. ### `get-no-collaborator-repos` + list all repos with no collaborators ### `get-public-keys` + list all public keys on gitea ### `get-repos-status` + list status of all repos with conditions ### `invite-to-teams` + invite all canvas students to gitea teams by team name ### `prepare-assignment-dir` + prepare assignment dir from extracted canvas "Download Submissions" zip ### `unsubscribe-from-repos` + Unsubscribe from all repos in the organization specified in the config file where the repo name matches a given regex expression. Example: `python3 -m joint_teapot unsubscribe-from-repos '\d{12}$'` will remove all repos whose names end with a student ID number from your gitea subscription list. Refer to the Python `re` module docs for more info about regex. ### `upload-assignment-grades` + upload assignment grades to canvas from grade file (GRADE.txt by default), read the first line as grade, the rest as comments ## License diff --git a/joint_teapot/app.py b/joint_teapot/app.py index 9c3bed7..b7705c5 100644 --- a/joint_teapot/app.py +++ b/joint_teapot/app.py @@ -2,7 +2,7 @@ from datetime import datetime from pathlib import Path from typing import List -from typer import Argument, Typer, echo +from typer import Argument, Option, Typer, echo from joint_teapot.teapot import Teapot from joint_teapot.utils.logger import logger @@ -140,14 +140,18 @@ def upload_assignment_grades(assignments_dir: Path, assignment_name: str) -> Non help="create channels for student groups according to group information on" " gitea", ) -def create_channels_on_mm(prefix: str = Argument("")) -> None: +def create_channels_on_mm(prefix: str = Option(""), suffix: str = Option("")) -> None: groups = { group_name: members for group_name, members in tea.pot.gitea.get_all_teams().items() if group_name.startswith(prefix) } - logger.info(f"{len(groups)} channel(s) to be created: {groups.keys()}") - tea.pot.mattermost.create_channels_for_groups(groups) + logger.info( + f"{len(groups)} channel(s) to be created " + + (f"with suffix {suffix}" if suffix else "") + + f": {','.join(groups.keys())}" + ) + tea.pot.mattermost.create_channels_for_groups(groups, suffix) @app.command( diff --git a/joint_teapot/workers/mattermost.py b/joint_teapot/workers/mattermost.py index 4110914..b3f94ba 100644 --- a/joint_teapot/workers/mattermost.py +++ b/joint_teapot/workers/mattermost.py @@ -39,21 +39,24 @@ class Mattermost: logger.error(f"Cannot get team {team_name}: {e}") return - def create_channels_for_groups(self, groups: Dict[str, List[str]]) -> None: + def create_channels_for_groups( + self, groups: Dict[str, List[str]], suffix: str = "" + ) -> None: for group_name, members in groups.items(): + channel_name = group_name + suffix try: channel = self.endpoint.channels.create_channel( { "team_id": self.team["id"], - "name": group_name, - "display_name": group_name, + "name": channel_name, + "display_name": channel_name, "type": "P", # create private channels } ) - logger.info(f"Added group {group_name} to Mattermost") + logger.info(f"Added group {channel_name} to Mattermost") except Exception as e: logger.warning( - f"Error when creating channel {group_name}: {e} Perhaps channel already exists?" + f"Error when creating channel {channel_name}: {e} Perhaps channel already exists?" ) continue for member in members: @@ -76,7 +79,7 @@ class Mattermost: ) except Exception: logger.warning(f"User {member} is not in the team") - logger.info(f"Added member {member} to channel {group_name}") + logger.info(f"Added member {member} to channel {channel_name}") def create_webhooks_for_repos(self, repos: List[str], gitea: Gitea) -> None: # one group corresponds to one repo so these concepts can be used interchangeably