Esempio n. 1
0
    async def _send_stats(self, ctx, preamble):
        placings = 5
        database_key = f"race.scores:{ctx.channel.id}"
        if database.zcard(database_key) == 0:
            logger.info(f"no users in {database_key}")
            await ctx.send("There are no users in the database.")
            return

        if placings > database.zcard(database_key):
            placings = database.zcard(database_key)

        leaderboard_list = database.zrevrangebyscore(
            database_key, "+inf", "-inf", 0, placings, True
        )
        embed = discord.Embed(
            type="rich", colour=discord.Color.blurple(), title=preamble
        )
        embed.set_author(name="Bird ID - An Ornithology Bot")
        leaderboard = ""

        for i, stats in enumerate(leaderboard_list):
            if ctx.guild is not None:
                user = await fetch_get_user(int(stats[0]), ctx=ctx, member=True)
            else:
                user = None

            if user is None:
                user = await fetch_get_user(int(stats[0]), ctx=ctx, member=False)
                if user is None:
                    user_info = "**Deleted**"
                else:
                    user_info = f"**{esc(user.name)}#{user.discriminator}**"
            else:
                user_info = f"**{esc(user.name)}#{user.discriminator}** ({user.mention})"

            leaderboard += f"{i+1}. {user_info} - {int(stats[1])}\n"

        start = int(database.hget(f"race.data:{ctx.channel.id}", "start"))
        elapsed = str(datetime.timedelta(seconds=round(time.time()) - start))

        embed.add_field(
            name="Options", value=await self._get_options(ctx), inline=False
        )
        embed.add_field(
            name="Stats", value=f"**Race Duration:** `{elapsed}`", inline=False
        )
        embed.add_field(name="Leaderboard", value=leaderboard, inline=False)

        if ctx.author:
            if database.zscore(database_key, str(ctx.author.id)) is not None:
                placement = int(database.zrevrank(database_key, str(ctx.author.id))) + 1
                embed.add_field(
                    name="You:", value=f"You are #{placement}.", inline=False
                )
            else:
                embed.add_field(
                    name="You:", value="You haven't answered any correctly."
                )

        await ctx.send(embed=embed)
Esempio n. 2
0
    async def _send_stats(self, ctx, preamble):
        database_key = f"session.incorrect:{ctx.author.id}"

        embed = discord.Embed(type="rich",
                              colour=discord.Color.blurple(),
                              title=preamble)
        embed.set_author(name="Bird ID - An Ornithology Bot")

        if database.zcard(database_key) != 0:
            leaderboard_list = database.zrevrangebyscore(
                database_key, "+inf", "-inf", 0, 5, True)
            leaderboard = ""

            for i, stats in enumerate(leaderboard_list):
                leaderboard += (
                    f"{i+1}. **{stats[0].decode('utf-8')}** - {int(stats[1])}\n"
                )
        else:
            logger.info(f"no birds in {database_key}")
            leaderboard = "**There are no missed birds.**"

        embed.add_field(name="Options",
                        value=await self._get_options(ctx),
                        inline=False)
        embed.add_field(name="Stats",
                        value=await self._get_stats(ctx),
                        inline=False)
        embed.add_field(name="Top Missed Birds",
                        value=leaderboard,
                        inline=False)

        await ctx.send(embed=embed)
Esempio n. 3
0
 def generate_series(database_key):
     """Generates a pandas.Series from a Redis sorted set."""
     logger.info("generating series")
     data = database.zrevrangebyscore(database_key, "+inf", "-inf", withscores=True)
     return pd.Series(
         {e[0]: e[1] for e in map(lambda x: (x[0].decode("utf-8"), int(x[1])), data)}
     )
Esempio n. 4
0
async def send_leaderboard(ctx, title, page, database_key=None, data=None):
    logger.info("building/sending leaderboard")

    if database_key is None and data is None:
        raise GenericError("database_key and data are both NoneType", 990)
    if database_key is not None and data is not None:
        raise GenericError("database_key and data are both set", 990)

    if page < 1:
        page = 1

    entry_count = (
        int(database.zcard(database_key)) if database_key is not None else data.count()
    )
    page = (page * 10) - 10

    if entry_count == 0:
        logger.info(f"no items in {database_key}")
        await ctx.send("There are no items in the database.")
        return

    if page > entry_count:
        page = entry_count - (entry_count % 10)

    items_per_page = 10
    leaderboard_list = (
        map(
            lambda x: (x[0].decode("utf-8"), x[1]),
            database.zrevrangebyscore(
                database_key, "+inf", "-inf", page, items_per_page, True
            ),
        )
        if database_key is not None
        else data.iloc[page : page + items_per_page - 1].items()
    )
    embed = discord.Embed(type="rich", colour=discord.Color.blurple())
    embed.set_author(name="Bird ID - An Ornithology Bot")
    leaderboard = ""

    for i, stats in enumerate(leaderboard_list):
        leaderboard += f"{i+1+page}. **{stats[0]}** - {int(stats[1])}\n"
    embed.add_field(name=title, value=leaderboard, inline=False)

    await ctx.send(embed=embed)
Esempio n. 5
0
def evict_media():
    """Deletes media for items that have exceeded a certain frequency.

    This prevents media from becoming stale. If the item frequency has
    been incremented more than 2*COUNT times, this function will delete
    the top 3 items.
    """
    logger.info("Updating cached images")

    for item in map(
            lambda x: x.decode(),
            database.zrevrangebyscore(
                "frequency.media:global",
                "+inf",
                min=2 * COUNT,
                start=0,
                num=3,
            ),
    ):
        database.zadd("frequency.media:global", {item: 0})
        shutil.rmtree(f"bot_files/cache/{item}/")
        logger.info(f"{item} removed")
Esempio n. 6
0
    async def user_lb(self, ctx, title, page, database_key=None, data=None):
        if database_key is None and data is None:
            raise GenericError("database_key and data are both NoneType", 990)
        if database_key is not None and data is not None:
            raise GenericError("database_key and data are both set", 990)

        if page < 1:
            page = 1

        user_amount = (
            int(database.zcard(database_key))
            if database_key is not None
            else data.count()
        )
        page = (page * 10) - 10

        if user_amount == 0:
            logger.info(f"no users in {database_key}")
            await ctx.send("There are no users in the database.")
            return

        if page >= user_amount:
            page = user_amount - (user_amount % 10 if user_amount % 10 != 0 else 10)

        users_per_page = 10
        leaderboard_list = (
            database.zrevrangebyscore(
                database_key, "+inf", "-inf", page, users_per_page, True
            )
            if database_key is not None
            else data.iloc[page : page + users_per_page - 1].items()
        )

        embed = discord.Embed(type="rich", colour=discord.Color.blurple())
        embed.set_author(name="Bird ID - An Ornithology Bot")
        leaderboard = ""

        for i, stats in enumerate(leaderboard_list):
            if ctx.guild is not None:
                user = ctx.guild.get_member(int(stats[0]))
            else:
                user = None

            if user is None:
                user = self.bot.get_user(int(stats[0]))
                if user is None:
                    user = "******"
                else:
                    user = f"**{user.name}#{user.discriminator}**"
            else:
                user = f"**{user.name}#{user.discriminator}** ({user.mention})"

            leaderboard += f"{i+1+page}. {user} - {int(stats[1])}\n"

        embed.add_field(name=title, value=leaderboard, inline=False)

        user_score = (
            database.zscore(database_key, str(ctx.author.id))
            if database_key is not None
            else data.get(str(ctx.author.id))
        )

        if user_score is not None:
            if database_key is not None:
                placement = int(database.zrevrank(database_key, str(ctx.author.id))) + 1
                distance = int(
                    database.zrevrange(
                        database_key, placement - 2, placement - 2, True
                    )[0][1]
                ) - int(user_score)
            else:
                placement = int(data.rank(ascending=False)[str(ctx.author.id)])
                distance = int(data.iloc[placement - 2] - user_score)

            if placement == 1:
                embed.add_field(
                    name="You:",
                    value=f"You are #{placement} on the leaderboard.\nYou are in first place.",
                    inline=False,
                )
            elif distance == 0:
                embed.add_field(
                    name="You:",
                    value=f"You are #{placement} on the leaderboard.\nYou are tied with #{placement-1}",
                    inline=False,
                )
            else:
                embed.add_field(
                    name="You:",
                    value=f"You are #{placement} on the leaderboard.\nYou are {distance} away from #{placement-1}",
                    inline=False,
                )
        else:
            embed.add_field(name="You:", value="You haven't answered any correctly.")

        await ctx.send(embed=embed)