feat(mm): create individual channel (#49)
This commit is contained in:
parent
1c90f55013
commit
d564aff885
|
@ -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, "
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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}"
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user