async def point_distribute(self, confirmed_cases): log(f"Starting COVID points distribution", "COVID") lb_messages = [] rank = 1 guessers = SQLFunctions.get_covid_guessers(self.conn, guessed=True) for g in guessers: g.TempPoints = int(calculate_points(confirmed_cases, g.NextGuess)) # Sort the guessers by their gotten points guessers.sort(key=lambda x: x.TempPoints, reverse=True) for g in guessers: msg = f"**{rank}:** <@{g.member.DiscordUserID}> got {g.TempPoints} points *(guess: {g.NextGuess})*" rank += 1 lb_messages.append(msg) SQLFunctions.clear_covid_guesses(users=guessers, increment=True, conn=self.conn) return lb_messages
async def guess(self, ctx, number=None, confirmed_number=None): """ Daily covid cases guessing game. You guess how many covid cases will be reported by the BAG and depending \ on how close you are, you get more points. `$guess avg` to get a leaderboard with average guessing scores `$guess lb` to get the total leaderboard with all points Leaderboard aliases: `leaderboard`, `lb`, `top`, `best`, `ranking` Average aliases: `avg`, `average` """ leaderboard_aliases = ["leaderboard", "lb", "top", "best", "ranking"] average_aliases = ["avg", "average"] await ctx.message.delete() if number is None: # No values were given in the command: guesser = SQLFunctions.get_covid_guessers( self.conn, discord_user_id=ctx.message.author.id, guild_id=ctx.message.guild.id) if len(guesser) == 0: await ctx.send( f"{ctx.message.author.mention}, you have not made any guesses yet. Guess with `$guess <integer>`.", delete_after=7) return async with ctx.typing(): guesser = guesser[0] image_url = str(ctx.message.author.avatar_url_as(format="png")) try: async with aiohttp.ClientSession() as cs: async with cs.get(image_url) as r: buffer = io.BytesIO(await r.read()) color_thief = ColorThief(buffer) dominant_color = color_thief.get_palette(color_count=2, quality=10)[0] hex_color = int('0x%02x%02x%02x' % dominant_color, 0) except UnidentifiedImageError as e: hex_color = 0x808080 already_guessed = "<:xmark:776717315139698720>" if guesser.NextGuess is not None: already_guessed = "<:checkmark:776717335242211329>" embed = discord.Embed( title="Covid Guesser Profile", description=f"**User:** <@{ctx.message.author.id}>\n" f"**Total Points:** `{guesser.TotalPointsAmount}`\n" f"**Total Guesses:** `{guesser.GuessCount}`\n" f"**Average:** `{round(guesser.average, 2)}`\n" f"**Guessed:** {already_guessed}", color=hex_color) embed.set_thumbnail(url=image_url) await ctx.send(embed=embed, delete_after=15) else: try: if number.lower( ) == "confirm" and ctx.author.guild_permissions.kick_members: # if the number of cases gets confirmed if confirmed_number is None: raise ValueError self.confirmed_cases = int(confirmed_number) if self.confirm_msg is not None: # Deletes the previous confirm message if there are multiple await self.confirm_msg.delete() self.confirm_msg = None self.confirm_msg = await ctx.send( f"Confirmed cases: {self.confirmed_cases}\nA mod or higher, press the <:checkmark:769279808244809798> to verify." ) await self.confirm_msg.add_reaction( "<:checkmark:776717335242211329>") await self.confirm_msg.add_reaction( "<:xmark:776717315139698720>") elif number.lower() in leaderboard_aliases: await self.send_leaderboard(ctx) elif number.lower() in average_aliases: await self.send_leaderboard(ctx, True) else: number = int(number) if number < 0: raise ValueError if number > 1000000: number = 1000000 member = SQLFunctions.get_or_create_discord_member( ctx.message.author, conn=self.conn) SQLFunctions.insert_or_update_covid_guess(member, number, conn=self.conn) await ctx.send( f"{ctx.message.author.mention}, received your guess.", delete_after=7) except ValueError: await ctx.send( f"{ctx.message.author.mention}, no proper positive integer given.", delete_after=7) raise discord.ext.commands.errors.BadArgument
async def send_leaderboard(self, ctx, average=False): async with ctx.typing(): try: """ Creates a list with sorted dicts """ guessers = SQLFunctions.get_covid_guessers(self.conn) if average: title = "Average" max_count = 0 # gets the max guess count of the server for g in guessers: max_count = max(g.GuessCount, max_count) for g in guessers: # We assign the weighted average to the TempPoints variable # for every guess less than the max your weighted average goes down by 2 g.TempPoints = g.average - (max_count - g.GuessCount) * 2 guessers.sort(key=lambda x: x.TempPoints, reverse=True) else: title = "'rona" guessers.sort(key=lambda x: x.TotalPointsAmount, reverse=True) """ Creates the message content """ i = 1 cont = "" for g in guessers: if i == 1: cont += "<:gold:413030003639582731>" elif i == 2: cont += "<:silver:413030018881552384>" elif i == 3: cont += "<:bronze:413030030076149776>" else: cont += "<:invisible:413030446327267328>" if average: # Show users with the best weighted average cont += f"**{i}.** <@{g.member.DiscordUserID}> | AVG Points: **{round(g.average, 2)}** *({round(g.TempPoints, 2)})*\n\n" else: # Show users with the most points cont += f"**{i}.** <@{g.member.DiscordUserID}> | Points: {g.TotalPointsAmount}\n\n" i += 1 if i >= 11: break guild_name = ctx.message.guild.name embed = discord.Embed( title= f"Top {title} Guessers: **{guild_name}** <:coronavirus:767839970303410247>", description=cont, color=0x00FF00) if average: embed.set_footer( text= "Ordered by decay (value to the right). Left is actual average." ) except KeyError: embed = discord.Embed( title=f"Error", description="There are no covid guessing points yet", color=0xFF0000) await ctx.send(embed=embed)