Ejemplo n.º 1
0
    async def check_constraints(self, ctx, now, remaining):
        if self.dt < now:
            raise commands.BadArgument('This time is in the past.')

        if not remaining:
            if self.default is None:
                raise commands.BadArgument('Missing argument after the time.')
            remaining = self.default

        if self.converter is not None:
            self.arg = await self.converter.convert(ctx, remaining)
        else:
            self.arg = remaining
        return self
Ejemplo n.º 2
0
    async def jsk_invite(self, ctx: commands.Context, *perms: str):
        """
        Retrieve the invite URL for this bot.

        If the names of permissions are provided, they are requested as part of the invite.
        """

        scopes = ('bot', 'applications.commands')
        permissions = disnake.Permissions()

        for perm in perms:
            if perm not in dict(permissions):
                raise commands.BadArgument(f"Invalid permission: {perm}")

            setattr(permissions, perm, True)

        application_info = await self.bot.application_info()

        query = {
            "client_id": application_info.id,
            "scope": "+".join(scopes),
            "permissions": permissions.value
        }

        return await ctx.send(
            f"Link to invite this bot:\n<https://discordapp.com/oauth2/authorize?{urlencode(query, safe='+')}>"
        )
Ejemplo n.º 3
0
    async def convert(self, ctx, argument):
        argument = await super().convert(ctx, argument)

        if argument != disnake.utils.escape_markdown(argument):
            raise commands.BadArgument('No markdown allowed in prefix.')

        return argument
Ejemplo n.º 4
0
    def get_raw(self, link: str) -> str:
        """Returns the url to raw text version of certain pastebin services."""
        link = link.strip("<>/")  # Allow for no-embed links

        if not any(link.startswith(url) for url in self.authorized):
            raise commands.BadArgument(
                message=
                f"Only links from the following domains are accepted: {', '.join(self.authorized)}. "
                f"(Starting with 'https').")

        domain = link.split("/")[2]

        if domain == "hastebin.com":
            if "/raw/" in link:
                return link
            token = link.split("/")[-1]
            if "." in token:
                token = token[:token.rfind(".")]  # removes extension
            return f"{self.hastebin_link}/raw/{token}"
        else:
            # Github uses redirection so raw -> user content and no raw -> normal
            # We still need to ensure we get a raw version after this potential redirection
            if "/raw" in link:
                return link
            return link + "/raw"
Ejemplo n.º 5
0
    def __init__(self, argument, *, now=None):
        match = self.compiled.fullmatch(argument)
        if match is None or not match.group(0):
            raise commands.BadArgument('invalid time provided')

        data = {k: int(v) for k, v in match.groupdict(default=0).items()}
        now = now or datetime.datetime.now(datetime.timezone.utc)
        self.dt = now + relativedelta(**data)
Ejemplo n.º 6
0
    async def convert(self, ctx, argument):
        value = _make_int(self, ctx, argument)

        if value > self.MAX:
            name = param_name(self, ctx)
            raise commands.BadArgument(f'{name} must be a lower value.')

        return value
Ejemplo n.º 7
0
    async def convert(self, ctx, argument):
        value = _make_int(self, ctx, argument)

        if value > self.max:
            name = param_name(self, ctx)
            raise commands.BadArgument(f'{name} must be lower than {self.max}')

        return value
Ejemplo n.º 8
0
    async def convert(self, ctx, argument):
        ret = f'{ctx.author} (ID: {ctx.author.id}): {argument}'

        if len(ret) > 512:
            reason_max = 512 - len(ret) - len(argument)
            raise commands.BadArgument(
                f'reason is too long ({len(argument)}/{reason_max})')
        return ret
Ejemplo n.º 9
0
    async def convert(self, ctx, argument):
        guild_emojis = list(str(e) for e in ctx.guild.emojis)

        if argument not in emoji.UNICODE_EMOJI['en']:
            if argument not in guild_emojis:
                raise commands.BadArgument('Unknown emoji.')

        return argument
Ejemplo n.º 10
0
    async def convert(self, ctx, action):
        try:
            value = SecurityAction[action.upper()]
        except KeyError:
            raise commands.BadArgument(
                '\'{0}\' is not a valid action. Valid actions are {1}'.format(
                    action, self.valid_actions))

        return value
Ejemplo n.º 11
0
    async def convert(self, ctx, argument):
        length = len(argument)

        if length > self.max:
            name = param_name(self, ctx)
            raise commands.BadArgument(
                f'{name} must be shorter than {self.max} characters.')

        return argument
Ejemplo n.º 12
0
    async def convert(self, ctx, argument):
        try:
            message = await super().convert(ctx, argument)
            _id = message.id
        except commands.BadArgument:
            try:
                _id = int(argument, base=10)
            except ValueError:
                name = param_name(self, ctx)
                raise commands.BadArgument(
                    f'{name} doesn\'t seem to be a message or message id.')

        row = await ctx.bot.db.fetchrow(
            'SELECT * FROM star_msg WHERE guild_id=$1 AND (message_id=$2 OR star_message_id=$2)',
            ctx.guild.id, _id)

        if row is None:
            name = param_name(self, ctx)
            raise commands.BadArgument(f'{name} is not a starred message.')

        return row
Ejemplo n.º 13
0
    async def convert(self, ctx, argument):
        ban_list = await ctx.guild.bans()
        try:
            member_id = int(argument, base=10)
            entity = disnake.utils.find(lambda u: u.user.id == member_id,
                                        ban_list)
        except ValueError:
            entity = disnake.utils.find(lambda u: str(u.user) == argument,
                                        ban_list)

        if entity is None:
            raise commands.BadArgument("Not a valid previously-banned member.")
        return entity
Ejemplo n.º 14
0
    async def scan_history(self, ctx, limit):
        """Scan current channel for images and save them as hashes
        limit: [all | <int>]
        """
        # parse parameter
        if limit == "all":
            limit = None
        else:
            try:
                limit = int(limit)
                if limit < 1:
                    raise ValueError
            except ValueError:
                raise commands.BadArgument("Expected 'all' or positive integer")

        messages = await ctx.channel.history(limit=limit).flatten()

        title = "**INITIATING...**\n\nLoaded {} messages"
        await asyncio.sleep(0.5)
        template = (
            "**SCANNING IN PROGRESS**\n\n"
            "Processed **{}** of **{}** messages ({:.1f} %)\n"
            "Computed **{}** hashes"
        )
        msg = await ctx.send(title.format(len(messages)))

        ctr_nofile = 0
        ctr_hashes = 0
        i = 0
        now = time.time()
        for i, message in enumerate(messages):
            # update info on every 10th message
            if i % 50 == 0:
                await msg.edit(
                    content=template.format(i, len(messages), (i / len(messages) * 100), ctr_hashes)
                )

            if len(message.attachments) == 0:
                ctr_nofile += 1
                continue

            hashes = [x async for x in self.saveMessageHashes(message)]
            ctr_hashes += len(hashes)

        await msg.edit(
            content="**SCAN COMPLETE**\n\n"
            f"Processed **{len(messages)}** messages.\n"
            f"Computed **{ctr_hashes}** hashes in {(time.time() - now):.1f} seconds."
        )
Ejemplo n.º 15
0
Archivo: tags.py Proyecto: Run1e/AceBot
    async def convert(self, ctx, argument):
        tag_name = await super().convert(ctx, argument.lower())

        if tag_name in self._reserved:
            raise commands.BadArgument('Sorry, that tag name is reserved.')

        escape_converter = commands.clean_content(fix_channel_mentions=True,
                                                  escape_markdown=True)
        if tag_name != await escape_converter.convert(ctx, tag_name):
            raise commands.BadArgument(
                'Tag name has disallowed formatting in it.')

        if ctx.cog.tag_is_being_made(ctx, tag_name):
            raise commands.BadArgument(
                'Tag with that name is currently being made elsewhere.')

        exist_id = await ctx.bot.db.fetchval(
            'SELECT id FROM tag WHERE guild_id=$1 AND (name=$2 OR alias=$2)',
            ctx.guild.id, tag_name)

        if exist_id is not None:
            raise commands.BadArgument('Tag name is already in use.')

        return tag_name
Ejemplo n.º 16
0
    async def convert(self, ctx, argument):
        try:
            m = await commands.MemberConverter().convert(ctx, argument)
        except commands.BadArgument:
            try:
                member_id = int(argument, base=10)
            except ValueError:
                raise commands.BadArgument(
                    f"{argument} is not a valid member or member ID."
                ) from None
            else:
                m = await ctx.bot.get_or_fetch_member(ctx.guild, member_id)
                if m is None:
                    # hackban case
                    return type('_Hackban', (), {
                        'id': member_id,
                        '__str__': lambda s: f'Member ID {s.id}'
                    })()

        if not can_execute_action(ctx, ctx.author, m):
            raise commands.BadArgument(
                'You cannot do this action on this user due to role hierarchy.'
            )
        return m
Ejemplo n.º 17
0
Archivo: time.py Proyecto: Run1e/AceBot
    async def convert(self, ctx, unit):
        unit = unit.lower()

        if unit in ('s', 'sec', 'secs', 'second', 'seconds'):
            return timedelta(seconds=1)
        elif unit in ('m', 'min', 'mins', 'minute', 'minutes'):
            return timedelta(minutes=1)
        elif unit in ('h', 'hr', 'hrs', 'hour', 'hours'):
            return timedelta(hours=1)
        elif unit in ('d', 'day', 'days'):
            return timedelta(days=1)
        elif unit in ('w', 'wk', 'week', 'weeks'):
            return timedelta(weeks=1)
        else:
            raise commands.BadArgument('Unknown time type.')
Ejemplo n.º 18
0
    def __init__(self, argument, *, now=None):
        now = now or datetime.datetime.utcnow()
        dt, status = self.calendar.parseDT(argument, sourceTime=now)
        if not status.hasDateOrTime:
            raise commands.BadArgument(
                'invalid time provided, try e.g. "tomorrow" or "3 days"')

        if not status.hasTime:
            # replace it with the current time
            dt = dt.replace(hour=now.hour,
                            minute=now.minute,
                            second=now.second,
                            microsecond=now.microsecond)

        self.dt = dt
        self._past = dt < now
Ejemplo n.º 19
0
 async def fetch(self, ctx: KurisuContext, _id: int):
     """Fetch information about a specific discord user"""
     user = await self.bot.fetch_user(_id)
     flags = [
         v.replace("_", " ").title() for v, b in user.public_flags if b
     ]
     if not user:
         raise commands.BadArgument(f"Failed converting {_id} to user.")
     await ctx.send(
         embed=disnake.Embed(title=f"Information for {user}",
                             color=self.bot.info_color).set_thumbnail(
                                 url=user.display_avatar.url).
         add_field(name="ID", value=user.id).add_field(
             name="Avatar URL",
             value=f"[url]({user.display_avatar.url})").add_field(
                 name="Account Creation",
                 value=disnake.utils.format_dt(user.created_at, style="R")
             ).add_field(name="Bot",
                         value=":white_check_mark:" if user.bot else ":x:").
         add_field(name="Flags", value="".join(flags) if flags else "None"))
Ejemplo n.º 20
0
    async def source_command(self,
                             ctx: commands.Context,
                             *,
                             source_item: typing.Optional[str] = None) -> None:
        """Displays information about the bot's source code."""
        if source_item is None:
            embed = Embed(title="Gurkbot's GitHub Repository")
            embed.add_field(name="Repository",
                            value=f"[Go to GitHub]({BOT_REPO_URL})")
            embed.set_thumbnail(url=self.bot.user.display_avatar.url)
            await ctx.send(embed=embed)
            return
        elif not ctx.bot.get_command(source_item):
            raise commands.BadArgument(
                f"Unable to convert `{source_item}` to valid command or Cog.")

        github_source = _source.Source(self.bot.http_session,
                                       self.bot.user.display_avatar.url)
        embed = await github_source.inspect(
            cmd=ctx.bot.get_command(source_item))

        await ctx.send(embed=embed)
Ejemplo n.º 21
0
    async def jsk_cancel(self, ctx: commands.Context, *,
                         index: typing.Union[int, str]):
        """
        Cancels a task with the given index.

        If the index passed is -1, will cancel the last task instead.
        """

        if not self.tasks:
            return await ctx.send("No tasks to cancel.")

        if index == "~":
            task_count = len(self.tasks)

            for task in self.tasks:
                task.task.cancel()

            self.tasks.clear()

            return await ctx.send(f"Cancelled {task_count} tasks.")

        if isinstance(index, str):
            raise commands.BadArgument('Literal for "index" not recognized.')

        if index == -1:
            task = self.tasks.pop()
        else:
            task = disnake.utils.get(self.tasks, index=index)
            if task:
                self.tasks.remove(task)
            else:
                return await ctx.send("Unknown task.")

        task.task.cancel()
        return await ctx.send(
            f"Cancelled task {task.index}: `{task.ctx.command.qualified_name}`,"
            f" invoked at {task.ctx.message.created_at.strftime('%Y-%m-%d %H:%M:%S')} UTC"
        )
Ejemplo n.º 22
0
    def __init__(self, argument, *, now=None):
        super().__init__(argument, now=now)

        if self._past:
            raise commands.BadArgument('this time is in the past')
Ejemplo n.º 23
0
 def _make_error(self, ctx):
     name = param_name(self, ctx)
     return commands.BadArgument(
         f'{name} must be between {self.min} and {self.max} characters.')
Ejemplo n.º 24
0
def activity_type(argument) -> disnake.ActivityType:
    try:
        return disnake.ActivityType[argument]
    except Exception as e:
        raise commands.BadArgument(f'Activity not valid: {e}')
Ejemplo n.º 25
0
 async def convert(self, ctx, argument):
     user_id = ctx.bot.user.id
     if argument.startswith((f'<@{user_id}>', f'<@!{user_id}>')):
         raise commands.BadArgument(
             'That is a reserved prefix already in use.')
     return argument
Ejemplo n.º 26
0
def _make_int(converter, ctx, argument):
    try:
        return int(argument)
    except ValueError:
        name = param_name(converter, ctx)
        raise commands.BadArgument(f'{name} should be a number.')
Ejemplo n.º 27
0
 async def convert(self, ctx: commands.Context, argument) -> list:
     try:
         return resolve_extensions(ctx.bot, argument)
     except UnbalancedBracesError as exc:
         raise commands.BadArgument(str(exc))
Ejemplo n.º 28
0
    async def convert(self, ctx, argument):
        # Create a copy of ourselves to prevent race conditions from two
        # events modifying the same instance of a converter
        result = self.copy()
        try:
            calendar = HumanTime.calendar
            regex = ShortTime.compiled
            now = ctx.message.created_at

            match = regex.match(argument)
            if match is not None and match.group(0):
                data = {
                    k: int(v)
                    for k, v in match.groupdict(default=0).items()
                }
                remaining = argument[match.end():].strip()
                result.dt = now + relativedelta(**data)
                return await result.check_constraints(ctx, now, remaining)

            # apparently nlp does not like "from now"
            # it likes "from x" in other cases though so let me handle the 'now' case
            if argument.endswith('from now'):
                argument = argument[:-8].strip()

            if argument[0:2] == 'me':
                # starts with "me to", "me in", or "me at "
                if argument[0:6] in ('me to ', 'me in ', 'me at '):
                    argument = argument[6:]

            elements = calendar.nlp(argument, sourceTime=now)
            if elements is None or len(elements) == 0:
                raise commands.BadArgument(
                    'Invalid time provided, try e.g. "tomorrow" or "3 days".')

            # handle the following cases:
            # "date time" foo
            # date time foo
            # foo date time

            # first the first two cases:
            dt, status, begin, end, dt_string = elements[0]

            if not status.hasDateOrTime:
                raise commands.BadArgument(
                    'Invalid time provided, try e.g. "tomorrow" or "3 days".')

            if begin not in (0, 1) and end != len(argument):
                raise commands.BadArgument('Time is either in an inappropriate location, which ' \
                                           'must be either at the end or beginning of your input, ' \
                                           'or I just flat out did not understand what you meant. Sorry.')

            if not status.hasTime:
                # replace it with the current time
                dt = dt.replace(hour=now.hour,
                                minute=now.minute,
                                second=now.second,
                                microsecond=now.microsecond)

            # if midnight is provided, just default to next day
            if status.accuracy == pdt.pdtContext.ACU_HALFDAY:
                dt = dt.replace(day=now.day + 1)

            result.dt = dt.replace(tzinfo=datetime.timezone.utc)

            if begin in (0, 1):
                if begin == 1:
                    # check if it's quoted:
                    if argument[0] != '"':
                        raise commands.BadArgument(
                            'Expected quote before time input...')

                    if not (end < len(argument) and argument[end] == '"'):
                        raise commands.BadArgument(
                            'If the time is quoted, you must unquote it.')

                    remaining = argument[end + 1:].lstrip(' ,.!')
                else:
                    remaining = argument[end:].lstrip(' ,.!')
            elif len(argument) == end:
                remaining = argument[:begin].strip()

            return await result.check_constraints(ctx, now, remaining)
        except:
            import traceback
            traceback.print_exc()
            raise