diff --git a/README.md b/README.md index f8e50ce..ddc9e41 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/352635b2c8534b0086b5a153db7c82e9)](https://app.codacy.com/gh/BoYanZh/Joint-Teapot?utm_source=github.com&utm_medium=referral&utm_content=BoYanZh/Joint-Teapot&utm_campaign=Badge_Grade_Settings) -A handy tool for TAs in JI to handle works through [Gitea](https://focs.ji.sjtu.edu.cn/git/), [Canvas](https://umjicanvas.com/), and [JOJ](https://joj.sjtu.edu.cn/). Joint is related to JI and also this tool which join websites together. Teapot means to hold Gitea, inspired by [@nichujie](https://github.com/nichujie). +A handy tool for TAs in JI to handle works through [Gitea](https://focs.ji.sjtu.edu.cn/git/), [Canvas](https://umjicanvas.com/), [JOJ](https://joj.sjtu.edu.cn/) and [Mattermost](https://focs.ji.sjtu.edu.cn/mm/). Joint is related to JI and also this tool which join websites together. Teapot means to hold Gitea, inspired by [@nichujie](https://github.com/nichujie). This tool is still under heavy development. The docs may not be updated on time, and all the features are provided with the probability to change. @@ -85,6 +85,11 @@ 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 diff --git a/joint_teapot/app.py b/joint_teapot/app.py index e25f2cf..9c3bed7 100644 --- a/joint_teapot/app.py +++ b/joint_teapot/app.py @@ -165,6 +165,14 @@ def create_webhooks_for_mm(prefix: str = Argument("")) -> None: tea.pot.mattermost.create_webhooks_for_repos(repo_names, tea.pot.gitea) +@app.command( + "unsubscribe-from-repos", + help="unsubscribe from all repos whose name match the given regex pattern", +) +def unsubscribe_from_repos(pattern: str = Argument("")) -> None: + tea.pot.gitea.unsubscribe_from_repos(pattern) + + if __name__ == "__main__": try: app() diff --git a/joint_teapot/workers/gitea.py b/joint_teapot/workers/gitea.py index 0b4c485..40b817a 100644 --- a/joint_teapot/workers/gitea.py +++ b/joint_teapot/workers/gitea.py @@ -1,3 +1,4 @@ +import re from datetime import datetime from enum import Enum from functools import lru_cache @@ -397,6 +398,25 @@ class Gitea: res[team.name] = members return res + def unsubscribe_from_repos(self, pattern: str) -> None: + subscriptions = [ + sub + for sub in self.user_api.user_current_list_subscriptions() + if sub.owner.login == self.org_name + and re.search(pattern, sub.name) is not None + ] + if len(subscriptions) == 0: + logger.warning(f"No subscribed repo matches the pattern {pattern}") + return + logger.info( + f"{len(subscriptions)} subscriptions match the pattern {pattern}: {[s.name for s in subscriptions]}" + ) + for sub in subscriptions: + self.repository_api.user_current_delete_subscription( + self.org_name, sub.name + ) + logger.info(f"Unsubscribed from {sub.name}") + if __name__ == "__main__": gitea = Gitea()