Ejemplo n.º 1
0
async def aux_go_for_help_from_command(ctx, member: discord.Member) -> bool:
    await aux_leave_group(ctx, member, show_not_in_group_error=False)
    # Get next group
    guild = member.guild
    async with help_queue_lock:
        group, message_id = GUILD_CONFIG.help_queue(guild).next()
    if not group:
        return False
    # If group found
    general_text_channel = hpf.get_general_text_channel(guild)
    try:
        message = await general_text_channel.fetch_message(message_id)
        await message.add_reaction(get_unicode_emoji_from_alias('thumbsup'))
    except discord.NotFound:
        pass
    if general_text_channel:
        await general_text_channel.send(
            btm.info_on_the_way_to(member, hpf.get_lab_group_name(group)))
    # Go for help
    group_text_channel = hpf.get_lab_text_channel(guild, group)
    if group_text_channel:
        await group_text_channel.send(
            btm.message_help_on_the_way(member, show_mention=True))
    await aux_join_group(ctx, member, group, group_message=False)
    return True
Ejemplo n.º 2
0
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))
Ejemplo n.º 3
0
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))
Ejemplo n.º 4
0
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))
Ejemplo n.º 5
0
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))
Ejemplo n.º 6
0
async def aux_delete_group(ctx,
                           group: Union[int, str],
                           show_bot_message: bool = True):
    async with create_delete_lock:
        guild = ctx.guild
        category = hpf.get_lab_group(guild, group)
        role = hpf.get_lab_role(guild, group)
        success = False
        if category:
            channels = category.channels
            for group_member in (role.members if role else []):
                await aux_leave_group(ctx,
                                      group_member,
                                      show_not_in_group_error=False)
            for channel in channels:
                print(f'Deleting channel: {channel.name}')
                await channel.delete()
            print(f'Deleting category: {category.name}')
            await category.delete()
            await aux_remove_group(guild, category)
            success = True
        elif show_bot_message:
            await ctx.send(btm.message_group_not_exists_error(category.name))
        if role:
            print(f'Deleting role: {role.name}')
            await role.delete()
        if success and show_bot_message:
            general_text_channel = hpf.get_general_text_channel(guild)
            if general_text_channel:
                await general_text_channel.send(
                    btm.message_group_deleted(category.name))
Ejemplo n.º 7
0
async def save_all_task():
    await bot.wait_until_ready()
    guild = bot.get_guild(int(TEST_GUILD_ID))
    general_text_channel = hpf.get_general_text_channel(guild)
    sleep_time = timedelta(hours=12, minutes=0, seconds=0)
    while True:
        await GUILD_CONFIG.save_all()
        now = datetime.now()
        await general_text_channel.send(
            f"Last config snapshot at {now.strftime('%H:%M:%S %Z on %d %b %Y')}"
        )
        await asyncio.sleep(sleep_time.seconds)
Ejemplo n.º 8
0
async def aux_broadcast(ctx, message: str):
    guild = ctx.guild
    general_text_channel = hpf.get_general_text_channel(guild)
    if general_text_channel:
        await general_text_channel.send(
            btm.broadcast_message_from(ctx.author, message))
    for group in hpf.all_existing_lab_groups(guild):
        text_channel = hpf.get_lab_text_channel(guild, group.name)
        if GUILD_CONFIG.broadcast_to_empty_groups(guild) or len(
                hpf.all_students_in_group(guild, group.name)) > 0:
            await text_channel.send(
                btm.broadcast_message_from(ctx.author, message))
Ejemplo n.º 9
0
async def aux_raise_hand(ctx):
    member = ctx.author
    existing_lab_group = hpf.existing_member_lab_group(member)
    general_text_channel = hpf.get_general_text_channel(ctx.guild)
    if not existing_lab_group:
        await ctx.channel.send(btm.message_member_not_in_group_for_help())
    elif ctx.channel != hpf.existing_member_lab_text_channel(member):
        await ctx.channel.send(
            btm.error_stay_in_your_seat(ctx.author, existing_lab_group))
    elif general_text_channel:
        group_num = hpf.get_lab_group_number(existing_lab_group.name)
        # Check if group already asked for help
        async with help_queue_lock:
            help_queue = GUILD_CONFIG.help_queue(ctx.guild)
            queue_size = help_queue.size()
            if group_num in help_queue:
                await ctx.channel.send(
                    btm.info_help_queue_size(queue_size -
                                             1) if queue_size > 1 else ":eyes:"
                )
                return
        # Get help
        online_team = hpf.all_teaching_team_members(ctx.author.guild)
        available_team = [
            member for member in online_team
            if not hpf.existing_member_lab_group(member)
        ]
        help_message = None
        if available_team:
            await ctx.channel.send(btm.message_asking_for_help())
            help_message = await general_text_channel.send(
                btm.message_call_for_help(existing_lab_group.name,
                                          available_team))
        elif online_team:
            await ctx.channel.send(btm.message_no_one_available_error())
            help_message = await general_text_channel.send(
                btm.message_call_for_help(existing_lab_group.name,
                                          online_team))
        else:
            await ctx.channel.send(btm.message_no_one_online_error())
        if help_message:
            async with help_queue_lock:
                if queue_size > 0:
                    await ctx.channel.send(btm.info_help_queue_size(queue_size)
                                           )
                help_queue.add(group=group_num, message_id=help_message.id)
    else:
        await ctx.channel.send(btm.message_can_not_get_help_error())
Ejemplo n.º 10
0
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))
Ejemplo n.º 11
0
async def aux_create_group(ctx) -> Optional[discord.CategoryChannel]:
    async with create_delete_lock:
        # Get existing lab groups
        guild = ctx.guild
        existing_lab_groups = hpf.all_existing_lab_groups(guild)
        # Get new group number (assumes a previous lab group could have been deleted)
        next_num = 1
        for idx, category in enumerate(
                sorted(existing_lab_groups, key=lambda c: c.name), 2):
            pattern = re.compile(f"Group[\s]+{next_num}")
            if re.search(pattern, category.name) is None:
                break
            next_num = idx
        # Create new names
        new_category_name = hpf.get_lab_group_name(next_num)
        new_role_name = hpf.get_role_name(next_num)
        text_channel_name = hpf.get_text_channel_name(next_num)
        voice_channel_name = hpf.get_voice_channel_name(next_num)
        # Check if category or channels already exist
        existing_category = discord.utils.get(guild.categories,
                                              name=new_category_name)
        existing_text_channel = discord.utils.get(guild.channels,
                                                  name=text_channel_name)
        existing_voice_channel = discord.utils.get(guild.channels,
                                                   name=voice_channel_name)
        if not (existing_category or existing_text_channel
                or existing_voice_channel):
            try:
                # Create new role
                new_role = await create_new_role(guild,
                                                 new_role_name,
                                                 mentionable=True)
                # Set lab group permissions
                default = discord.Permissions()
                allow_text_voice_stream = discord.Permissions(
                    PMask.VIEW | PMask.PARTIAL_TEXT | PMask.PARTIAL_VOICE
                    | PMask.STREAM)
                can_not_view_channel = discord.Permissions(PMask.VIEW)
                overwrites = {
                    role: discord.PermissionOverwrite.from_pair(
                        default, can_not_view_channel)
                    for role in hpf.all_existing_lab_roles(guild)
                }
                student_role = discord.utils.get(guild.roles,
                                                 name=STUDENT_ROLE_NAME)
                if student_role:
                    overwrites[
                        student_role] = discord.PermissionOverwrite.from_pair(
                            default, can_not_view_channel)
                overwrites[new_role] = discord.PermissionOverwrite.from_pair(
                    allow_text_voice_stream, default)
                # Create new lab group
                print(f'Creating a new category: {new_category_name}')
                new_category = await guild.create_category_channel(
                    new_category_name, overwrites=overwrites)
                # Deny access to the lab groups created before
                await update_previous_lab_groups_permission(
                    new_role, new_category, deny_mask=PMask.VIEW)
                # Create new text and voice channels
                print(
                    f'Creating a new channels: ({text_channel_name}) and ({voice_channel_name})'
                )
                text_channel = await new_category.create_text_channel(
                    text_channel_name)
                await new_category.create_voice_channel(voice_channel_name)
                # Success message
                general_text_channel = hpf.get_general_text_channel(guild)
                if general_text_channel:
                    await general_text_channel.send(
                        btm.message_group_created(new_category_name, next_num))
                await text_channel.send(
                    btm.message_welcome_group(new_category_name))
                await open_group(guild, new_category)
                return new_category
            except Exception as e:
                print(e)
                await ctx.send(btm.message_unexpected_error("create-group"))
                await aux_delete_group(ctx, next_num, show_bot_message=False)
                raise e