diff --git a/joint_teapot/workers/mattermost.py b/joint_teapot/workers/mattermost.py index 93cc47d..ebd2a23 100644 --- a/joint_teapot/workers/mattermost.py +++ b/joint_teapot/workers/mattermost.py @@ -103,6 +103,91 @@ class Mattermost: ) logger.info(f"Added member {member} to channel {channel_name}") + def update_channels_for_groups( + self, + groups: Dict[str, List[str]], + suffix: str = "", + update_teaching_team: bool = True, + dry_run: bool = False, + ) -> None: + for group_name, members in groups.items(): + channel_name = group_name + suffix + try: + channel = self.endpoint.channels.get_channel_by_name(self.team["id"], channel_name) + logger.info(f"Channel {channel_name} exists, updating members") + except Exception: + # channel does not exist + if dry_run: + info_members = list(members) + if update_teaching_team: + info_members = info_members + settings.mattermost_teaching_team + logger.info(f"Dry run: would create channel {channel_name} and add members: {info_members}") + continue + try: + channel = self.endpoint.channels.create_channel( + { + "team_id": self.team["id"], + "name": channel_name, + "display_name": channel_name, + "type": "P", + } + ) + logger.info(f"Created channel {channel_name} on Mattermost") + except Exception as e: + logger.warning( + f"Error when creating channel {channel_name}: {e} Perhaps channel already exists?" + ) + continue + + current_members = set() + try: + mm_members = self.endpoint.channels.get_channel_members(channel["id"]) or [] + for m in mm_members: + uname = None + if isinstance(m, dict): + uname = m.get("username") or m.get("name") + if not uname and "user" in m and isinstance(m["user"], dict): + uname = m["user"].get("username") or m["user"].get("name") + if not uname and "user_id" in m: + try: + u = self.endpoint.users.get_user(m["user_id"]) or {} + if isinstance(u, dict): + uname = u.get("username") or u.get("name") + except Exception: + uname = None + if uname: + current_members.add(uname.lower()) + except Exception: + current_members = set() + + add_members = list(members) + if update_teaching_team: + add_members = add_members + settings.mattermost_teaching_team + + for member in add_members: + if member.lower() in current_members: + logger.debug(f"Member {member} already in channel {channel_name}") + continue + if dry_run: + logger.info(f"Dry run: would add member {member} to channel {channel_name}") + continue + 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 + 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}") + def create_channels_for_individuals( self, students: PaginatedList, @@ -166,6 +251,90 @@ class Mattermost: logger.info(f"Added member {member} to channel {channel_name}") + def update_channels_for_individuals( + self, + students: PaginatedList, + update_teaching_team: bool = True, + dry_run: bool = False, + ) -> None: + for student in students: + display_name = student.name + channel_name = student.sis_id + try: + channel = self.endpoint.channels.get_channel_by_name(self.team["id"], channel_name) + logger.info(f"Channel {channel_name} exists, updating members") + except Exception: + if dry_run: + members_info = [student.login_id] + if update_teaching_team: + members_info = members_info + settings.mattermost_teaching_team + logger.info(f"Dry run: would create channel {display_name} ({channel_name}) and add members: {members_info}") + continue + try: + channel = self.endpoint.channels.create_channel( + { + "team_id": self.team["id"], + "name": channel_name, + "display_name": display_name, + "type": "P", + } + ) + logger.info(f"Created channel {display_name} ({channel_name}) on Mattermost") + except Exception as e: + logger.warning( + f"Error when creating channel {channel_name}: {e} Perhaps channel already exists?" + ) + continue + + current_members = set() + try: + mm_members = self.endpoint.channels.get_channel_members(channel["id"]) or [] + for m in mm_members: + uname = None + if isinstance(m, dict): + uname = m.get("username") or m.get("name") + if not uname and "user" in m and isinstance(m["user"], dict): + uname = m["user"].get("username") or m["user"].get("name") + if not uname and "user_id" in m: + try: + u = self.endpoint.users.get_user(m["user_id"]) or {} + if isinstance(u, dict): + uname = u.get("username") or u.get("name") + except Exception: + uname = None + if uname: + current_members.add(uname.lower()) + except Exception: + current_members = set() + + members = [student.login_id] + if update_teaching_team: + members = members + settings.mattermost_teaching_team + + for member in members: + if member.lower() in current_members: + logger.debug(f"Member {member} already in channel {channel_name}") + continue + if dry_run: + logger.info(f"Dry run: would add member {member} to channel {channel_name}") + continue + 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 + 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}") + def create_webhooks_for_repos( self, repos: List[str], gitea: Gitea, gitea_suffix: bool ) -> None: