Ejemplo n.º 1
0
    async def showcase(self, ctx):
        """
        [MOD ONLY] Publicly announce the currently selected application in the Spotlight channel,
        and switch the Spotlight Host role to the application's owner (if valid).
        """

        # Retrieve and showcase the app
        logger.debug("showcase: {}".format(message_log_str(ctx.message)))
        self._load_applications()
        try:
            current_app = await self._get_current()
        except IndexError:
            return  # get_current() already handles this

        try:
            role = get_named_role(ctx.message.server, self.role_audience_name)
        except ValueError:
            logger.exception("Can't retrieve Spotlight Audience role")
            role = None

        await self.bot.send_message(self.channel_spotlight,
            "**WORLD SPOTLIGHT** {2}\n\n"
            "Our next host is {0}, presenting their project, *{1}*!\n\n"
            "Welcome, {0}!".format(
                current_app.user_disp,
                current_app.project,
                role.mention if role else ""
            )
        )
        await self.send_spotlight_info(self.channel_spotlight, current_app)
        await self.bot.say("Application showcased: {} ({}) - {}"
            .format(current_app.user_disp, current_app.user_name_only, current_app.project)
        )
        await self.send_validation_warnings(ctx, current_app)

        # Deassign the spotlight host role
        server = ctx.message.server  # type: discord.Server
        host_role = get_named_role(server, self.role_host_name)
        await remove_role_from_all(self.bot, server, host_role)

        # Assign the role to the selected app's owner
        try:
            user = get_member(ctx, current_app.user_id)
        except discord.InvalidArgument:
            logger.warning("Invalid discord ID in application: '{}'".format(current_app.user_id))
            await self.bot.say(("Can't set new Spotlight Host role: Application Discord ID "
                                "'{0.user_id}' is invalid or user not on server")
                .format(current_app))
        else:
            await self.bot.add_roles(user, host_role)
            await self.bot.say("'{}' role switched to {.mention}."
                .format(self.role_host_name, user))
Ejemplo n.º 2
0
 async def on_ready(self):
     await super().on_ready()
     self.check_in_channel = self.get_channel(self.check_in_channel_id)
     self.checkin_anytime_roles = tuple(
         get_named_role(self.server, n)
         for n in self.cog_config.check_in_window_exempt_roles)
     milestone_map = {}
     for pt, ms_map in self.cog_config.milestone_map.items():
         milestone_map[model.ProjectType[pt]] = {
             get_named_role(self.server, r): v
             for r, v in ms_map.items()
         }
     self.c = CheckInController(self.server, self.cog_config, milestone_map)
     await self.schedule_checkin_announcements()
Ejemplo n.º 3
0
    def _process_checks(data: dict, command: commands.Command, bot: commands.Bot):
        roles = []
        channels = []
        new_brief = ''
        for check in command.checks:
            # get check data
            try:
                check_type = check.kaz_check_id
            except AttributeError:
                continue
            try:
                check_data = check.kaz_check_data
            except AttributeError:
                check_data = []

            # process check_type
            if check_type is CheckId.U_ROLE or check_type is CheckId.U_ROLE_OR_MODS:
                for role_name in check_data:
                    for server in bot.servers:
                        try:
                            role = get_named_role(server, role_name)
                            roles.append(role.name)
                            break
                        except ValueError:
                            continue
                    else:
                        roles.append(role_name + ' (not found)')
                if check_type is CheckId.U_ROLE_OR_MODS:
                    roles.append('Moderators')
                    roles.append('Administrators')
            elif check_type is CheckId.U_MOD:
                roles = ['Moderators', 'Administrators']
                new_brief = '[MOD ONLY] ' + data['brief']
            elif check_type is CheckId.U_ADMIN:
                roles = ['Administrators']
                new_brief = '[ADMIN ONLY] ' + data['brief']
            elif check_type is CheckId.C_LIST:
                for ch_id in check_data:
                    ch = bot.get_channel(ch_id)  # type: discord.Channel
                    if ch is not None:
                        channels.append('#' + ch.name)
                        break
                    else:
                        channels.append(ch_id + ' (not found)')
            elif check_type is CheckId.C_MOD:
                channels = ['Mod channels']
                new_brief = '[MOD ONLY] ' + data['brief']
            elif check_type is CheckId.C_ADMIN:
                channels = ['Admin channels']
                new_brief = '[ADMIN ONLY] ' + data['brief']
            elif check_type is CheckId.C_PM_ONLY:
                channels = ['PM only']
                new_brief = '[PM ONLY]' + data['brief']

        if roles:
            data['users'] = ', '.join(roles) + '. ' + data['users']
        if channels:
            data['channels'] = ', '.join(channels) + '. ' + data['channels']
        if new_brief:
            data['brief'] = new_brief
Ejemplo n.º 4
0
    async def down(self, ctx):
        """
        [MOD ONLY] Uncolours a moderator's username.

        This command undoes the `.up` command.

        Arguments: None
        """
        logger.debug("down: {}".format(message_log_str(ctx.message)))

        for status_role_name, distinguish_role_name in self.distinguish_map.items(
        ):
            status_role = discord.utils.get(ctx.message.server.roles,
                                            name=status_role_name)
            if status_role and status_role in ctx.message.author.roles:
                distinguish_role = get_named_role(ctx.message.server,
                                                  distinguish_role_name)
                await self.bot.remove_roles(ctx.message.author,
                                            distinguish_role)
                await self.bot.delete_message(ctx.message)
                logger.info("down: Took away from {} the {} role".format(
                    ctx.message.author, distinguish_role_name))
                break
        else:
            err_msg = "down: user's roles not recognised: {}".format(
                message_log_str(ctx.message))
            logger.warning(err_msg)
            await self.bot.say(
                "That command is only available to mods and admins.")
            await self.send_output("[WARNING] " + err_msg)
Ejemplo n.º 5
0
    async def up(self, ctx):
        """
        [MOD ONLY] Colours a moderator's username.

        This command colours the moderator's username by applying a special role to it. This is
        used for moderators to be able to signal when they are speaking or intervening officially
        in their role as moderator.

        Arguments: None
        """
        logger.debug("up: {}".format(message_log_str(ctx.message)))

        for status_role_name, distinguish_role_name in self.distinguish_map.items(
        ):
            status_role = discord.utils.get(ctx.message.server.roles,
                                            name=status_role_name)
            if status_role and status_role in ctx.message.author.roles:
                distinguish_role = get_named_role(ctx.message.server,
                                                  distinguish_role_name)
                await self.bot.add_roles(ctx.message.author, distinguish_role)
                await self.bot.delete_message(ctx.message)
                logger.info("up: Gave {} the {} role".format(
                    ctx.message.author, distinguish_role_name))
                break
        else:
            err_msg = "up: user's roles not recognised: {}".format(
                message_log_str(ctx.message))
            logger.warning(err_msg)
            await self.bot.say(
                "That command is only available to mods and admins.")
            await self.send_output("[WARNING] " + err_msg)
Ejemplo n.º 6
0
 def __init__(self, bot):
     super().__init__(bot, 'modnotes', BanToolsConfig)
     self.cog_config.set_defaults(
         ban_check_interval=3600,
         ban_temp_expires='in 7 days',
         ban_temp_enforce=False,
         ban_perma_enforce=False
     )
     self.cog_config.set_converters('ban_check_interval', lambda s: timedelta(seconds=s), None)
     self.cog_config.set_converters('ban_role', lambda r: get_named_role(self.server, r), None)
     self.cog_config.set_converters('channel_mod', self.get_channel, None)
     self.cog_modnotes: ModNotes = None
     self.modnotes_patch_applied = False
Ejemplo n.º 7
0
    async def do_join(self, ctx: commands.Context):
        logger.debug("join({}): {}".format(self.name,
                                           message_log_str(ctx.message)[:256]))
        role = get_named_role(ctx.message.server, self.name)

        if role not in ctx.message.author.roles:
            await self.bot.add_roles(ctx.message.author, role)
            logger.info("join: Gave role {} to user {}".format(
                self.name, ctx.message.author))
            await self.bot.send_message(self.reply_dest(ctx),
                                        self.join_message(ctx))
        else:
            await self.bot.send_message(self.reply_dest(ctx),
                                        self.join_error(ctx))
        await self.delete_message(ctx)
Ejemplo n.º 8
0
    async def do_leave(self, ctx: commands.Context):
        logger.debug("leave({}): {}".format(self.name,
                                            message_log_str(
                                                ctx.message)[:256]))
        role = get_named_role(ctx.message.server, self.name)

        if role in ctx.message.author.roles:
            await self.bot.remove_roles(ctx.message.author, role)
            logger.info("leave: Removed role {} from user {}".format(
                self.name, ctx.message.author))
            await self.bot.send_message(self.reply_dest(ctx),
                                        self.leave_message(ctx))
        else:
            await self.bot.send_message(self.reply_dest(ctx),
                                        self.leave_error(ctx))
        await self.delete_message(ctx)
Ejemplo n.º 9
0
    async def leave(self, ctx):
        """
        Leave the Spotlight Audience. See `.help spotlight join` for more information.

        To join the Spotlight Audience, use `.spotlight join`.
        """
        logger.debug("leave: " + message_log_str(ctx.message)[:64])
        role = get_named_role(ctx.message.server, self.role_audience_name)

        if role in ctx.message.author.roles:
            await self.bot.remove_roles(ctx.message.author, role)
            logger.info("leave: Removed role {} from user {}"
                .format(self.role_audience_name, ctx.message.author))
            await self.bot.send_message(ctx.message.author, self.msg_leave)
        else:
            await self.bot.send_message(ctx.message.author, self.msg_leave_err)
        await self.bot.delete_message(ctx.message)
Ejemplo n.º 10
0
    async def join(self, ctx):
        """
        Join the Spotlight Audience. This allows you to be pinged by moderators or the Spotlight
        Host for news about the spotlight (like the start of a new spotlight, or a newly released
        schedule).

        To leave the Spotlight Audience, use `.spotlight leave`.
        """
        logger.debug("join: " + message_log_str(ctx.message)[:64])
        role = get_named_role(ctx.message.server, self.role_audience_name)

        if role not in ctx.message.author.roles:
            await self.bot.add_roles(ctx.message.author, role)
            logger.info("join: Gave role {} to user {}"
                .format(self.role_audience_name, ctx.message.author))
            await self.bot.send_message(ctx.message.author, self.msg_join)
        else:
            await self.bot.send_message(ctx.message.author, self.msg_join_err)
        await self.bot.delete_message(ctx.message)
Ejemplo n.º 11
0
def get_role(server: discord.Server, role_arg: str) -> discord.Role:
    """
    Get a role from a passed command parameter (name, mention or ID).
    :return:
    """
    try:
        role_id = extract_role_id(role_arg)
    except discord.InvalidArgument:  # no ID, treat as a role name
        try:
            role = get_named_role(server, role_arg)  # type: discord.Role
        except discord.InvalidArgument:
            logger.warning("Cannot find role {!r} as name or ID".format(role_arg))
            role = None
    else:
        logger.debug("Found role ID in {!r}".format(role_arg))
        role = discord.utils.get(server.roles, id=role_id)  # type: discord.Role

    if role is None:
        raise commands.BadArgument('No such role: {}'.format(role))
    return role
Ejemplo n.º 12
0
    async def on_voice_state_update(self, before: discord.Member, after: discord.Member):
        """ Assigns "in voice" role to members who join voice channels. """
        if not self.voice_feature:
            return

        # get the role
        role_voice = get_named_role(before.server, self.role_voice_name)
        if role_voice is None:
            err_msg = "Cannot find voice role: {}" .format(self.role_voice_name)
            logger.warning(err_msg)
            await self.bot.send_message(self.dest_output, "[WARNING] " + err_msg)
            return

        # determine the action to take
        if after.voice_channel and after.voice_channel.id in self.voice_channel_ids:
            await self.bot.add_roles(after, role_voice)
            logger.info("Gave '{}' role to {}".format(self.role_voice_name, after))
        else:
            await self.bot.remove_roles(after, role_voice)
            logger.info("Took '{}' role from {}".format(self.role_voice_name, after))
Ejemplo n.º 13
0
    async def update_tempbans(self):
        """
        Check and update all current tempbans in modnotes. Unexpired tempbans will be applied and
        expired tempbans will be removed, when needed.
        """
        logger.info("Checking all tempbans.")
        try:
            server = self.bot.get_channel(
                self.ch_mod.id).server  # type: discord.Server
        except AttributeError:  # get_channel failed
            logger.error("Can't find mod channel")
            await self.send_output(
                "**ERROR**: update_tempbans: can't find mod channel")
            return

        tempban_role = get_named_role(server, self.role_name)
        bans_db = self._get_tempbanned_members_db(server)
        bans_server = self._get_tempbanned_members_server(server)

        # check if any members who need to be banned
        for member in bans_db:
            if member not in bans_server:
                logger.info(
                    "Applying tempban role '{role}' to {user!s}...".format(
                        role=tempban_role.name, user=member))
                await self.bot.add_roles(member, tempban_role)
                await self.bot.send_message(
                    self.ch_mod, "Tempbanned {.mention}".format(member))

        # check if any members who need to be unbanned
        for member in bans_server:
            if member not in bans_db:
                logger.info(
                    "Removing tempban role '{role}' to {user!s}...".format(
                        role=tempban_role.name, user=member))
                await self.bot.remove_roles(member, tempban_role)
                await self.bot.send_message(
                    self.ch_mod, "Unbanned {.mention}".format(member))
Ejemplo n.º 14
0
 def _get_tempbanned_members_server(
         self, server: discord.Server) -> List[discord.Member]:
     tempban_role = get_named_role(server, self.role_name)
     return [m for m in server.members if tempban_role in m.roles]