feat(mm): create individual channel (#49)

This commit is contained in:
mQzLjP 2025-02-23 21:30:11 +08:00 committed by GitHub
parent 1c90f55013
commit d564aff885
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 106 additions and 8 deletions

View File

@ -172,14 +172,14 @@ def upload_assignment_grades(assignments_dir: Path, assignment_name: str) -> Non
@app.command( @app.command(
"create-channels-on-mm", "create-group-channels-on-mm",
help="create channels for student groups according to group information on" help="create channels for student groups according to group information on"
" gitea", " gitea",
) )
def create_channels_on_mm( def create_group_channels_on_mm(
prefix: str = Option(""), prefix: str = Option(""),
suffix: str = Option(""), suffix: str = Option(""),
invite_teaching_team: bool = Option(False), invite_teaching_team: bool = Option(True),
) -> None: ) -> None:
groups = { groups = {
group_name: members group_name: members
@ -195,6 +195,16 @@ def create_channels_on_mm(
tea.pot.mattermost.create_channels_for_groups(groups, suffix, invite_teaching_team) tea.pot.mattermost.create_channels_for_groups(groups, suffix, invite_teaching_team)
@app.command(
"create-personal-channels-on-mm",
help="create channels for every student",
)
def create_personal_channels_on_mm(
invite_teaching_team: bool = Option(True),
) -> None:
tea.pot.create_channels_for_individuals(invite_teaching_team)
@app.command( @app.command(
"create-webhooks-for-mm", "create-webhooks-for-mm",
help="create a pair of webhooks on gitea and mm for all student groups on gitea, " help="create a pair of webhooks on gitea and mm for all student groups on gitea, "

View File

@ -10,7 +10,7 @@ class Settings(BaseSettings):
""" """
# canvas # canvas
canvas_domain_name: str = "jicanvas.com" canvas_domain_name: str = "oc.sjtu.edu.cn"
canvas_suffix: str = "/" canvas_suffix: str = "/"
canvas_access_token: str = "" canvas_access_token: str = ""
canvas_course_id: int = 0 canvas_course_id: int = 0

View File

@ -13,7 +13,7 @@ _T = TypeVar("_T")
def for_all_methods( def for_all_methods(
decorator: Callable[[Callable[[_T], _T]], Any] decorator: Callable[[Callable[[_T], _T]], Any],
) -> Callable[[_T], _T]: ) -> Callable[[_T], _T]:
@functools.wraps(decorator) @functools.wraps(decorator)
def decorate(cls: Any) -> Any: def decorate(cls: Any) -> Any:
@ -204,6 +204,13 @@ class Teapot:
f"{commit_count} commit(s), {issue_count} issue(s)" f"{commit_count} commit(s), {issue_count} issue(s)"
) )
def create_channels_for_individuals(
self, invite_teaching_teams: bool = True
) -> None:
return self.mattermost.create_channels_for_individuals(
self.canvas.students, invite_teaching_teams
)
if __name__ == "__main__": if __name__ == "__main__":
teapot = Teapot() teapot = Teapot()

View File

@ -30,8 +30,8 @@ def percentile(
def default_repo_name_convertor(user: User) -> str: def default_repo_name_convertor(user: User) -> str:
login_id, name = user.login_id, user.name sis_id, name = user.sis_id, user.name
eng = re.sub("[\u4e00-\u9fa5]", "", name) eng = re.sub("[\u4e00-\u9fa5]", "", name)
eng = eng.replace(",", "") eng = eng.replace(",", "")
eng = eng.title().replace(" ", "").replace("\xa0", "") eng = eng.title().replace(" ", "").replace("\xa0", "")
return f"{eng}{login_id}" return f"{eng}{sis_id}"

View File

@ -1,4 +1,5 @@
import os import os
import re
from glob import glob from glob import glob
from typing import cast from typing import cast
@ -33,6 +34,10 @@ class Canvas:
types = ["student"] types = ["student"]
def patch_student(student: User) -> User: def patch_student(student: User) -> User:
student.name = re.sub(
r"[^\x00-\x7F]+", "", student.name
).strip() # We only care english name
student.sis_id = student.login_id
student.login_id = student.email.split("@")[0] student.login_id = student.email.split("@")[0]
return student return student

View File

@ -1,6 +1,7 @@
from typing import Dict, List from typing import Dict, List
import focs_gitea import focs_gitea
from canvasapi.paginated_list import PaginatedList
from mattermostdriver import Driver from mattermostdriver import Driver
from joint_teapot.config import settings from joint_teapot.config import settings
@ -47,7 +48,7 @@ class Mattermost:
self, self,
groups: Dict[str, List[str]], groups: Dict[str, List[str]],
suffix: str = "", suffix: str = "",
invite_teaching_team: bool = False, invite_teaching_team: bool = True,
) -> None: ) -> None:
for group_name, members in groups.items(): for group_name, members in groups.items():
channel_name = group_name + suffix channel_name = group_name + suffix
@ -75,6 +76,12 @@ class Mattermost:
logger.warning( logger.warning(
f"User {member} is not found on the Mattermost server" f"User {member} is not found on the Mattermost server"
) )
self.endpoint.posts.create_post(
{
"channel_id": channel["id"],
"message": f"User {member} is not found on the Mattermost server",
}
)
continue continue
# code for adding student to mm, disabled since there is no need to do that # code for adding student to mm, disabled since there is no need to do that
# try: # try:
@ -88,6 +95,75 @@ class Mattermost:
) )
except Exception: except Exception:
logger.warning(f"User {member} is not in the team") logger.warning(f"User {member} is not in the team")
self.endpoint.posts.create_post(
{
"channel_id": channel["id"],
"message": f"User {member} is not in the team",
}
)
logger.info(f"Added member {member} to channel {channel_name}")
def create_channels_for_individuals(
self,
students: PaginatedList,
invite_teaching_team: bool = True,
) -> None:
for student in students:
display_name = student.name
channel_name = student.sis_id
try:
channel = self.endpoint.channels.create_channel(
{
"team_id": self.team["id"],
"name": channel_name,
"display_name": display_name,
"type": "P", # create private channels
}
)
logger.info(
f"Added channel {display_name} ({channel_name}) to Mattermost"
)
except Exception as e:
logger.warning(
f"Error when creating channel {channel_name}: {e} Perhaps channel already exists?"
)
continue
members = [student.login_id]
if invite_teaching_team:
members.extend(settings.mattermost_teaching_team)
for member in members:
try:
mmuser = self.endpoint.users.get_user_by_username(member)
except Exception:
logger.warning(
f"User {member} is not found on the Mattermost server"
)
self.endpoint.posts.create_post(
{
"channel_id": channel["id"],
"message": f"User {member} is not found on the Mattermost server",
}
)
continue
# code for adding student to mm, disabled since there is no need to do that
# try:
# mmuser = self.endpoint.users.create_user({'email':f"{member}@sjtu.edu.cn", 'username':member, auth_service:"gitlab"})
# except e:
# logger.error(f"Error creating user {member}")
# continue
try:
self.endpoint.channels.add_user(
channel["id"], {"user_id": mmuser["id"]}
)
except Exception:
logger.warning(f"User {member} is not in the team")
self.endpoint.posts.create_post(
{
"channel_id": channel["id"],
"message": f"User {member} is not in the team",
}
)
logger.info(f"Added member {member} to channel {channel_name}") logger.info(f"Added member {member} to channel {channel_name}")
def create_webhooks_for_repos(self, repos: List[str], gitea: Gitea) -> None: def create_webhooks_for_repos(self, repos: List[str], gitea: Gitea) -> None: