Ejemplo n.º 1
0
    async def begone(self, ctx, message: Optional[discord.Message] = None):
        if message is not None and ctx.message.reference is not None:
            raise commands.TooManyArguments(
                "Please only either reply to the problemed message or add it to the end of this message not both"
            )

        message = message if message is not None else ctx.message.reference.resolved if ctx.message.reference is not None else None
        if message is None:
            raise commands.MessageNotFound(
                "Please either reply to the message with this command or add the message to the end of this command"
            )

        if message.author != ctx.guild.me:
            raise commands.CommandError(
                "I will not delete messages that I didn't author with this command"
            )
        reference = await ctx.channel.fetch_message(
            message.reference.message_id)
        if reference.author != ctx.author:
            raise commands.CommandError(
                "You are not the author of that message, I will only 'begone' messages that referenced a message authored by you"
            )

        await asyncio.gather(
            relay_info(
                f"**Begone**\nUSER: {reference.clean_content}\nME: {message.clean_content}```{message}```",
                self.bot,
                webhook=self.bot.log.log_chat), message.delete(),
            ctx.reply(embed=embed(title="Message has been removed"),
                      delete_after=10), ctx.message.delete(delay=10))
Ejemplo n.º 2
0
    async def convert(self, ctx: commands.Context,
                      argument: str) -> list[float]:
        arguments = re.split(r",\s*|\s+(?=\d)", argument)
        arguments = [
            self.strip(argument) for argument in arguments if argument
        ]

        if arguments.__len__() > 2:
            raise commands.TooManyArguments(
                "More than two coordinate arguments were passed.")
        elif arguments.__len__() < 2:
            raise commands.BadArgument(
                "Less than two coordinate arguments were passed.")

        arguments = [
            re.split(r"(?i)(?<=\d)(?:Degrees|Deg(\.)?|°)?(?!\d)", argument)
            for argument in arguments
        ]
        arguments = [[i for i in index if i] for index in arguments]

        coords: list[float | None] = [None, None]
        for i, arg in enumerate(arguments):
            len = arg.__len__()
            if not (1 <= len <= 2):
                raise commands.BadArgument(
                    "More or less than two coordinate arguments were passed")

            if len == 1:
                try:
                    coords[i] = float(arg[0])
                except ValueError as e:
                    raise commands.BadArgument(
                        "Invalid coordinate arguments passed") from e
            elif len == 2:
                try:
                    coord_name = arg[1][0].lower()

                    if coord_name == "n":
                        coords[0] = float(arg[0])
                    elif coord_name == "e":
                        coords[1] = float(arg[0])
                    elif coord_name == "w":
                        coords[1] = -float(arg[0])
                    elif coord_name == "s":
                        coords[0] = -float(arg[0])
                except (ValueError, KeyError) as e:
                    raise commands.BadArgument(
                        "Invalid coordinate arguments passed") from e
        resp = [self.assert_float(coord) for coord in coords]

        if abs(resp[0]) > 90:
            raise commands.BadArgument(
                f"Latitude cannot exceed 90 degrees (given latitude: {resp[0]})."
            )
        elif abs(resp[1]) > 180:
            raise commands.BadArgument(
                f"Longitude cannot exceed 180 degrees (given longitude: {resp[1]})."
            )

        return resp
Ejemplo n.º 3
0
    async def _parse_arguments(self, ctx: Context):
        ctx.args = args = [ctx] if self.instance is None else [
            self.instance, ctx
        ]
        ctx.kwargs = kwargs = {}

        view = ctx.view
        iterator = iter(self.params.items())

        if self.instance is not None:
            # we have 'self' as the first parameter so just advance
            # the iterator and resume parsing
            try:
                next(iterator)
            except StopIteration:
                raise discord.ClientException(
                    f'Callback for {self.name} command is missing "self" parameter.'
                )

        # next we have the 'ctx' as the next parameter
        try:
            next(iterator)
        except StopIteration:
            raise discord.ClientException(
                f'Callback for {self.name} command is missing "ctx" parameter.'
            )

        for name, param in iterator:
            if param.kind == param.POSITIONAL_OR_KEYWORD:
                transformed = await self.transform(ctx, param)
                args.append(transformed)

            elif param.kind == param.KEYWORD_ONLY:
                # kwarg only param denotes "consume rest" semantics
                if self.rest_is_raw:
                    converter = self._get_converter(param)
                    argument = view.read_rest()
                    kwargs[name] = await self.do_conversion(
                        ctx, converter, argument)
                    break

                kwargs[name] = await self.transform(ctx, param)

            elif param.kind == param.VAR_POSITIONAL:
                while not view.eof:
                    try:
                        transformed = await self.transform(ctx, param)
                        args.append(transformed)
                    except RuntimeError:
                        break

        if not self.ignore_extra:
            if not view.eof:
                raise commands.TooManyArguments(
                    f'Too many arguments passed to {self.qualified_name}')
Ejemplo n.º 4
0
    async def _parse_arguments(self, ctx):
        ctx.args = [ctx] if self.cog is None else [self.cog, ctx]
        ctx.kwargs = {}
        args = ctx.args
        kwargs = ctx.kwargs

        view = ctx.view
        iterator = iter(self.params.items())

        if self.cog is not None:
            # we have 'self' as the first parameter so just advance
            # the iterator and resume parsing
            try:
                next(iterator)
            except StopIteration:
                raise discord.ClientException(
                    f'Callback for {self.name} command is missing "self" parameter.'
                )

        # next we have the 'ctx' as the next parameter
        try:
            next(iterator)
        except StopIteration:
            raise discord.ClientException(
                f'Callback for {self.name} command is missing "ctx" parameter.'
            )

        for name, param in iterator:
            if param.kind == param.POSITIONAL_OR_KEYWORD:
                transformed = await self.transform(ctx, param)
                args.append(transformed)
            elif param.kind == param.KEYWORD_ONLY:
                # kwarg only param denotes "consume rest" semantics
                kwargs[
                    name] = await self.callback.__lightning_argparser__.parse_args(
                        ctx)
                break
            elif param.kind == param.VAR_POSITIONAL:
                if view.eof and self.require_var_positional:
                    raise commands.MissingRequiredArgument(param)
                while not view.eof:
                    try:
                        transformed = await self.transform(ctx, param)
                        args.append(transformed)
                    except RuntimeError:
                        break
            elif param.kind == param.VAR_KEYWORD:
                await self._parse_flag_args(ctx)
                break

        if not self.ignore_extra:
            if not view.eof:
                raise commands.TooManyArguments(
                    'Too many arguments passed to ' + self.qualified_name)
Ejemplo n.º 5
0
def validate_attachment(msg):
    """Checks if a message includes 1 image attachment

    Returns the image's proxy_url
    """

    if len(msg.attachments) != 1:
        raise commands.TooManyArguments('needs one file attachment.')
    attachment = msg.attachments[0]
    if attachment.height is None or attachment.width is None:
        raise commands.BadArgument('file attachment must be an image.')

    return attachment.proxy_url
Ejemplo n.º 6
0
    async def command_poll(self, context, name, *options):
        """
        Starts a poll

        Use quotation marks if you want whole phrases as name/options.
        If just the poll name is given, options will be yes/no/maybe, otherwise
        each option will have a letter associated.

        ex:
        `<prefix>poll` "Is this a cool poll command?"
        `<prefix>poll` "Favourite icecream?" chocolate strawberry banana concrete
        """
        if len(options) <= 20:
            message = await context.send(
                embed=self.create_poll_embed(name, options))
            await self.react_with_options(message, options)
        else:
            raise commands.TooManyArguments("Maximum number of options is 20")
Ejemplo n.º 7
0
 async def poll(self, ctx, title, *choices):
     if len(choices) >= 21:
         raise commands.TooManyArguments()
     emoji = 0x0001f1e6  # 絵文字定数(A)
     num = 0
     emojis = []
     content = ""
     if len(choices) == 0:
         choices = ["そう思う", "そう思わない"]
     for num, choice in enumerate(choices):
         reaction = chr(emoji + num)
         content += f"{reaction}:{choice}\n"
         emojis.append(reaction)
     embed = discord.Embed(
         title=title,
         description=content,
         color=0x3aee67)
     msg = await ctx.send(embed=embed)
     await ctx.message.delete()
     [await msg.add_reaction(e) for e in emojis]
Ejemplo n.º 8
0
    async def pick_player(self, ctx: commands.context.Context):
        """
        Adds player to calling captains team.

        SYNOPSIS
            .tm_pick_player @mention
        """
        if len(ctx.message.raw_mentions) > 1:
            raise commands.TooManyArguments(
                "Captain attempted to pick too many players.")

        captain_id = ctx.message.author.id
        try:
            pick = ctx.message.mentions[0]
        except IndexError:
            raise commands.MissingRequiredArgument(param=inspect.Parameter(
                name="Player", kind=inspect.Parameter.POSITIONAL_ONLY))
        captain_team_status = self.__ongoing.get_captain_team_status(
            captain_id)

        last_pick = self.__ongoing.pick_player(pick.id, captain_id)

        role_config_property = Config.get_config_property(
            "tenman", "team{0}".format(captain_team_status.name), "playerRole")
        role = find(lambda r: r.name == role_config_property, ctx.guild.roles)
        await ctx.message.mentions[0].add_roles(role)

        embed = discord.Embed(title="Player Selected",
                              color=discord.Color.red() if captain_team_status
                              == TeamStatus.A else discord.Color.blue())
        embed.add_field(name="Name", value=ctx.message.mentions[0].name)
        embed.add_field(name="Picked By",
                        value="Team {0}".format(captain_team_status.name))
        embed.add_field(name="Ten Man Status",
                        value="[Link]({0})".format(
                            self.__status_message.jump_url))
        embed.set_thumbnail(url=pick.avatar_url)
        await ctx.channel.send(embed=embed)

        try:
            await self.__move_user_to_proper_voice(ctx,
                                                   ctx.message.mentions[0],
                                                   captain_team_status)
        except discord.errors.HTTPException:
            pass

        status_embed = self.__status_message.embeds[0]
        team_field = status_embed.fields[4 if captain_team_status ==
                                         TeamStatus.A else 5]
        status_embed.set_field_at(
            index=(4 if captain_team_status == TeamStatus.A else 5),
            name=team_field.name,
            value=(team_field.value + "\n" + pick.name))

        if last_pick[0] is not None and last_pick[1] is not None:
            last_pick_profile = find(lambda p: p.id == last_pick[0],
                                     ctx.guild.members)
            role_config_property_lp = Config.get_config_property(
                "tenman", "team{0}".format(last_pick[1].name), "playerRole")
            role_lp = find(lambda r: r.name == role_config_property_lp,
                           ctx.guild.roles)

            await last_pick_profile.add_roles(role_lp)

            embed_lp = discord.Embed(title="Last Pick",
                                     color=discord.Color.red() if last_pick[1]
                                     == TeamStatus.A else discord.Color.blue())
            embed_lp.set_thumbnail(url=last_pick_profile.avatar_url)
            embed_lp.add_field(name="Name", value=last_pick_profile.name)
            embed_lp.add_field(name="Picked for",
                               value="Team {0}".format(last_pick[1].name))
            embed_lp.add_field(name="Ten Man Status",
                               value="[Link]({0})".format(
                                   self.__status_message.jump_url))
            await ctx.channel.send(embed=embed_lp)
            status_embed.remove_field(index=3)
            status_embed.set_field_at(
                index=(3 if last_pick[0] == TeamStatus.A else 4),
                name=team_field.name,
                value="{0}\n{1}".format(team_field.value,
                                        last_pick_profile.name))
            status_embed.set_field_at(index=5,
                                      name=status_embed.fields[5].name,
                                      value=status_embed.fields[5].value,
                                      inline=True)
        else:
            rp_field = status_embed.fields[3]
            status_embed.set_field_at(
                index=3,
                name=rp_field.name,
                value="\n".join([
                    find(lambda u: u.id == rp, ctx.guild.members).name
                    for rp in self.__ongoing.get_remaining_participant_ids()
                ]))
            status_embed.set_field_at(index=5,
                                      name=status_embed.fields[5].name,
                                      value=status_embed.fields[5].value,
                                      inline=True)
        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            try:
                message = "***Help Message:***\nIt is Team {0}'s turn to pick the next player.\nThey can do so by " \
                          "using the command\n`.pick_player @player`".format(self.__ongoing.peek_next_player_pick().name)
            except IndexError:
                map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban()
                message = "***Help Message:***\nIt is now time to move on to the map pick/ban phase. Team " \
                          "{0.get_team_status().name} can {0.get_mode().name.lower()} the first map.\nThey can do so" \
                          "by using the command\n`{0.get_mode().name.lower()}_map map`".format(map_pick_ban_entry)
            await ctx.channel.send(message)
Ejemplo n.º 9
0
    async def pick_captains(self, ctx: commands.context.Context):
        """
        Makes mentioned players captain or selects two captains at random if none are provided

        SYNOPSIS
            .tm_pick_captains [@mention @mention]
        """
        # Caller tried to manually select too many captains
        if len(ctx.message.mentions) > 2:
            raise commands.TooManyArguments(
                "Attempted to pick too many captains.")

        # Create role objects for config
        captain_a_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamA", "captainRole"), ctx.guild.roles)
        captain_b_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamB", "captainRole"), ctx.guild.roles)

        # Get captains either randomly or manually (based on # of mentioned users)
        captain_ids = ctx.message.raw_mentions
        captains = self.__ongoing.set_or_pick_captains(captain_ids)
        captain_a = find(lambda c: c.id == captains[0], ctx.guild.members)
        captain_b = find(lambda c: c.id == captains[1], ctx.guild.members)
        await captain_a.add_roles(captain_a_role)
        await captain_b.add_roles(captain_b_role)

        # Pretty output for discord
        embed_a = discord.Embed(title="Captain Selected",
                                color=discord.Color.red())
        embed_a.set_thumbnail(url=captain_a.avatar_url)
        embed_a.add_field(name="Name", value=captain_a.name)
        embed_a.add_field(
            name="Selection Type",
            value="Manual" if len(ctx.message.mentions) == 2 else "Random")
        embed_a.add_field(name="Ten Man Status",
                          value="[Link](" + self.__status_message.jump_url +
                          ")")

        embed_b = discord.Embed(title="Captain Selected",
                                color=discord.Color.blue())
        embed_b.set_thumbnail(url=captain_b.avatar_url)
        embed_b.add_field(name="Name", value=captain_b.name)
        embed_b.add_field(
            name="Selection Type",
            value="Manual" if len(ctx.message.mentions) == 2 else "Random")
        embed_b.add_field(name="Ten Man Status",
                          value="[Link](" + self.__status_message.jump_url +
                          ")")

        await ctx.channel.send(embed=embed_a)
        await ctx.channel.send(embed=embed_b)

        try:
            await self.__move_user_to_proper_voice(ctx, captain_a,
                                                   TeamStatus.A)
            await self.__move_user_to_proper_voice(ctx, captain_b,
                                                   TeamStatus.B)
        except discord.errors.HTTPException:
            pass

        status_embed = self.__status_message.embeds[0]
        rp_field = status_embed.fields[3]
        status_embed.set_field_at(
            index=3,
            name=rp_field.name,
            value="\n".join([
                find(lambda u: u.id == rp, ctx.guild.members).name
                for rp in self.__ongoing.get_remaining_participant_ids()
            ]))
        status_embed.insert_field_at(index=4,
                                     name="Team A",
                                     value=captain_a.name,
                                     inline=True)
        status_embed.insert_field_at(index=5,
                                     name="Team B",
                                     value=captain_b.name,
                                     inline=True)
        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            message = "***Help Message***:\nNow that captains have been selected, it is time for the captain of Team" \
                      "A to pick a player. They can do so by using the command\n`.pick_player @mention`"
            await ctx.channel.send(message)