Esempio n. 1
0
    async def remind_me(self, ctx, when: str, *, message: str):
        """ Request the bot remind you in the given time. """

        timestamp = dateparser.parse(when)
        now = datetime.now()
        if timestamp is None:
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = (
                f"Unknown date specification: `{escape_backticks(when)}`")
            raise CommandFailed(embed=embed)

        if now > timestamp:
            # First, try to see if a naive time specification put it in the past
            new_timestamp = dateparser.parse(f"in {when}")
            if new_timestamp is None or now > new_timestamp:
                time_since = fancy_timedelta(now - timestamp)
                embed = discord.Embed(colour=discord.Colour.red())
                embed.description = f"Specified date was in the past: {time_since} ago"
                raise CommandFailed(embed=embed)

            # Was successful, replace it
            timestamp = new_timestamp

        # Check time
        assert timestamp > now
        duration = timestamp - now
        time_since = fancy_timedelta(duration)
        if duration > MAX_REMINDER_DURATION:
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = f"Specified date is too far away: {time_since}"
            raise CommandFailed(embed=embed)

        logger.info(
            "Creating self-reminder SendMessageTask for '%s' (%d): %r",
            ctx.author.name,
            ctx.author.id,
            message,
        )

        # Create navi task
        embed = discord.Embed(colour=discord.Colour.dark_teal())
        embed.set_author(name=f"Reminder made {time_since} ago")
        embed.description = f"You asked to be reminded of:\n\n{message}"
        embed.timestamp = now
        self.bot.add_tasks(
            SendMessageTask(
                self.bot,
                None,
                ctx.author,
                timestamp,
                None,
                ctx.author,
                embed=embed,
                metadata={
                    "type": "reminder",
                    "message": message
                },
            ))
Esempio n. 2
0
    async def uinfo(self, ctx, *, name: str = None):
        """
        Fetch information about a user, whether they are in the guild or not.
        If no argument is passed, the caller is checked instead.
        """

        user = await self.get_user(ctx, name)
        usernames, nicknames = self.bot.sql.alias.get_alias_names(
            ctx.guild, user)

        logger.info("Running uinfo on '%s' (%d)", user.name, user.id)

        # Status
        content = StringBuilder()
        if getattr(user, "status", None):
            status = ("do not disturb"
                      if user.status == discord.Status.dnd else user.status)
            content.writeln(f"{user.mention}, {status}")
        else:
            content.writeln(user.mention)

        embed = discord.Embed()
        embed.timestamp = user.created_at
        embed.set_author(name=user_discrim(user))
        embed.set_thumbnail(url=user.avatar_url)

        # User colour
        if hasattr(user, "colour"):
            embed.colour = user.colour

        embed.add_field(name="ID", value=f"`{user.id}`")
        self.uinfo_add_roles(embed, user)
        self.uinfo_add_activity(embed, user, content)

        embed.description = str(content)
        content.clear()

        self.uinfo_add_voice(embed, user)
        self.uinfo_add_aliases(embed, content, usernames, nicknames)

        # Guild join date
        if hasattr(user, "joined_at"):
            embed.add_field(name="Member for",
                            value=fancy_timedelta(user.joined_at))

        # Discord join date
        embed.add_field(name="Account age",
                        value=fancy_timedelta(user.created_at))

        # Send them
        await ctx.send(embed=embed)
Esempio n. 3
0
    async def about(self, ctx):
        """ Prints information about the running bot. """

        pyver = sys.version_info
        python_emoji = self.bot.get_emoji(
            self.bot.config.python_emoji_id) or ""
        discord_py_emoji = self.bot.get_emoji(
            self.bot.config.discord_py_emoji_id) or ""

        embed = discord.Embed()
        embed.set_thumbnail(url=self.bot.user.avatar_url)
        embed.set_author(name=f"Futaba v{__version__} [{GIT_HASH}]")
        embed.add_field(name="Running for",
                        value=fancy_timedelta(self.bot.uptime))
        embed.add_field(
            name="Created by",
            value="[Programming Discord](https://discord.gg/010z0Kw1A9ql5c1Qe)",
        )
        embed.add_field(name="Source code",
                        value="https://github.com/strinking/futaba")
        embed.description = "\n".join((
            f"{python_emoji} Powered by Python {pyver.major}.{pyver.minor}.{pyver.micro}",
            f"{discord_py_emoji} Using discord.py {discord.__version__}",
            f"\N{TIMER CLOCK} Latency: {self.bot.latency:.3} s",
        ))

        if ctx.guild is not None:
            embed.colour = ctx.guild.me.colour

        await ctx.send(embed=embed)
Esempio n. 4
0
        def make_embed(message):
            embed = discord.Embed(colour=message.author.colour)
            embed.description = message.content or None
            embed.timestamp = message.created_at
            embed.url = message.jump_url
            embed.set_author(
                name=f"{message.author.name}#{message.author.discriminator}")
            embed.set_thumbnail(url=message.author.avatar_url)
            embed.add_field(name="Sent by", value=message.author.mention)

            if ctx.guild is not None:
                embed.add_field(name="Channel", value=message.channel.mention)

            embed.add_field(name="Permalink", value=message.jump_url)

            if message.edited_at is not None:
                delta = fancy_timedelta(message.edited_at - message.created_at)
                embed.add_field(
                    name="Edited at",
                    value=f"`{message.edited_at}` ({delta} afterwords)",
                )

            if message.attachments:
                embed.add_field(
                    name="Attachments",
                    value="\n".join(attach.url
                                    for attach in message.attachments),
                )

            if message.embeds:
                embed.add_field(name="Embeds", value=str(len(message.embeds)))

            if message.reactions:
                emojis = Counter()
                for reaction in message.reactions:
                    emojis[str(reaction.emoji)] += 1

                embed.add_field(
                    name="Reactions",
                    value="\n".join((f"{count}: {emoji}"
                                     for emoji, count in emojis.items())),
                )

            return embed
Esempio n. 5
0
    async def remind_list(self, ctx):
        """ Lists all reminders for the current user. """

        reminders = self.bot.sql.navi.get_reminders(ctx.author)
        if reminders:
            descr = StringBuilder()
            for reminder in reminders:
                until = fancy_timedelta(reminder.timestamp)
                message = escape_backticks(reminder.message)
                descr.writeln(
                    f"ID: #`{reminder.id:05}`: in `{until}` with message: `{message}`"
                )

            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.set_author(name=f"Reminders for {ctx.author.display_name}")
            embed.description = str(descr)
        else:
            embed = discord.Embed(colour=discord.Colour.dark_purple())
            embed.description = f"No reminders for {ctx.author.mention}"

        await ctx.send(embed=embed)
Esempio n. 6
0
    async def aliases(self, ctx, *, user: UserConv):
        """ Gets information about known aliases of the given user. """

        logger.info(
            "Getting and printing alias information for some user '%s' (%d)",
            user.name,
            user.id,
        )

        avatars, usernames, nicknames, alt_user_ids = self.bot.sql.alias.get_aliases(
            ctx.guild, user)

        # Remove self from chain
        try:
            alt_user_ids.remove(user.id)
        except KeyError:
            pass

        embed = discord.Embed(colour=discord.Colour.dark_teal())
        embed.set_author(name="Member alias information")

        if not any((avatars, usernames, nicknames, alt_user_ids)):
            embed.colour = discord.Colour.dark_purple()
            embed.description = f"No information found for {user.mention}"

            await ctx.send(embed=embed)
            return

        embed.description = f"{user.mention}\n"
        content = StringBuilder()
        files = []

        if avatars:
            for i, (avatar_bin, avatar_ext,
                    timestamp) in enumerate(avatars, 1):
                time_since = fancy_timedelta(timestamp)
                content.writeln(f"**{i}.** set {time_since} ago")
                files.append(
                    discord.File(avatar_bin,
                                 filename=f"avatar {time_since}.{avatar_ext}"))
            embed.add_field(name="Past avatars", value=str(content))
            content.clear()

        if usernames:
            for username, timestamp in usernames:
                content.writeln(
                    f"- `{username}` set {fancy_timedelta(timestamp)} ago")
            embed.add_field(name="Past usernames", value=str(content))
            content.clear()

        if nicknames:
            for nickname, timestamp in nicknames:
                content.writeln(
                    f"- `{nickname}` set {fancy_timedelta(timestamp)} ago")
            embed.add_field(name="Past nicknames", value=str(content))
            content.clear()

        if alt_user_ids:
            for alt_user_id in alt_user_ids:
                content.writeln(f"<@!{alt_user_id}>")
            embed.add_field(name="Possible alts", value=str(content))

        await ctx.send(embed=embed)
        for i, file in enumerate(files, 1):
            await ctx.send(content=f"#{i}", file=file)