Example #1
0
 async def on_raw_reaction_add(self,
                               payload: discord.RawReactionActionEvent):
     guild = self.bot.get_guild(payload.guild_id)
     if guild is None:
         return
     user = guild.get_member(payload.user_id)
     if guild.me.id == payload.user_id:
         return
     try:
         message = await self.bot.get_channel(
             payload.channel_id).get_message(payload.message_id)
     except discord.NotFound:
         pass
     else:
         if str(payload.emoji) == str(Emoji.get_emoji('LEFT')):
             if await Pages.update(self.bot, message, "PREV",
                                   payload.user_id):
                 try:
                     await message.remove_reaction(Emoji.get_emoji('LEFT'),
                                                   user)
                 except discord.Forbidden:
                     pass
         elif str(payload.emoji) == str(Emoji.get_emoji('RIGHT')):
             if await Pages.update(self.bot, message, "NEXT",
                                   payload.user_id):
                 try:
                     await message.remove_reaction(Emoji.get_emoji('RIGHT'),
                                                   user)
                 except discord.Forbidden:
                     pass
Example #2
0
async def self_roles(bot, message, user_id, reaction, **kwargs):
    user = message.channel.guild.get_member(user_id)
    if user is None:
        if user_id is not 0:
            await remove_reaction(message, reaction, await bot.fetch_user(user_id))
            return kwargs
    bot.loop.create_task(remove_reaction(message, reaction, user))
    left = Emoji.get_chat_emoji('LEFT')
    right = Emoji.get_chat_emoji('RIGHT')
    refresh = Emoji.get_chat_emoji('REFRESH')
    r2 = "🔁"
    page_num = int(kwargs.get("page_num", 0))
    add = reaction not in [left, right, refresh, r2]
    if str(reaction) == left:
        page_num -= 1
        add = False
    elif str(reaction) == right:
        page_num += 1
        add = False
    elif str(reaction) in [refresh, r2]:
        if not message.channel.permissions_for(message.channel.guild.me).manage_messages:
            return kwargs
        await message.clear_reactions()
        await asyncio.sleep(0.2)
        add = False
    if add:
        for i in range(10):
            if str(reaction) == str(Emoji.get_emoji(str(i+1))):
                roles = Configuration.get_var(message.guild.id, "SELF_ROLES")
                role = message.channel.guild.get_role(roles[page_num*10 + i])
                if role is None:
                    await Selfroles.validate_self_roles(bot, message.channel.guild)
                    return
                add_role = role not in user.roles
                try:
                    await (user.add_roles if add_role else user.remove_roles)(role)
                except Forbidden:
                    if message.channel.permissions_for(message.channel.guild.me).send_messages:
                        await MessageUtils.send_to(message.channel, "NO", "role_too_high_add", role=role.name)
                        return kwargs
                else:
                    if message.channel.permissions_for(message.channel.guild.me).send_messages:
                        await MessageUtils.send_to(message.channel, "YES", "role_joined" if add_role else "role_left", role_name=await Utils.clean(role.name), delete_after=10)
                        bot.loop.create_task(remove_reaction(message, reaction, user))
                        return kwargs

        return kwargs
    pages = Selfroles.gen_role_pages(message.channel.guild)

    if page_num >= len(pages):
        page_num = 0
    elif page_num < 0:
        page_num = len(pages) - 1
    kwargs["page_num"] = page_num
    embed = Embed(title=Translator.translate("assignable_roles", message.channel, server_name=message.channel.guild.name, page_num=page_num+1,
                                             page_count=len(pages)), colour=Colour(0xbffdd), description=pages[page_num])
    await message.edit(embed=embed)
    await Selfroles.update_reactions(message, pages[page_num], len(pages) > 1)
    bot.loop.create_task(bot.redis_pool.expire(f"self_role:{message.channel.guild.id}", int(kwargs.get("duration", 60 * 60 * 24 * 7))))
    return kwargs
Example #3
0
async def on_ready():
    if not bot.STARTUP_COMPLETE:
        await Util.readyBot(bot)
        Emoji.on_ready(bot)
        Utils.on_ready(bot)
        Translator.on_ready(bot)
        bot.loop.create_task(
            keepDBalive())  # ping DB every hour so it doesn't run off

        #shutdown handler for clean exit on linux
        try:
            for signame in ('SIGINT', 'SIGTERM'):
                asyncio.get_event_loop().add_signal_handler(
                    getattr(signal, signame), lambda: asyncio.ensure_future(
                        Utils.cleanExit(bot, signame)))
        except Exception:
            pass  #doesn't work on windows

        bot.aiosession = aiohttp.ClientSession()
        bot.start_time = datetime.datetime.utcnow()
        GearbotLogging.info("Loading cogs...")
        for extension in extensions:
            try:
                bot.load_extension("Cogs." + extension)
            except Exception as e:
                GearbotLogging.exception(
                    f"Failed to load extention {extension}", e)
        GearbotLogging.info("Cogs loaded")

        if Configuration.getMasterConfigVar("CROWDIN_KEY") is not None:
            bot.loop.create_task(translation_task())

        bot.STARTUP_COMPLETE = True
    await bot.change_presence(
        activity=discord.Activity(type=3, name='the gears turn'))
Example #4
0
    async def remind_me(self, ctx, duration: Duration, *,
                        reminder: ReminderText):
        """remind_me_help"""
        if duration.unit is None:
            parts = reminder.split(" ")
            duration.unit = parts[0]
            reminder = " ".join(parts[1:])
        duration_seconds = duration.to_seconds(ctx)
        if duration_seconds <= 0:
            await MessageUtils.send_to(ctx, "NO", "reminder_time_travel")
            return
        if ctx.guild is not None:
            message = f'{Emoji.get_chat_emoji("QUESTION")} {Translator.translate("remind_question", ctx)}'
            one = Emoji.get_emoji("1")
            two = Emoji.get_emoji("2")
            no = Emoji.get_emoji("NO")
            embed = Embed(description=f"""
{Emoji.get_chat_emoji("1")} {Translator.translate("remind_option_here", ctx)}
{Emoji.get_chat_emoji("2")} {Translator.translate("remind_option_dm", ctx)}
{Emoji.get_chat_emoji("NO")} {Translator.translate("remind_option_cancel", ctx)}
""")
            m = await ctx.send(message, embed=embed)
            for e in [one, two, no]:
                await m.add_reaction(e)

            try:
                reaction, user = await ctx.bot.wait_for(
                    'reaction_add',
                    timeout=30,
                    check=lambda reaction, user: user == ctx.message.author and
                    reaction.emoji in [one, two, no])
            except asyncio.TimeoutError:
                await MessageUtils.send_to(ctx,
                                           "NO",
                                           "confirmation_timeout",
                                           timeout=30)
                return
            else:
                if reaction.emoji == no:
                    await MessageUtils.send_to(ctx, "NO", "command_canceled")
                    return
                else:
                    dm = reaction.emoji == two
            finally:
                await m.delete()

        else:
            dm = True
        Reminder.create(user_id=ctx.author.id,
                        channel_id=ctx.channel.id,
                        dm=dm,
                        to_remind=await Utils.clean(reminder, markdown=False),
                        time=time.time() + duration_seconds,
                        status=ReminderStatus.Pending)
        mode = "dm" if dm else "here"
        await MessageUtils.send_to(ctx,
                                   "YES",
                                   f"reminder_confirmation_{mode}",
                                   duration=duration.length,
                                   duration_identifier=duration.unit)
Example #5
0
async def update_reactions(message, page, has_multiple):
    left = Emoji.get_emoji("LEFT")
    if has_multiple and not any(left == r.emoji and r.me
                                for r in message.reactions):
        await message.add_reaction(left)
    # add numbered reactions
    needed = int(len(page.splitlines()) / 2)
    added = False
    try:
        for i in range(10):
            reaction = Emoji.get_emoji(str(i + 1))
            if i < needed:
                added = True
                await message.add_reaction(reaction)
            elif any(reaction == r.emoji and r.me for r in message.reactions):
                await message.remove_reaction(reaction,
                                              message.channel.guild.me)

        right = Emoji.get_emoji("RIGHT")
        has_right = any(right == r.emoji and r.me for r in message.reactions)
        if added and has_right:
            await message.remove_reaction(right, message.channel.guild.me)
            has_right = False
        if not has_right and has_multiple:
            await message.add_reaction(right)

        has_left = any(left == r.emoji and r.me for r in message.reactions)
        if has_left and has_multiple:
            await message.remove_reaction(left, message.channel.guild.me)
    except Forbidden:
        pass  # we lost access
Example #6
0
async def create_new(type, ctx, **kwargs):
    text, embed, has_pages, emoji = await page_handlers[type]["init"](ctx,
                                                                      **kwargs)
    message: discord.Message = await ctx.channel.send(text, embed=embed)
    if has_pages or len(emoji) > 0:
        data = {
            "type": type,
            "page": 0,
            "trigger": ctx.message.id,
            "sender": ctx.author.id
        }
        for k, v in kwargs.items():
            data[k] = v
        known_messages[str(message.id)] = data
        try:
            if has_pages: await message.add_reaction(Emoji.get_emoji('LEFT'))
            for e in emoji:
                await message.add_reaction(e)
            if has_pages: await message.add_reaction(Emoji.get_emoji('RIGHT'))
        except discord.Forbidden:
            await ctx.send(
                f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('paginator_missing_perms', ctx, prev=Emoji.get_chat_emoji('LEFT'), next=Emoji.get_chat_emoji('RIGHT'))} {Emoji.get_chat_emoji('WARNING')}"
            )

    if len(known_messages.keys()) > 500:
        del known_messages[list(known_messages.keys())[0]]

    save_to_disc()
Example #7
0
async def initialize(bot):
    #lock event handling while we get ready
    bot.locked = True
    try:
        #database
        GearbotLogging.info("Connecting to the database.")
        DatabaseConnector.init()
        bot.database_connection = DatabaseConnector.connection
        GearbotLogging.info("Database connection established.")

        GearbotLogging.initialize_pump(bot)
        Emoji.initialize(bot)
        Pages.initialize(bot)
        Utils.initialize(bot)
        Translator.initialize(bot)
        InfractionUtils.initialize(bot)
        bot.data = {
            "forced_exits": set(),
            "unbans": set(),
            "message_deletes": set()
        }
        await GearbotLogging.initialize(
            bot, Configuration.get_master_var("BOT_LOG_CHANNEL"))

        if bot.redis_pool is None or not hasattr(
                bot, 'redis_raid_pool') or bot.redis_raid_pool is None:
            try:
                bot.redis_pool = await aioredis.create_redis_pool(
                    (Configuration.get_master_var('REDIS_HOST', "localhost"),
                     Configuration.get_master_var('REDIS_PORT', 6379)),
                    encoding="utf-8",
                    db=0)
                bot.redis_raid_pool = await aioredis.create_redis_pool(
                    (Configuration.get_master_var('REDIS_HOST', "localhost"),
                     Configuration.get_master_var('REDIS_PORT', 6379)),
                    encoding="utf-8",
                    db=1)
            except OSError:
                GearbotLogging.error(
                    "==============Failed to connect to redis==============")
                await GearbotLogging.bot_log(
                    f"{Emoji.get_chat_emoji('NO')} Failed to connect to redis, caching and anti-raid connections unavailable"
                )
            else:
                GearbotLogging.info("Redis connection established")
                await GearbotLogging.bot_log(
                    f"{Emoji.get_chat_emoji('YES')} Redis connection established, caching and anti-raid connections established"
                )

        if bot.aiosession is None:
            bot.aiosession = aiohttp.ClientSession()
        bot.being_cleaned.clear()
        await Configuration.initialize(bot)
    except Exception as ex:
        #make sure we always unlock, even when something went wrong!
        bot.locked = False
        raise ex
    bot.locked = False
Example #8
0
async def initialize(bot, startup=False):
    #lock event handling while we get ready
    bot.locked = True
    try:
        #database
        GearbotLogging.info("Connecting to the database.")
        DatabaseConnector.init()
        bot.database_connection = DatabaseConnector.connection
        GearbotLogging.info("Database connection established.")

        Emoji.initialize(bot)
        Utils.initialize(bot)
        InfractionUtils.initialize(bot)
        bot.data = {
            "forced_exits": set(),
            "unbans": set(),
            "message_deletes": set(),
            "nickname_changes": set()
        }
        await GearbotLogging.initialize(bot, Configuration.get_master_var("BOT_LOG_CHANNEL"))
        if startup:
            c = await Utils.get_commit()
            bot.version = c
            GearbotLogging.info(f"GearBot spinning up version {c}")
            await GearbotLogging.bot_log(f"{Emoji.get_chat_emoji('ALTER')} GearBot spinning up version {c}")

        if bot.redis_pool is None:
            try:
                socket = Configuration.get_master_var("REDIS_SOCKET", "")
                if socket == "":
                    bot.redis_pool = await aioredis.create_redis_pool((Configuration.get_master_var('REDIS_HOST', "localhost"), Configuration.get_master_var('REDIS_PORT', 6379)), encoding="utf-8", db=0)
                else:
                    bot.redis_pool = await aioredis.create_redis_pool(socket, encoding="utf-8", db=0)
            except OSError:
                GearbotLogging.error("==============Failed to connect to redis==============")
                await GearbotLogging.bot_log(f"{Emoji.get_chat_emoji('NO')} Failed to connect to redis, caching unavailable")
            else:
                GearbotLogging.info("Redis connection established")
                await GearbotLogging.bot_log(f"{Emoji.get_chat_emoji('YES')} Redis connection established, let's go full speed!")

        if bot.aiosession is None:
            bot.aiosession = aiohttp.ClientSession()

        await Translator.initialize(bot)
        bot.being_cleaned.clear()
        await Configuration.initialize(bot)
        DashConfig.initialize(bot)
    except Exception as ex:
        #make sure we always unlock, even when something went wrong!
        bot.locked = False
        raise ex
    bot.locked = False
Example #9
0
async def create_new(bot, type, ctx, **kwargs):
    text, embed, has_pages = await page_handlers[type]["init"](ctx, **kwargs)
    message: discord.Message = await ctx.channel.send(text, embed=embed)
    if has_pages:
        await ReactionManager.register(bot, message.id, message.channel.id, "paged", subtype=type, duration=60 * 60 * 24, **kwargs)
        try:
            if has_pages: await message.add_reaction(Emoji.get_emoji('LEFT'))
            if has_pages: await message.add_reaction(Emoji.get_emoji('RIGHT'))
        except discord.Forbidden:
            await MessageUtils.send_to(ctx, 'WARNING', 'paginator_missing_perms', prev=Emoji.get_chat_emoji('LEFT'),
                                       next=Emoji.get_chat_emoji('RIGHT'))
        except discord.NotFound:
            await MessageUtils.send_to(ctx, 'WARNING', 'fix_censor')
Example #10
0
async def inf_update(message, query, fields, amount, page_num):
    if str(query).isnumeric():
        query = int(query)
    guild_id = message.channel.guild.id
    old = message.content
    key = get_key(guild_id, query, fields, amount)
    # do we have pages?
    count = await bot.redis_pool.llen(key)
    if count == 0:
        count = await fetch_infraction_pages(guild_id, query, amount, fields,
                                             page_num)
        if page_num >= count:
            page_num = 0
        elif page_num < 0:
            page_num = count - 1
        page = (await bot.wait_for(
            "page_assembled",
            check=lambda l: l["key"] == key and l["page_num"] == page_num)
                )["page"]
    else:
        if page_num >= count:
            page_num = 0
        elif page_num < 0:
            page_num = count - 1
        page = await bot.redis_pool.lindex(key, page_num)
    name = await Utils.username(query) if isinstance(
        query, int) else await Utils.clean(bot.get_guild(guild_id).name)
    new = f"{Emoji.get_chat_emoji('SEARCH')} {Translator.translate('inf_search_header', message.channel.guild.id, name=name, page_num=page_num + 1, pages=count)}\n{page}"
    if old != new:
        try:
            await message.edit(content=new)
            if count > 1:
                left = Emoji.get_emoji('LEFT')
                if not any(left == r.emoji and r.me
                           for r in message.reactions):
                    await message.add_reaction(Emoji.get_emoji('LEFT'))
                    await message.add_reaction(Emoji.get_emoji('RIGHT'))
        except NotFound:
            pass

    parts = {
        "page_num": page_num,
        "cache_key": key,
    }
    if len(fields) != 0:
        parts["fields"] = "-".join(fields)
    if query is not None:
        parts["query"] = query
    if amount != 100:
        parts["amount"] = 100
    return parts
Example #11
0
async def inf_search(bot, message, user_id, reaction, **kwargs):
    user = await Utils.get_member(bot, message.channel.guild, user_id)
    left = Emoji.get_chat_emoji('LEFT')
    right = Emoji.get_chat_emoji('RIGHT')
    refresh = Emoji.get_chat_emoji('REFRESH')
    r2 = "🔁"
    if str(reaction) not in [left, right, refresh, r2]:
        return kwargs
    page_num = int(kwargs.get("page_num", 0))
    if str(reaction) == left:
        page_num -= 1
    elif str(reaction) == right:
        page_num += 1
    if user is not None:
        bot.loop.create_task(remove_reaction(message, reaction, user))
Example #12
0
async def on_ready(bot):
    if not bot.STARTUP_COMPLETE:
        GearbotLogging.initialize_pump(bot)
        await GearbotLogging.onReady(
            bot, Configuration.get_master_var("BOT_LOG_CHANNEL"))
        info = await bot.application_info()
        await GearbotLogging.bot_log(message="Spinning up the gears!")
        await Util.readyBot(bot)
        Emoji.on_ready(bot)
        Utils.on_ready(bot)
        Translator.on_ready(bot)
        bot.loop.create_task(
            keepDBalive(bot))  # ping DB every hour so it doesn't run off

        #shutdown handler for clean exit on linux
        try:
            for signame in ('SIGINT', 'SIGTERM'):
                asyncio.get_event_loop().add_signal_handler(
                    getattr(signal, signame), lambda: asyncio.ensure_future(
                        Utils.cleanExit(bot, signame)))
        except Exception:
            pass  #doesn't work on windows

        bot.aiosession = aiohttp.ClientSession()
        bot.start_time = datetime.datetime.utcnow()
        GearbotLogging.info("Loading cogs...")
        for extension in Configuration.get_master_var("COGS"):
            try:
                bot.load_extension("Cogs." + extension)
            except Exception as e:
                GearbotLogging.exception(
                    f"Failed to load extention {extension}", e)
        GearbotLogging.info("Cogs loaded")

        if Configuration.get_master_var("CROWDIN_KEY") is not None:
            bot.loop.create_task(translation_task(bot))

        await DocUtils.update_docs(bot)

        bot.STARTUP_COMPLETE = True
        await GearbotLogging.bot_log(
            message=f"All gears turning at full speed, {info.name} ready to go!"
        )
        await bot.change_presence(
            activity=discord.Activity(type=3, name='the gears turn'))
    else:
        await bot.change_presence(
            activity=discord.Activity(type=3, name='the gears turn'))
Example #13
0
async def confirm(ctx: commands.Context,
                  text,
                  timeout=30,
                  on_yes=None,
                  on_no=None,
                  delete=True,
                  confirm_cancel=True):
    yes = str(Emoji.get_emoji("YES"))
    no = str(Emoji.get_emoji("NO"))
    message: discord.Message = await ctx.send(text)
    await message.add_reaction(yes)
    await message.add_reaction(no)

    def check(reaction: discord.RawReactionActionEvent):
        return reaction.user_id == ctx.message.author.id and str(
            reaction.emoji) in (yes, no) and reaction.message_id == message.id

    try:
        reaction = await ctx.bot.wait_for('raw_reaction_add',
                                          timeout=timeout,
                                          check=check)
    except asyncio.TimeoutError:
        try:
            await message.delete()
        except NotFound:
            pass  # someone deleted it
        await MessageUtils.send_to(ctx,
                                   "NO",
                                   "confirmation_timeout",
                                   timeout=30)
        return
    if str(reaction.emoji) == yes and on_yes is not None:
        if delete:
            try:
                await message.delete()
            except (discord.Forbidden, discord.NotFound):
                pass
        await on_yes()
    elif str(reaction.emoji) == no:
        if delete:
            try:
                await message.delete()
            except (discord.Forbidden, discord.NotFound):
                pass
        if on_no is not None:
            await on_no()
        elif confirm_cancel:
            await MessageUtils.send_to(ctx, "NO", "command_canceled")
Example #14
0
async def on_command_error(bot, ctx: commands.Context, error):
    if isinstance(error, NotCachedException):
        if bot.loading_task is not None:
            if bot.initial_fill_complete:
                await ctx.send(
                    f"{Emoji.get_chat_emoji('CLOCK')} Due to a earlier connection failure the cached data for this guild is no longer up to date and is being rebuild. Please try again in a few minutes."
                )
            else:
                await ctx.send(
                    f"{Emoji.get_chat_emoji('CLOCK')} GearBot is in the process of starting up and has not received the member info for this guild. Please try again in a few minutes."
                )
        else:
            await ctx.send(
                f"{Emoji.get_chat_emoji('CLOCK')} GearBot only just joined this guild and is still receiving the initial member info for this guild, please try again in a few seconds"
            )
    if isinstance(error, commands.BotMissingPermissions):
        GearbotLogging.error(
            f"Encountered a permission error while executing {ctx.command}: {error}"
        )
        await ctx.send(error)
    elif isinstance(error, commands.CheckFailure):
        if ctx.command.qualified_name is not "latest" and ctx.guild is not None and Configuration.get_var(
                ctx.guild.id, "GENERAL", "PERM_DENIED_MESSAGE"):
            await MessageUtils.send_to(ctx, 'LOCK', 'permission_denied')
    elif isinstance(error, commands.CommandOnCooldown):
        await ctx.send(error)
    elif isinstance(error, commands.MissingRequiredArgument):
        param = list(ctx.command.params.values())[min(
            len(ctx.args) + len(ctx.kwargs), len(ctx.command.params))]
        bot.help_command.context = ctx
        await ctx.send(
            f"{Emoji.get_chat_emoji('NO')} {Translator.translate('missing_arg', ctx, arg=param._name, error=Utils.replace_lookalikes(str(error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}"
        )
    elif isinstance(error, PostParseError):
        bot.help_command.context = ctx
        await ctx.send(
            f"{Emoji.get_chat_emoji('NO')} {Translator.translate('bad_argument', ctx, type=error.type, error=Utils.replace_lookalikes(str(error.error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}"
        )
    elif isinstance(error, commands.BadArgument):
        param = list(ctx.command.params.values())[min(
            len(ctx.args) + len(ctx.kwargs), len(ctx.command.params))]
        bot.help_command.context = ctx
        await ctx.send(
            f"{Emoji.get_chat_emoji('NO')} {Translator.translate('bad_argument', ctx, type=param._name, error=Utils.replace_lookalikes(str(error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}"
        )
    elif isinstance(error, commands.CommandNotFound):
        return

    else:
        await handle_exception(
            "Command execution failed",
            bot,
            error.original if hasattr(error, "original") else error,
            ctx=ctx)
        # notify caller
        e = Emoji.get_chat_emoji('BUG')
        if ctx.channel.permissions_for(ctx.me).send_messages:
            await ctx.send(
                f"{e} Something went wrong while executing that command. If this keeps happening please report it on support server (DM me ``!about`` or check the website for an invite) {e}"
            )
Example #15
0
    def __init__(self, filters, pages, guild_id, userid, current_page=0):
        super().__init__(timeout=None)
        self.id = ""
        if pages > 0:
            start = f"einf_search:{userid}:{current_page}"

            self.add_item(
                Button(label=Translator.translate('first_page', guild_id),
                       custom_id=f'{start}:first_page',
                       disabled=current_page == 0,
                       style=ButtonStyle.blurple))
            self.add_item(
                Button(label=Translator.translate('prev_page', guild_id),
                       custom_id=f'{start}:prev_page',
                       disabled=current_page == 0,
                       style=ButtonStyle.blurple))
            self.add_item(
                Button(emoji=Emoji.get_emoji('AE'),
                       style=ButtonStyle.grey,
                       custom_id=f'{start}:blank',
                       label=None))
            self.add_item(
                Button(label=Translator.translate('next_page', guild_id),
                       custom_id=f'{start}:next_page',
                       disabled=current_page >= pages - 1,
                       style=ButtonStyle.blurple))
            self.add_item(
                Button(label=Translator.translate('last_page', guild_id),
                       custom_id=f'{start}:last_page',
                       disabled=current_page >= pages - 1,
                       style=ButtonStyle.blurple))
        self.stop()
Example #16
0
async def inf_search(bot, message, user_id, reaction, **kwargs):
    user = message.channel.guild.get_member(user_id)
    left = Emoji.get_chat_emoji('LEFT')
    right = Emoji.get_chat_emoji('RIGHT')
    refresh = Emoji.get_chat_emoji('REFRESH')
    r2 = "🔁"
    if str(reaction) not in [left, right, refresh, r2]:
        return kwargs
    page_num = int(kwargs.get("page_num", 0))
    if str(reaction) == left:
        page_num -= 1
    elif str(reaction) == right:
        page_num += 1
    if user is not None:
        bot.loop.create_task(remove_reaction(message, reaction, user))
    return await InfractionUtils.inf_update(message, kwargs.get("query", None), kwargs.get("fields", "").split("-"), kwargs.get("amount", 100), page_num)
Example #17
0
async def on_ready(bot):
    if not bot.STARTUP_COMPLETE:
        await initialize(bot, True)
        #shutdown handler for clean exit on linux
        try:
            for signame in ('SIGINT', 'SIGTERM'):
                asyncio.get_event_loop().add_signal_handler(getattr(signal, signame),
                                        lambda: asyncio.ensure_future(Utils.cleanExit(bot, signame)))
        except Exception:
            pass #doesn't work on windows

        bot.start_time = datetime.utcnow()
        GearbotLogging.info("Loading cogs...")
        for extension in Configuration.get_master_var("COGS"):
            try:
                bot.load_extension("Cogs." + extension)
            except Exception as e:
                await handle_exception(f"Failed to load cog {extension}", bot, e)
        GearbotLogging.info("Cogs loaded")

        to_unload = Configuration.get_master_var("DISABLED_COMMANDS", [])
        for c in to_unload:
            bot.remove_command(c)

        bot.STARTUP_COMPLETE = True
        info = await bot.application_info()
        bot.loop.create_task(keepDBalive(bot))  # ping DB every hour so it doesn't run off
        gears = [Emoji.get_chat_emoji(e) for e in ["WOOD", "STONE", "IRON", "GOLD", "DIAMOND"]]
        a = " ".join(gears)
        b = " ".join(reversed(gears))
        await GearbotLogging.bot_log(message=f"{a} All gears turning at full speed, {info.name} ready to go! {b}")
        await bot.change_presence(activity=Activity(type=3, name='the gears turn'))
    else:
        await bot.change_presence(activity=Activity(type=3, name='the gears turn'))
Example #18
0
async def on_command_error(bot, ctx: commands.Context, error):
    if isinstance(error, commands.BotMissingPermissions):
        GearbotLogging.error(f"Encountered a permission error while executing {ctx.command}: {error}")
        await ctx.send(error)
    elif isinstance(error, commands.CheckFailure):
        if ctx.command.qualified_name is not "latest" and ctx.guild is not None and Configuration.get_var(ctx.guild.id, "GENERAL", "PERM_DENIED_MESSAGE"):
            await MessageUtils.send_to(ctx, 'LOCK', 'permission_denied')
    elif isinstance(error, commands.CommandOnCooldown):
        await ctx.send(error)
    elif isinstance(error, commands.MissingRequiredArgument):
        param = list(ctx.command.params.values())[min(len(ctx.args) + len(ctx.kwargs), len(ctx.command.params))]
        bot.help_command.context = ctx
        await ctx.send(
            f"{Emoji.get_chat_emoji('NO')} {Translator.translate('missing_arg', ctx, arg=param._name, error=Utils.replace_lookalikes(str(error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}")
    elif isinstance(error, PostParseError):
        bot.help_command.context = ctx
        await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('bad_argument', ctx, type=error.type, error=Utils.replace_lookalikes(str(error.error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}")
    elif isinstance(error, commands.BadArgument):
        param = list(ctx.command.params.values())[min(len(ctx.args) + len(ctx.kwargs), len(ctx.command.params))]
        bot.help_command.context = ctx
        await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('bad_argument', ctx, type=param._name, error=Utils.replace_lookalikes(str(error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}")
    elif isinstance(error, commands.CommandNotFound):
        return
    elif isinstance(error, PeeweeException):
        await handle_database_error(bot)

    else:
        await handle_exception("Command execution failed", bot, error.original if hasattr(error, "original") else error, ctx=ctx)
        # notify caller
        e = Emoji.get_chat_emoji('BUG')
        if ctx.channel.permissions_for(ctx.me).send_messages:
            await ctx.send(f"{e} Something went wrong while executing that command {e}")
Example #19
0
 async def init_help(self, ctx, query=None, **kwargs):
     pages = await self.get_help_pages(ctx, query)
     if pages is None:
         query_clean = await clean_content().convert(ctx, query)
         return await clean_content().convert(ctx, Translator.translate(
             "help_not_found" if len(query) < 1500 else "help_no_wall_allowed", ctx,
             query=query_clean)), None, False
     eyes = Emoji.get_chat_emoji('EYES')
     return f"{eyes} **{Translator.translate('help_title', ctx, page_num=1, pages=len(pages))}** {eyes}```diff\n{pages[0]}```", None, len(pages) > 1
Example #20
0
async def paged(bot, message, user_id, reaction, **kwargs):
    user = await Utils.get_member(bot, message.channel.guild, user_id)
    if user is None:
        await remove_reaction(message, reaction, await bot.fetch_user(user_id))
        return
    left = Emoji.get_chat_emoji('LEFT')
    right = Emoji.get_chat_emoji('RIGHT')
    refresh = Emoji.get_chat_emoji('REFRESH')
    r2 = "🔁"
    if str(reaction) not in [left, right, refresh, r2]:
        return kwargs
    action = "REFRESH"
    if str(reaction) == left:
        action = "PREV"
    elif str(reaction) == right:
        action = "NEXT"
    bot.loop.create_task(remove_reaction(message, reaction, user))
    return await Pages.update(bot, message, action, user_id, **kwargs)
Example #21
0
 def __init__(self, filters, pages, guild_id, current_page=0, ephemeral=False, userid=""):
     super().__init__(timeout=None)
     self.id=""
     if pages > 0:
         self.add_item(CallbackButton(Translator.translate('first_page', guild_id), self.on_first_page, 'inf_search:first_page', disabled=current_page == 0))
         self.add_item(CallbackButton(Translator.translate('prev_page', guild_id), self.on_prev_page, 'inf_search:prev_page', disabled=current_page == 0))
         self.add_item(CallbackButton(emoji=Emoji.get_emoji('AE'), style=ButtonStyle.grey, cid='inf_search:blank', callback=self.hi, label=None))
         self.add_item(CallbackButton(Translator.translate('next_page', guild_id), self.on_next_page, 'inf_search:next_page', disabled=current_page >= pages-1))
         self.add_item(CallbackButton(Translator.translate('last_page', guild_id), self.on_last_page, 'inf_search:last_page', disabled=current_page >= pages-1))
Example #22
0
async def confirm(ctx: commands.Context,
                  text,
                  timeout=30,
                  on_yes=None,
                  on_no=None,
                  delete=True):
    yes = Emoji.get_emoji("YES")
    no = Emoji.get_emoji("NO")
    message: discord.Message = await ctx.send(text)
    await message.add_reaction(yes)
    await message.add_reaction(no)

    def check(reaction: discord.Reaction, user):
        return user == ctx.message.author and reaction.emoji in (
            yes, no) and reaction.message.id == message.id

    try:
        reaction, user = await ctx.bot.wait_for('reaction_add',
                                                timeout=timeout,
                                                check=check)
    except asyncio.TimeoutError:
        await message.delete()
        await MessageUtils.send_to(ctx,
                                   "NO",
                                   "confirmation_timeout",
                                   timeout=30)
        return
    if reaction.emoji == yes and on_yes is not None:
        if delete:
            try:
                await message.delete()
            except (discord.Forbidden, discord.NotFound):
                pass
        await on_yes()
    elif reaction.emoji == no:
        if delete:
            try:
                await message.delete()
            except (discord.Forbidden, discord.NotFound):
                pass
        if on_no is not None:
            await on_no()
        else:
            await MessageUtils.send_to(ctx, "NO", "command_canceled")
Example #23
0
async def confirm(ctx: commands.Context,
                  text,
                  timeout=30,
                  on_yes=None,
                  on_no=None,
                  delete=True):
    yes = Emoji.get_emoji("YES")
    no = Emoji.get_emoji("NO")
    message: discord.Message = await ctx.send(text)
    await message.add_reaction(yes)
    await message.add_reaction(no)

    def check(reaction: discord.Reaction, user):
        return user == ctx.message.author and reaction.emoji in (
            yes, no) and reaction.message.id == message.id

    try:
        reaction, user = await ctx.bot.wait_for('reaction_add',
                                                timeout=timeout,
                                                check=check)
    except asyncio.TimeoutError:
        await message.delete()
        await ctx.send(f"I got no answer within {timeout} seconds.. Aborting.")
        return
    GearbotLogging.info(
        f"CONFIRMATOR RESPONCE RECEIVED:\nreaction: {reaction}\nemoji: {reaction.emoji}\non_yes: {on_yes}\non_no: {on_no}"
    )
    if reaction.emoji == yes and on_yes is not None:
        if delete:
            try:
                await message.delete()
            except discord.Forbidden:
                pass
        await on_yes()
    elif reaction.emoji == no:
        if delete:
            try:
                await message.delete()
            except discord.Forbidden:
                pass
        if on_no is not None:
            await on_no()
        else:
            await GearbotLogging.send_to(ctx, "NO", "command_canceled")
Example #24
0
    async def eval(self, ctx:commands.Context, *, code: str):
        output = None
        env = {
            'bot': self.bot,
            'ctx': ctx,
            'channel': ctx.channel,
            'author': ctx.author,
            'guild': ctx.guild,
            'message': ctx.message
        }

        env.update(globals())

        if code.startswith('```'):
            code = "\n".join(code.split("\n")[1:-1])

        out = io.StringIO()

        to_compile = f'async def func():\n{textwrap.indent(code, "  ")}'

        try:
            exec(to_compile, env)
        except Exception as e:
            output = f'{e.__class__.__name__}: {e}'
        else:
            func = env['func']
            try:
                with contextlib.redirect_stdout(out):
                    ret = await func()
            except Exception as e:
                value = out.getvalue()
                output = f'{value}{traceback.format_exc()}'
            else:
                value = out.getvalue()
                if ret is None:
                    if value:
                        output = value
                else:
                    output = f'{value}{ret}'
        if output is not None:
            pipe = self.bot.redis_pool.pipeline()
            k = f'eval:{ctx.message.id}'
            pipe.set(k, output)
            pipe.expire(k, 7*24*60*60)
            await pipe.execute()
            pages = Pages.paginate(output, prefix='```py\n', suffix='```')
            content, view, _ = SimplePager.get_parts(pages, 0, ctx.guild.id if ctx.guild is not None else 0, f'eval:{ctx.message.id}')
            await ctx.send(f'Eval output 1/{len(pages)}{content}', view=view)
        else:
            await ctx.message.add_reaction(Emoji.get_emoji("YES"))
Example #25
0
    async def eval(self, ctx: commands.Context, *, code: str):
        output = None
        env = {
            'bot': self.bot,
            'ctx': ctx,
            'channel': ctx.channel,
            'author': ctx.author,
            'guild': ctx.guild,
            'message': ctx.message
        }

        env.update(globals())

        if code.startswith('```'):
            code = "\n".join(code.split("\n")[1:-1])

        out = io.StringIO()

        to_compile = f'async def func():\n{textwrap.indent(code, "  ")}'

        try:
            exec(to_compile, env)
        except Exception as e:
            output = f'{e.__class__.__name__}: {e}'
        else:
            func = env['func']
            try:
                with contextlib.redirect_stdout(out):
                    ret = await func()
            except Exception as e:
                value = out.getvalue()
                output = f'{value}{traceback.format_exc()}'
            else:
                value = out.getvalue()
                if ret is None:
                    if value:
                        output = value
                else:
                    output = f'{value}{ret}'
        if output is not None:
            await Pages.create_new(self.bot,
                                   "eval",
                                   ctx,
                                   pages="----NEW PAGE----".join(
                                       Pages.paginate(output)),
                                   code=code,
                                   trigger=ctx.message.id,
                                   sender=ctx.author.id)
        else:
            await ctx.message.add_reaction(Emoji.get_emoji("YES"))
Example #26
0
 async def init_role(self, ctx):
     pages = self.gen_role_pages(ctx.guild)
     page = pages[0]
     emoji = []
     for i in range(
             10 if len(pages) > 1 else round(len(page.splitlines()) / 2)):
         emoji.append(Emoji.get_emoji(str(i + 1)))
     embed = discord.Embed(title=Translator.translate(
         "assignable_roles",
         ctx,
         server_name=ctx.guild.name,
         page_num=1,
         page_count=len(pages)),
                           colour=discord.Colour(0xbffdd),
                           description=page)
     return None, embed, len(pages) > 1, emoji
Example #27
0
async def message_parts(bot, query, guild, member, page_num):
    view = None
    raw_pages = await get_help_pages(query, guild, member, bot)
    if raw_pages is None:
        if query in [cog.lower() for cog in bot.cogs]:
            raw_pages = [Translator.translate('no_runnable_commands', guild)]
        else:
            return Translator.translate("help_not_found" if len(query) < 1500 else "help_no_wall_allowed", guild,
                                    query=await Utils.clean(query, emoji=False)), None
    if page_num >= len(raw_pages):
        page_num = 0
    eyes = Emoji.get_chat_emoji('EYES')
    content = f"{eyes} **{Translator.translate('help_title', guild, page_num=page_num + 1, pages=len(raw_pages))}** {eyes}```diff\n{raw_pages[page_num]}```"
    cog_names = [cog.lower() for cog in bot.cogs]
    if query is None or query.lower() in cog_names or len(raw_pages) > 1:
        view = HelpView(bot, guild, query, page_num, len(raw_pages), True)
    return content, view
Example #28
0
 async def update_help(self, ctx, message, page_num, action, data):
     pages = await self.get_help_pages(ctx, data.get("query", None))
     page, page_num = Pages.basic_pages(pages, page_num, action)
     eyes = Emoji.get_chat_emoji('EYES')
     data["page"] = page_num
     return f"{eyes} **{Translator.translate('help_title', ctx, page_num=page_num + 1, pages=len(pages))}**{eyes}```diff\n{page}```", None, data
Example #29
0
    async def on_raw_reaction_add(self,
                                  payload: discord.RawReactionActionEvent):
        guild = self.bot.get_guild(payload.guild_id)
        if guild is None:
            return
        if guild.me.id == payload.user_id:
            return
        try:
            message = await self.bot.get_channel(
                payload.channel_id).get_message(payload.message_id)
        except discord.NotFound:
            pass
        else:
            if str(payload.message_id) in Pages.known_messages:
                info = Pages.known_messages[str(payload.message_id)]
                if info["type"] == "role":
                    for i in range(10):
                        e = Emoji.get_emoji(str(i + 1))
                        if payload.emoji.name == e:
                            roles = Configuration.get_var(
                                guild.id, "SELF_ROLES")
                            channel = self.bot.get_channel(payload.channel_id)
                            number = info['page'] * 10 + i
                            if number >= len(roles):
                                await GearbotLogging.send_to(
                                    channel,
                                    "NO",
                                    "role_not_on_page",
                                    requested=number + 1,
                                    max=len(roles) % 10,
                                    delete_after=10)
                                return
                            role = guild.get_role(roles[number])
                            if role is None:
                                return
                            member = guild.get_member(payload.user_id)
                            try:
                                if role in member.roles:
                                    await member.remove_roles(role)
                                    added = False
                                else:
                                    await member.add_roles(role)
                                    added = True
                            except discord.Forbidden:
                                emessage = f"{Emoji.get_chat_emoji('NO')} {Translator.translate('mute_role_to_high', payload.guild_id, role=role.name)}"
                                try:
                                    await channel.send(emessage)
                                except discord.Forbidden:
                                    try:
                                        member.send(emessage)
                                    except discord.Forbidden:
                                        pass
                            else:
                                try:
                                    action_type = 'role_joined' if added else 'role_left'
                                    await channel.send(
                                        f"{member.mention} {Translator.translate(action_type, payload.guild_id, role_name=role.name)}",
                                        delete_after=10)
                                except discord.Forbidden:
                                    pass

                            if channel.permissions_for(
                                    guild.me).manage_messages:
                                await message.remove_reaction(e, member)
                            break
Example #30
0
    async def on_interaction(self, interaction):
        guild = self.bot.get_guild(interaction.guild_id)
        if interaction.type == InteractionType.component:
            cid = interaction.data.custom_id
            if cid.startswith('self_role'):
                parts = cid.split(':')
                if parts[1] == 'role':
                    rid = parts[2]
                    if rid.isnumeric():
                        rid = int(rid)
                        roles = Configuration.get_var(interaction.guild_id,
                                                      "ROLES", "SELF_ROLES")
                        if rid in roles:
                            role = guild.get_role(rid)
                            if role is None:
                                roles.remove(rid)
                                Configuration.set_var(interaction.guild_id,
                                                      "ROLES", "SELF_ROLES",
                                                      roles)
                                v = SelfRoleView(guild=guild, page=0)
                                interaction.response.edit_message(
                                    content=Translator.translate(
                                        "assignable_roles",
                                        interaction.guild_id,
                                        server_name=guild.name,
                                        page_num=1,
                                        page_count=v.pages),
                                    view=v)
                                interaction.followup.send_message(
                                    MessageUtils.assemble(
                                        interaction.guild_id, 'WARNING',
                                        'self_role_missing'),
                                    ephemeral=True)
                            else:
                                try:
                                    if role in interaction.user.roles:
                                        await interaction.user.remove_roles(
                                            role)
                                        await interaction.response.send_message(
                                            Translator.translate(
                                                "role_left",
                                                interaction.guild_id,
                                                role_name=role.name,
                                                user=interaction.user),
                                            ephemeral=True)
                                    else:
                                        await interaction.user.add_roles(role)
                                        await interaction.response.send_message(
                                            Translator.translate(
                                                "role_joined",
                                                interaction.guild_id,
                                                role_name=role.name,
                                                user=interaction.user),
                                            ephemeral=True)
                                except disnake.Forbidden:
                                    await interaction.response.send_message(
                                        f"{Emoji.get_chat_emoji('NO')} {Translator.translate('role_too_high_add', interaction.guild_id, role=role.name)}",
                                        ephemeral=True)
                elif parts[1] == "page":
                    v = SelfRoleView(guild=interaction.guild,
                                     page=int(parts[2]))
                    await interaction.response.edit_message(
                        content=Translator.translate(
                            "assignable_roles",
                            interaction.guild_id,
                            server_name=interaction.guild.name,
                            page_num=int(parts[2]) + 1,
                            page_count=v.pages),
                        view=v)
            elif cid.startswith('help:'):
                parts = cid.split(':')
                if parts[1] == 'page':
                    q = parts[3] if parts[3] != 'None' else None
                    content, view = await Help.message_parts(
                        self.bot, q, guild, interaction.user, int(parts[2]))
                    await interaction.response.edit_message(content=content,
                                                            view=view)
                elif parts[1] == 'selector':
                    q = interaction.values[0]
                    q = q if q != 'None' else None
                    content, view = await Help.message_parts(
                        self.bot, q, guild, interaction.user, 0)
                    await interaction.response.edit_message(content=content,
                                                            view=view)
            elif cid.startswith('pager:'):
                parts = cid.split(':')
                t = parts[2]
                if t == 'eval':
                    if interaction.user.id not in Configuration.get_master_var(
                            'BOT_ADMINS'):
                        return
                    output = await self.bot.redis_pool.get(f'eval:{parts[3]}')
                    if output is None:
                        await interaction.response.send_message(
                            "Eval output no longer available", ephemeral=True)
                    else:
                        pages = Pages.paginate(output,
                                               prefix='```py\n',
                                               suffix='```')
                        content, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), interaction.guild_id,
                            f'eval:{parts[3]}')
                        await interaction.response.edit_message(
                            content=
                            f'Eval output {page_num + 1}/{len(pages)}{content}',
                            view=view)
                elif t == 'commands':
                    cog = self.bot.get_command("CustCommands")
                    if cog is not None:
                        pages = cog.get_command_pages(interaction.guild_id)
                        content, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), guild.id, 'commands')
                        page = cog.gen_command_page(pages, page_num,
                                                    interaction.guild)
                        await interaction.response.edit_message(embed=page,
                                                                view=view)
                elif t == 'emoji':
                    cog = self.bot.get_cog('Emoji')
                    if cog is not None:
                        amount = len(guild.emojis) + 1
                        content, view, page_num = SimplePager.get_parts(
                            range(amount), int(parts[1]), interaction.guild.id,
                            'emoji')
                        await interaction.response.edit_message(
                            embed=cog.gen_emoji_page(guild, page_num),
                            view=view)
                elif t == 'role_list':
                    cog = self.bot.get_cog('Moderation')
                    if cog is not None:
                        pages = cog.gen_roles_pages(interaction.guild,
                                                    parts[3])
                        content, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), guild.id,
                            f'role_list:{parts[3]}')
                        await interaction.response.edit_message(
                            content=
                            f"**{Translator.translate('roles', interaction.guild_id, server_name=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{pages[page_num]}```",
                            view=view)
                elif t == 'censor_list':
                    cog = self.bot.get_cog('Moderation')
                    if cog is not None:
                        censor_list = Configuration.get_var(
                            interaction.guild.id, "CENSORING",
                            "TOKEN_CENSORLIST")
                        pages = Pages.paginate("\n".join(censor_list))
                        page, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), interaction.guild.id,
                            'censor_list')
                        await interaction.response.edit_message(
                            content=
                            f"**{Translator.translate(f'censor_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```",
                            view=view)
                elif t == 'word_censor_list':
                    cog = self.bot.get_cog('Moderation')
                    if cog is not None:
                        censor_list = Configuration.get_var(
                            guild.id, "CENSORING", "WORD_CENSORLIST")
                        pages = Pages.paginate("\n".join(censor_list))
                        page, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), guild.id, 'word_censor_list')
                        await interaction.response.edit_message(
                            content=
                            f"**{Translator.translate(f'word_censor_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```",
                            view=view)
                elif t == 'full_censor_list':
                    cog = self.bot.get_cog('Moderation')
                    if cog is not None:
                        censor_list = Configuration.get_var(
                            guild.id, "CENSORING", "FULL_MESSAGE_LIST")
                        pages = Pages.paginate("\n".join(censor_list))
                        page, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), guild.id, 'full_censor_list')
                        await interaction.response.edit_message(
                            content=
                            f"**{Translator.translate(f'full_censor_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```",
                            view=view)
                elif t == 'flag_list':
                    cog = self.bot.get_cog('Moderation')
                    if cog is not None:
                        censor_list = Configuration.get_var(
                            guild.id, "FLAGGING", "TOKEN_LIST")
                        pages = Pages.paginate("\n".join(censor_list))
                        page, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), guild.id, 'flag_list')
                        await interaction.response.edit_message(
                            content=
                            f"**{Translator.translate(f'flagged_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```",
                            view=view)
                elif t == 'word_flag_list':
                    cog = self.bot.get_cog('Moderation')
                    if cog is not None:
                        censor_list = Configuration.get_var(
                            guild.id, "FLAGGING", "WORD_LIST")
                        pages = Pages.paginate("\n".join(censor_list))
                        page, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), guild.id, 'word_flag_list')
                        await interaction.response.edit_message(
                            content=
                            f"**{Translator.translate(f'flagged_word_list', guild, server=guild.name, page_num=page_num + 1, pages=len(pages))}**```\n{page}```",
                            view=view)
                elif t == 'mass_failures':
                    output = await self.bot.redis_pool.get(
                        f'mass_failures:{parts[3]}')
                    if output is None:
                        await interaction.response.send_message(
                            MessageUtils.assemble(interaction.guild_id, 'NO',
                                                  'view_expired'),
                            ephemeral=True)
                    else:
                        pages = Pages.paginate(output,
                                               prefix='```\n',
                                               suffix='```')
                        content, view, page_num = SimplePager.get_parts(
                            pages, int(parts[1]), interaction.guild_id,
                            f'mass_failures:{parts[3]}:{parts[4]}')
                        await interaction.response.edit_message(
                            content=
                            f"**{Translator.translate(f'mass_failures_{parts[4]}', interaction.guild_id, page_num=page_num+1, pages=len(pages))}**{content}",
                            view=view)
            elif cid.startswith('einf_search:'):
                parts = cid.split(':')
                uid = int(parts[1])
                old_page = int(parts[2])
                t = parts[3]

                if t == 'first_page':
                    page, current, pages, query, fields = await get_ephemeral_cached_page(
                        interaction, uid, 0)
                    await interaction.response.edit_message(
                        content=await InfractionUtils.assemble_message(
                            interaction.guild_id, page, query, current, pages),
                        view=EphemeralInfSearch(filters=fields,
                                                pages=pages,
                                                current_page=current,
                                                guild_id=interaction.guild_id,
                                                userid=uid))
                elif t == 'prev_page':
                    page, current, pages, query, fields = await get_ephemeral_cached_page(
                        interaction, uid, old_page - 1)
                    await interaction.response.edit_message(
                        content=await InfractionUtils.assemble_message(
                            interaction.guild_id, page, query, current, pages),
                        view=EphemeralInfSearch(filters=fields,
                                                pages=pages,
                                                current_page=current,
                                                guild_id=interaction.guild_id,
                                                userid=uid))
                elif t == 'blank':
                    await interaction.response.send_message(
                        Emoji.get_chat_emoji('AE'), ephemeral=True)
                elif t == 'next_page':
                    page, current, pages, query, fields = await get_ephemeral_cached_page(
                        interaction, uid, old_page + 1)
                    await interaction.response.edit_message(
                        content=await InfractionUtils.assemble_message(
                            interaction.guild_id, page, query, current, pages),
                        view=EphemeralInfSearch(filters=fields,
                                                pages=pages,
                                                current_page=current,
                                                guild_id=interaction.guild_id,
                                                userid=uid))
                elif t == 'last_page':
                    page, current, pages, query, fields = await get_ephemeral_cached_page(
                        interaction, uid, 1000)
                    await interaction.response.edit_message(
                        content=await InfractionUtils.assemble_message(
                            interaction.guild_id, page, query, current, pages),
                        view=EphemeralInfSearch(filters=fields,
                                                pages=pages,
                                                current_page=current,
                                                guild_id=interaction.guild_id,
                                                userid=uid))
        elif interaction.type == InteractionType.application_command:
            if interaction.data.name == "Extract user IDs":
                self.bot.metrics.uid_usage.labels(
                    type="channel", cluster=self.bot.cluster).inc()
                await interaction.response.defer(ephemeral=True)
                parts = await Utils.get_user_ids(interaction.target.content)
                if len(parts) > 0:
                    for chunk in Pages.paginate("\n".join(parts), 200):
                        await interaction.followup.send(chunk)
                else:
                    await interaction.followup.send(
                        MessageUtils.assemble(interaction.guild, "NO",
                                              "no_uids_found"))
            elif interaction.data.name == "Send user IDs to DM":
                self.bot.metrics.uid_usage.labels(
                    type="DM", cluster=self.bot.cluster).inc()
                await interaction.response.defer(ephemeral=True)
                parts = await Utils.get_user_ids(interaction.target.content)
                if len(parts) > 0:
                    try:
                        for chunk in Pages.paginate("\n".join(parts), 200):
                            await interaction.user.send(chunk)
                    except Forbidden:
                        await interaction.followup.send("Unable to send DM")
                    else:
                        await interaction.followup.send("IDs sent in DM")
                else:
                    try:
                        await interaction.user.send(
                            MessageUtils.assemble(interaction.guild, "NO",
                                                  "no_uids_found"))
                    except Forbidden:
                        await interaction.followup.send("Unable to send DM")
                    else:
                        await interaction.followup.send("IDs sent in DM")
            elif interaction.data.name == "Userinfo":
                if await Permissioncheckers.check_permission(
                        self.bot.get_command("userinfo"), interaction.guild,
                        interaction.user, self.bot):
                    t = "allowed"
                    target = interaction.data.target
                    embed = await Utils.generate_userinfo_embed(
                        target, target if isinstance(target, Member) else None,
                        interaction.guild, interaction.user)
                    await interaction.response.send_message(embed=embed,
                                                            ephemeral=True)
                else:
                    t = "denied"
                    await interaction.response.send_message(
                        MessageUtils.assemble(interaction.guild, 'LOCK',
                                              'permission_denied'),
                        ephemeral=True)
                self.bot.metrics.userinfo_usage.labels(
                    type=t, cluster=self.bot.cluster).inc()
            elif interaction.data.name == "Search Infractions":
                if await Permissioncheckers.check_permission(
                        self.bot.get_command("inf search"), interaction.guild,
                        interaction.user, self.bot):
                    uid = interaction.data.target.id
                    t = "allowed"
                    await interaction.response.send_message(
                        MessageUtils.assemble(interaction.guild, 'SEARCH',
                                              'inf_search_compiling'),
                        ephemeral=True)

                    pages = await InfractionUtils.fetch_infraction_pages(
                        interaction.guild.id, uid, 100,
                        ["[user]", "[mod]", "[reason]"], 0)
                    page = await self.bot.wait_for(
                        'page_assembled',
                        check=lambda l: l['key'] == get_key(
                            interaction.guild.id, uid, [
                                "[user]", "[mod]", "[reason]"
                            ], 100) and l['page_num'] == 0)
                    await interaction.edit_original_message(
                        content=await InfractionUtils.assemble_message(
                            interaction.guild.id, page['page'], uid, 0, pages),
                        view=EphemeralInfSearch(
                            filters=["[user]", "[mod]", "[reason]"],
                            pages=pages,
                            guild_id=interaction.guild.id,
                            userid=uid))
                else:
                    t = "denied"
                    await interaction.response.send_message(
                        MessageUtils.assemble(interaction.guild, 'LOCK',
                                              'permission_denied'),
                        ephemeral=True)
                self.bot.metrics.inf_search_usage.labels(
                    type=t, cluster=self.bot.cluster).inc()