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)
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)
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)} )
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)
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")
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)