async def aux_invite_member(ctx, host_member: discord.Member, invited_member: discord.Member): guild = ctx.guild existing_lab_group = hpf.existing_member_lab_group(host_member) if not existing_lab_group: await ctx.send(btm.error_not_in_group_for_invite(host_member)) elif hpf.member_in_teaching_team(invited_member, guild): await ctx.send(btm.error_can_not_invite_teaching_team()) else: async with invites_lock: group_num = hpf.get_lab_group_number(existing_lab_group.name) invite_list = GUILD_CONFIG.group_invites(guild) if hpf.existing_member_lab_group(invited_member): await ctx.send( btm.error_member_already_in_group(invited_member.name, existing_lab_group.name)) elif invite_list.has_invite(invited_member.id, group_num): await ctx.send(btm.error_invite_already_sent(invited_member)) else: # Add invitation invite_list.add_invite(invited_member.id, group_num) general_text_channel = hpf.get_general_text_channel(guild) if general_text_channel: await general_text_channel.send( btm.success_invite_sent_to_group( invited_member, existing_lab_group, group_num)) group_channel = hpf.get_lab_text_channel(guild, group_num) if group_channel: await group_channel.send( btm.success_invite_sent(invited_member))
async def leave_group(guild: discord.Guild, member: discord.Member, existing_lab_role: discord.Role, existing_lab_group: discord.CategoryChannel, group_message: bool = True, general_message: bool = True): # Disconnect from the group voice channel if connected to it voice_channel = hpf.existing_member_lab_voice_channel(member) if voice_channel and member.voice and member.voice.channel == voice_channel: general_voice_channel = hpf.get_general_voice_channel(guild) # if no general_voice_channel, it will move user out of the current voice channel await member.move_to(general_voice_channel if hpf. member_in_teaching_team(member, guild) else None) # Message to group text channel text_channel = hpf.existing_member_lab_text_channel(member) if group_message and text_channel: await text_channel.send( btm.message_member_left_group(hpf.get_nick(member), existing_lab_group.name)) # Remove group role await member.remove_roles(existing_lab_role) print(f'Role "{existing_lab_role}" removed to {member}') # Message to general channel general_text_channel = hpf.get_general_text_channel(guild) if general_message and general_text_channel and not hpf.member_in_teaching_team( member, guild): await general_text_channel.send( btm.message_member_left_group(hpf.get_nick(member), existing_lab_group.name))
async def join_group(guild: discord.Guild, member: discord.Member, new_role: discord.Role, new_lab_group: discord.CategoryChannel, group_message: bool = True, general_message: bool = True): await member.add_roles(new_role) print(f'Role "{new_role}" assigned to {member}') # Move to voice channel if connected voice_channel = hpf.get_lab_voice_channel(guild, new_lab_group.name) if voice_channel and member.voice and member.voice.channel: await member.move_to(voice_channel) # Message to group text channel text_channel = hpf.get_lab_text_channel(guild, new_lab_group.name) if group_message and text_channel: await text_channel.send( btm.message_mention_member_when_join_group(member, new_lab_group.name)) # Message to general channel general_text_channel = hpf.get_general_text_channel(guild) if general_message and general_text_channel and not hpf.member_in_teaching_team( member, guild): await general_text_channel.send( btm.message_member_joined_group(hpf.get_nick(member), new_lab_group.name))
async def aux_leave_group(ctx, member: discord.Member, group_message: bool = True, general_message: bool = True, show_open_message: bool = True, show_not_in_group_error: bool = True): guild = ctx.guild existing_lab_role = hpf.existing_member_lab_role(member) if existing_lab_role: existing_lab_group = hpf.existing_member_lab_group(member) await leave_group(guild, member, existing_lab_role, existing_lab_group, group_message=group_message, general_message=general_message) # If group get empty, open it if len(hpf.all_students_in_group(guild, existing_lab_group.name)) < 1 \ and is_closed_group(guild, existing_lab_group) \ and not hpf.member_in_teaching_team(member, guild): await open_group(guild, existing_lab_group) if show_open_message: general_text_channel = hpf.get_general_text_channel(guild) await general_text_channel.send( btm.success_group_open(existing_lab_group)) elif show_not_in_group_error: await ctx.send(btm.message_member_not_in_any_group(member))
async def aux_close_group(ctx, group: Optional[discord.CategoryChannel]): guild = ctx.guild member_group = hpf.existing_member_lab_group(ctx.author) is_in_teaching_team = hpf.member_in_teaching_team(ctx.author, guild) if not member_group and not is_in_teaching_team: await ctx.send(btm.message_member_not_in_any_group(ctx.author)) elif group and (not (is_in_teaching_team or group == member_group)): await ctx.send( btm.error_member_not_part_of_group( ctx.author, group if group else member_group)) else: group_to_be_closed = group if group else member_group await close_group(guild, group_to_be_closed) general_text_channel = hpf.get_general_text_channel(guild) if general_text_channel: await general_text_channel.send( btm.success_group_closed(group_to_be_closed)) print("OPEN_GROUPS", GUILD_CONFIG.open_groups(guild)) print("CLOSED_GROUPS", GUILD_CONFIG.closed_groups(guild))
async def on_reaction_add(reaction: discord.Reaction, user: Union[discord.Member, discord.User]): message = reaction.message emoji = reaction.emoji guild = message.guild # bot reacted for marking the message as attended if bot.user == user: return elif message.author == bot.user and re.search(r"calling for help", message.content): success = False if len(message.reactions) <= 1 and hpf.member_in_teaching_team(user, guild): success = await rhh.go_for_help_from_message(user, message, group=hpf.get_lab_group_number(message.content)) if not success: await message.remove_reaction(reaction, user) elif message.author == bot.user and len(message.reactions) <= 1: if same_emoji(emoji, 'slight_smile'): await message.add_reaction(get_unicode_emoji_from_alias('thumbsup')) await message.channel.send(emoji) else: print(emoji, get_unicode_from_emoji(emoji))
async def aux_make_group( ctx, members: List[discord.Member], random_choice: bool = False) -> Optional[discord.CategoryChannel]: guild = ctx.guild if not hpf.member_in_teaching_team(ctx.author, guild) and ctx.author not in members: members.append(ctx.author) members = set(members) max_group_size = GUILD_CONFIG.max_students_per_group(guild) # Check if there are not more members than allowed if len(members) > max_group_size: await ctx.send(btm.message_too_many_members_error(max_group_size)) return None members_with_groups = False # Check if any member is already in any group for member in members: existing_lab_group = hpf.existing_member_lab_group(member) if existing_lab_group: members_with_groups = True await ctx.send( btm.error_member_already_in_group(hpf.get_nick(member), existing_lab_group.name)) if members_with_groups: return None empty_groups = hpf.all_empty_groups(guild) if not empty_groups: extra_group = await aux_create_group(ctx) empty_groups.append(extra_group) if random_choice: new_group = random.choice(empty_groups) else: new_group = sorted(empty_groups, key=lambda g: g.name, reverse=False)[0] print( f'Moving members {" ".join([hpf.get_nick(m) for m in members])} to {new_group.name}' ) success = True for member in members: success = success and await aux_join_group(ctx, member, new_group.name) if success: return new_group
async def aux_random_join_all(ctx, *args): # Get excluded groups excluded_groups = hpf.get_excluded_groups(*args) if not excluded_groups: await ctx.send("All extra arguments should be integers!") return # Get available groups available_lab_groups = [] for group in hpf.all_existing_lab_groups(ctx.guild): group_number = hpf.get_lab_group_number(group.name) if group_number and group not in excluded_groups and is_open_group( ctx.guild, group): available_lab_groups.append(group) no_group_members = hpf.all_members_with_no_group(ctx.guild) # Assign groups for member in no_group_members: if not member.bot and member.status == discord.Status.online \ and not hpf.member_in_teaching_team(member, ctx.guild): available_lab_groups = await random_assignment( ctx, member, available_lab_groups)
async def aux_join_group(ctx, member: discord.Member, group: Union[int, str], group_message: bool = True, general_message: bool = True) -> bool: guild = ctx.guild new_role = hpf.get_lab_role(guild, group) new_lab_group = hpf.get_lab_group(guild, group) existing_lab_group = hpf.existing_member_lab_group(member) max_group_size = GUILD_CONFIG.max_students_per_group(guild) if GUILD_CONFIG.require_nickname(guild) and not member.nick: await ctx.send(btm.message_member_need_name_error(member)) elif existing_lab_group: await ctx.send( btm.error_member_already_in_group(hpf.get_nick(member), existing_lab_group.name)) elif not new_role: await ctx.send(btm.message_lab_group_not_exists(new_lab_group.name)) elif not hpf.member_in_teaching_team(member, guild) and len( hpf.all_students_in_group(guild, group)) >= max_group_size: await ctx.send( btm.message_max_members_in_group_error(new_lab_group.name, max_group_size)) else: if not hpf.member_in_teaching_team(member, guild): group_num = hpf.get_lab_group_number(new_lab_group.name) async with invites_lock: invite_list = GUILD_CONFIG.group_invites(guild) invited = invite_list.has_invite(member.id, group_num) if is_closed_group(guild, new_lab_group) and not invited: text_channel = hpf.get_lab_text_channel(guild, group) if text_channel: await text_channel.send( btm.error_someone_try_to_enter(member)) await ctx.send(btm.error_lab_group_is_closed(new_lab_group) ) return False if invited: invite_list.remove_invite(member.id, group_num) await join_group(guild, member, new_role, new_lab_group, group_message=group_message, general_message=general_message) else: await join_group(guild, member, new_role, new_lab_group, group_message=group_message, general_message=general_message) # Remove other invitations async with invites_lock: invite_list = GUILD_CONFIG.group_invites(guild) old_invites = invite_list.retrieve_invites(member.id) for group_invite in old_invites: text_channel = hpf.get_lab_text_channel(guild, group_invite) await text_channel.send( btm.info_member_accepted_another_invite(member)) return True return False