async def newcontributors_fetch(self, ctx: GuildContext) -> None:
        """Fetches all contributors and puts them in pending list.

        This command should only be ran on first setup.
        """
        async with ctx.typing():
            await self._newcontributors_fetch(ctx)
Пример #2
0
    async def mee6rank(self,
                       ctx: commands.GuildContext,
                       member: Optional[discord.Member] = None) -> None:
        """Get detailed information about Mee6 rank for you or given member."""
        async with ctx.typing():
            if (player := await self._maybe_get_player(ctx, member)) is None:
                return

            embed = discord.Embed(title=f"Mee6 rank for {player.member.name}")
            embed.add_field(name="Level", value=str(player.level))
            embed.add_field(name="XP amount", value=str(player.total_xp))
            xp_needed = player.xp_until_next_level
            embed.add_field(name="XP needed to next level",
                            value=str(xp_needed))
            embed.add_field(
                name="Average amount of messages to next lvl",
                value=str(self._message_amount_from_xp(xp_needed)),
            )
            next_role_reward = player.next_role_reward
            if next_role_reward is not None:
                xp_needed = player.xp_until_level(next_role_reward.rank)
                embed.add_field(
                    name=f"XP to next role - {next_role_reward.role.name}",
                    value=str(xp_needed),
                )
                embed.add_field(
                    name=("Average amount of messages to next role"
                          f" - {next_role_reward.role.name}"),
                    value=str(self._message_amount_from_xp(xp_needed)),
                )
            await ctx.send(embed=embed)
Пример #3
0
    async def resetnicks(self, ctx: commands.GuildContext) -> None:
        """
        Reset everyone's nicknames to what they were before `[p]renameall` command was used.
        """
        not_changed = []
        async with ctx.typing():
            for member in ctx.guild.members:
                original_nick = await self.config.member(member
                                                         ).original_nick()
                if original_nick is False:
                    continue
                if (member.top_role >= ctx.guild.me.top_role
                        and member is not ctx.guild.me):
                    not_changed.append(
                        f"{member} - Member's top role is not lower than mine."
                    )
                    continue
                try:
                    await member.edit(nick=original_nick,
                                      reason="Revert April Fools joke")
                except discord.HTTPException as exc:
                    not_changed.append(
                        f"{member} - An unexpected error occurred"
                        f" when trying to edit member's nickname: {exc}")
                else:
                    await self.config.member(member).original_nick.clear()

        msg = "Nicknames updated!\n"
        if not_changed:
            msg += "Nicknames of these users have not been updated:\n"
            msg += "\n".join(not_changed)
        for page in pagify(msg):
            await ctx.send(page)
Пример #4
0
    async def setmessage(self, ctx: commands.GuildContext, message: str):
        """
        Set the message to add the emoji's
        """
        guild = ctx.message.guild
        current_message = await self._config.guild(guild).welcome_message()

        # Check if the guild alrdy has used 'setmessage'
        if current_message:
            await ctx.send("A Message has already been set for this server. Would you like to change it? (respond with yes or no)")
            continue_setup = await bot.wait_for(
                'message', check=lambda message: message if message.author == ctx.author and message.channel in guild.channels and (message.lower() == "yes" or message.lower() == "no"))
            if continue_setup.lower() == "yes":
                pass
            else:
                return await ctx.send("Stopped the setup")

        # Intermediate Update about the progress
        ctx.send("""
        Succesfully received the new message for RoleManager!
        
        Which channel would you like to post it? (Type the exact channel name in chat)
        """)

        # Simple watcher
        which_channel = await bot.wait_for(
            'message', check=lambda message: message if message.author == ctx.author and message.channel in guild.channels else False)

        if not which_channel:
            return
        # Create try/except blocks to check for assignment availability
        try:
            assigned_channel = discord.utils.get(
                ctx.guild.channels, name=which_channel)

        except Exception as exc:
            return await ctx.send(f"Could not find channel {which_channel}. Encountered error: {exc}")

        try:
            await self._config.guild(guild).welcome_message.set(message)
            await self._config.guild(guild).welcome_message_channel.set(assigned_channel.id)

        except Exception as exc:
            return await ctx.send(f"Could not assign given content to {guild} guild Configuration. Encountered Error: {exc}")

        # Purposely taking the message from the Config object for persistence.
        return await assigned_channel.send(self._config.guild(guild).welcome_message())
Пример #5
0
    async def renameall(self, ctx: commands.GuildContext) -> None:
        """
        Rename everyone in the server.

        These values will be substituted:
        $index - Member's number/index on the members list. First server member (with the earliest join date) has $index=1, second member $index=2 and so on.
        """
        nick_template = await self.config.guild(ctx.guild).nick_template()
        if nick_template is None:
            command = inline(f"{ctx.clean_prefix}setnicktemplate")
            await ctx.send("Nickname template needs to be set"
                           f" with {command} before you can use this command.")
            return
        tmpl = Template(nick_template)
        if len(tmpl.safe_substitute(index=len(ctx.guild.members))) > 32:
            await ctx.send("The set nickname is too long!")
            return

        members = sorted(ctx.guild.members, key=lambda m: m.joined_at)
        rename_exclusions = await self.config.guild(ctx.guild
                                                    ).rename_exclusions()

        not_changed = []
        async with ctx.typing():
            for idx, member in enumerate(members, start=1):
                nick = tmpl.safe_substitute(index=idx)
                if member.id in rename_exclusions:
                    not_changed.append(
                        f"{member} (would be: {nick})"
                        " - Member is set to be excluded from renaming.")
                    continue
                if (member.top_role >= ctx.guild.me.top_role
                        and member is not ctx.guild.me):
                    not_changed.append(
                        f"{member} (would be: {nick})"
                        " - Member's top role is not lower than mine.")
                    continue
                original_nick = member.nick
                try:
                    await member.edit(nick=nick, reason="April Fools joke")
                except discord.HTTPException as exc:
                    not_changed.append(
                        f"{member} (would be: {nick}) - An unexpected error occurred"
                        f" when trying to edit member's nickname: {exc}")
                else:
                    await self.config.member(member).original_nick.set(
                        original_nick)

        msg = "Nicknames updated!\n"
        if not_changed:
            msg += "Nicknames of these users have not been updated:\n"
            msg += "\n".join(not_changed)
        await ctx.send(msg)
Пример #6
0
    async def importbans(self, ctx: commands.GuildContext):
        """
        Imports bans from json
        """
        if not ctx.message.attachments:
            return await ctx.send(
                _(
                    "You definitely need to supply me an exported ban list to be imported."
                )
            )

        fp = io.BytesIO()
        a = ctx.message.attachments[0]
        await a.save(fp)
        try:
            data = json.load(fp)
            if not isinstance(data, list) or not all(isinstance(x, int) for x in data):
                raise TypeError() from None
        except (json.JSONDecodeError, TypeError):
            return await ctx.send(_("That wasn't an exported ban list"))

        current_bans = await ctx.guild.bans()
        to_ban = set(data) - {b.user.id for b in current_bans}

        if not to_ban:
            return await ctx.send(
                _("That list doesn't contain anybody not already banned.")
            )

        async with ctx.typing():
            exit_codes = [
                await self.ban_or_hackban(
                    ctx.guild,
                    idx,
                    mod=ctx.author,
                    reason=f"Imported ban by {ctx.author}({ctx.author.id})",
                )
                for idx in to_ban
            ]

        if all(exit_codes):
            await ctx.message.add_reaction("\N{HAMMER}")
        elif not any(exit_codes):
            await ctx.send(_("You are not worthy"))
        else:
            await ctx.send(
                _(
                    "I got some of those, but other's couldn't be banned for some reason."
                )
            )
Пример #7
0
    async def mrole_complex(self, ctx: GuildContext, *,
                            _query: ComplexActionConverter):
        """
        Similar syntax to search, while applying/removing roles

        --has-all roles
        --has-none roles
        --has-any roles

        --has-no-roles
        --has-exactly-nroles number
        --has-more-than-nroles number
        --has-less-than-nroles number

        --has-perm permissions
        --any-perm permissions
        --not-perm permissions

        --above role
        --below role

        --only-humans
        --only-bots
        --everyone

        --add roles
        --remove roles
        """
        query = _query.parsed
        apply = query["add"] + query["remove"]
        if not await self.all_are_valid_roles(ctx, *apply):
            return await ctx.send(
                "Either you or I don't have the required permissions "
                "or position in the hierarchy.")

        members = set(ctx.guild.members)
        members = self.search_filter(members, query)

        if len(members) > 100:
            await ctx.send(
                "This may take a while given the number of members to update.")

        async with ctx.typing():
            for member in members:
                try:
                    await self.update_roles_atomically(who=member,
                                                       give=query["add"],
                                                       remove=query["remove"])
                except RoleManagementException:
                    log.debug(
                        "Internal filter failure on member id %d guild id %d query %s",
                        member.id,
                        ctx.guild.id,
                        query,
                    )
                except discord.HTTPException:
                    log.debug(
                        "Unpredicted failure for member id %d in guild id %d query %s",
                        member.id,
                        ctx.guild.id,
                        query,
                    )

        await ctx.tick()