diff --git a/README.md b/README.md index f9b707f..69fddf6 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ pytest -svv ## Features - [ ] retreive the hw/project releases for all students -- [ ] open "bulk issues" to report something wrong +- [x] open "bulk issues" to report something wrong - [x] collect all the public keys - [x] import groups (create teams) - [x] create repos -- [ ] archive all repos of a course +- [x] archive all repos of a course diff --git a/joint_teapot/__init__.py b/joint_teapot/__init__.py index 36bdcfa..be3c3d3 100644 --- a/joint_teapot/__init__.py +++ b/joint_teapot/__init__.py @@ -1,3 +1,4 @@ from joint_teapot.canvas import Canvas as Canvas from joint_teapot.git import Git as Git from joint_teapot.gitea import Gitea as Gitea +from joint_teapot.teapot import Teapot as Teapot diff --git a/joint_teapot/__main__.py b/joint_teapot/__main__.py index a51d462..6c8e6b9 100644 --- a/joint_teapot/__main__.py +++ b/joint_teapot/__main__.py @@ -1,13 +1 @@ -from joint_teapot import Canvas, Gitea - __version__ = "0.0.0" - - -class Teapot: - def __init__(self) -> None: - self.canvas = Canvas() - self.gitea = Gitea() - - -if __name__ == "__main__": - teapot = Teapot() diff --git a/joint_teapot/config.py b/joint_teapot/config.py index 868ac3e..6a97143 100644 --- a/joint_teapot/config.py +++ b/joint_teapot/config.py @@ -22,6 +22,9 @@ class Settings(BaseSettings): gitea_access_token: str = "" org_name: str = "" + # git + repos_dir: str = "" + class Config: env_file = ".env" env_file_encoding = "utf-8" diff --git a/joint_teapot/git.py b/joint_teapot/git.py index d747e89..ee03ecc 100644 --- a/joint_teapot/git.py +++ b/joint_teapot/git.py @@ -6,24 +6,30 @@ from joint_teapot.config import settings class Git: - def __init__(self, org_name: str = settings.org_name, repos_dir: str = ""): + def __init__( + self, org_name: str = settings.org_name, repos_dir: str = settings.repos_dir + ): self.org_name = org_name if not os.path.isdir(repos_dir): raise Exception(f"{repos_dir} does not exist! Create it first.") self.repos_dir = repos_dir - def __get_repo(self, repo_name: str) -> git.Repo: + def clone_repo(self, repo_name: str) -> git.Repo: repo_dir = os.path.join(self.repos_dir, repo_name) - if os.path.exists(repo_dir): - return git.Repo(repo_dir) return git.Repo.clone_from( f"https://focs.ji.sjtu.edu.cn/git/{self.org_name}/{repo_name}", repo_dir, branch="master", ) + def get_repo(self, repo_name: str) -> git.Repo: + repo_dir = os.path.join(self.repos_dir, repo_name) + if os.path.exists(repo_dir): + return git.Repo(repo_dir) + return self.clone_repo(repo_dir) + def repo_clean_and_checkout(self, repo_name: str, checkout_dest: str) -> str: - repo = self.__get_repo(repo_name) + repo = self.get_repo(repo_name) repo.git.fetch("--tags", "--all", "-f") repo.git.reset("--hard", f"origin/master") repo.git.clean("-d", "-f", "-x") diff --git a/joint_teapot/gitea.py b/joint_teapot/gitea.py index cf00a9c..7028ca1 100644 --- a/joint_teapot/gitea.py +++ b/joint_teapot/gitea.py @@ -140,7 +140,7 @@ class Gitea: }, ) self.organization_api.org_add_team_repository( - team["id"], self.org_name, repo["name"] + team["id"], self.org_name, repo_name ) membership: GroupMembership for membership in group.get_memberships(): @@ -149,12 +149,14 @@ class Gitea: raise Exception( f"student with user_id {membership.user_id} not found" ) - self.organization_api.org_add_team_member( - team["id"], self.__get_username_by_canvas_student(student) + username = self.__get_username_by_canvas_student(student) + self.organization_api.org_add_team_member(team["id"]) + self.repository_api.repo_add_collaborator( + self.org_name, repo_name, username ) return repo_names - def get_public_key_of_students( + def get_public_key_of_canvas_students( self, students: PaginatedList ) -> List[List[Dict[str, Any]]]: return [ @@ -162,6 +164,38 @@ class Gitea: for student in students ] + def get_repos_releases(self, repo_names: List[str]) -> List[List[Dict[str, Any]]]: + return [ + self.repository_api.repo_list_releases(self.org_name, repo_name) + for repo_name in repo_names + ] + + def get_all_repo_names(self) -> List[str]: + return [ + data["name"] for data in self.organization_api.org_list_repos(self.org_name) + ] + + def create_issue( + self, + repo_name: str, + title: str, + body: str, + assign_every_collaborators: bool = True, + ) -> None: + assignees = [] + if assign_every_collaborators: + assignees = [ + item["username"] + for item in self.repository_api.repo_list_collaborators( + self.org_name, repo_name + ) + ] + self.issue_api.issue_create_issue( + self.org_name, + repo_name, + body={"title": title, "body": body, "assignees": assignees}, + ) + if __name__ == "__main__": gitea = Gitea() diff --git a/joint_teapot/teapot.py b/joint_teapot/teapot.py new file mode 100644 index 0000000..4a772a7 --- /dev/null +++ b/joint_teapot/teapot.py @@ -0,0 +1,39 @@ +from typing import Any, Dict, List + +from joint_teapot import Canvas, Git, Gitea + + +class Teapot: + def __init__(self) -> None: + self.canvas = Canvas() + self.gitea = Gitea() + self.git = Git() + + def create_personal_repos_for_all_canvas_students(self) -> List[str]: + return self.gitea.create_personal_repos_for_canvas_students( + self.canvas.students + ) + + def create_teams_and_repos_by_canvas_groups(self) -> List[str]: + return self.gitea.create_teams_and_repos_by_canvas_groups( + self.canvas.students, self.canvas.groups + ) + + def get_public_key_of_all_canvas_students(self) -> List[List[Dict[str, Any]]]: + return self.gitea.get_public_key_of_canvas_students(self.canvas.students) + + def archieve_all_repos(self) -> List[str]: + return [ + self.git.repo_clean_and_checkout(repo_name, "master") + for repo_name in self.gitea.get_all_repo_names() + ] + + def create_issue_for_repos( + self, repo_names: List[str], title: str, body: str + ) -> None: + for repo_name in repo_names: + self.gitea.create_issue(repo_name, title, body) + + +if __name__ == "__main__": + teapot = Teapot()