Exemple #1
0
def ongoing_rounds_embed(data):
    content = []

    for round in data:
        try:
            ranklist = updation.round_score(list(map(int, round.users.split())), list(map(int, round.status.split())),
                                            list(map(int, round.times.split())))
            msg = ' vs '.join([f"[{db.get_handle(round.guild, user.id)}](https://codeforces.com/profile/{db.get_handle(round.guild, user.id)}) `Rank {user.rank}` `{user.points} Points`"
                               for user in ranklist])
            msg += f"\n**Problem ratings:** {round.rating}"
            msg += f"\n**Score distribution** {round.points}"
            msg += f"\n**Time left:** {timeez(60*round.duration + round.time - int(time.time()))}\n\n"
            content.append(msg)
        except Exception:
            pass

    return content
Exemple #2
0
def round_problems_embed(round_info):
    ranklist = round_score(list(map(int, round_info.users.split())), list(map(int, round_info.status.split())), list(map(int, round_info.times.split())))

    problems = round_info.problems.split()
    names = [f"[{db.get_problems(problems[i])[0].name}](https://codeforces.com/contest/{problems[i].split('/')[0]}"
             f"/problem/{problems[i].split('/')[1]})" if problems[i] != '0' else "This problem has been solved" if
             round_info.repeat == 0 else "No problems of this rating left" for i in range(len(problems))]

    desc = ""
    for user in ranklist:
        emojis = [":first_place:", ":second_place:", ":third_place:"]
        handle = db.get_handle(round_info.guild, user.id)
        desc += f"{emojis[user.rank-1] if user.rank <= len(emojis) else user.rank} [{handle}](https://codeforces.com/profile/{handle}) **{user.points}** points\n"

    embed = discord.Embed(description=desc, color=discord.Color.magenta())
    embed.set_author(name=f"Problems")

    embed.add_field(name="Points", value='\n'.join(round_info.points.split()), inline=True)
    embed.add_field(name="Problem Name", value='\n'.join(names), inline=True)
    embed.add_field(name="Rating", value='\n'.join(round_info.rating.split()), inline=True)
    embed.set_footer(text=f"Time left: {timeez((round_info.time + 60 * round_info.duration) - int(time.time()))}")

    return embed
Exemple #3
0
async def update_rounds(client):
    rounds = db.get_all_rounds()
    global api
    if api is None:
        api = challonge_api.ChallongeAPI(client)
    for round in rounds:
        try:
            guild = client.get_guild(round.guild)
            resp = await updation.update_round(round)
            if not resp[0]:
                logging_channel = await client.fetch_channel(
                    os.environ.get("LOGGING_CHANNEL"))
                await logging_channel.send(
                    f"Error while updating rounds: {resp[1]}")
                continue
            resp = resp[1]
            channel = client.get_channel(round.channel)

            if resp[2] or resp[1]:
                await channel.send(
                    f"{' '.join([(await guild.fetch_member(int(m))).mention for m in round.users.split()])} there is an update in standings"
                )

            for i in range(len(resp[0])):
                if len(resp[0][i]):
                    await channel.send(embed=discord.Embed(
                        description=
                        f"{' '.join([(await guild.fetch_member(m)).mention for m in resp[0][i]])} has solved problem worth **{round.points.split()[i]}** points",
                        color=discord.Color.blue()))

            if not resp[1] and resp[2]:
                new_info = db.get_round_info(round.guild, round.users)
                await channel.send(
                    embed=discord_.round_problems_embed(new_info))

            if resp[1]:
                round_info = db.get_round_info(round.guild, round.users)
                ranklist = updation.round_score(
                    list(map(int, round_info.users.split())),
                    list(map(int, round_info.status.split())),
                    list(map(int, round_info.times.split())))
                eloChanges = elo.calculateChanges([[
                    (await guild.fetch_member(user.id)), user.rank,
                    db.get_match_rating(round_info.guild, user.id)[-1]
                ] for user in ranklist])

                for id in list(map(int, round_info.users.split())):
                    db.add_rating_update(round_info.guild, id,
                                         eloChanges[id][0])

                db.delete_round(round_info.guild, round_info.users)
                db.add_to_finished_rounds(round_info)

                embed = discord.Embed(color=discord.Color.dark_magenta())
                pos, name, ratingChange = '', '', ''
                for user in ranklist:
                    handle = db.get_handle(round_info.guild, user.id)
                    emojis = [
                        ":first_place:", ":second_place:", ":third_place:"
                    ]
                    pos += f"{emojis[user.rank - 1] if user.rank <= len(emojis) else str(user.rank)} **{user.points}**\n"
                    name += f"[{handle}](https://codeforces.com/profile/{handle})\n"
                    ratingChange += f"{eloChanges[user.id][0]} (**{'+' if eloChanges[user.id][1] >= 0 else ''}{eloChanges[user.id][1]}**)\n"
                embed.add_field(name="Position", value=pos)
                embed.add_field(name="User", value=name)
                embed.add_field(name="Rating changes", value=ratingChange)
                embed.set_author(name=f"Round over! Final standings")
                await channel.send(embed=embed)

                if round_info.tournament == 1:
                    tournament_info = db.get_tournament_info(round_info.guild)
                    if not tournament_info or tournament_info.status != 2:
                        continue
                    if ranklist[1].rank == 1 and tournament_info.type != 2:
                        await discord_.send_message(
                            channel,
                            "Since the round ended in a draw, you will have to compete again for it to be counted in the tournament"
                        )
                    else:
                        res = await tournament_helper.validate_match(
                            round_info.guild, ranklist[0].id, ranklist[1].id,
                            api, db)
                        if not res[0]:
                            await discord_.send_message(
                                channel, res[1] +
                                "\n\nIf you think this is a mistake, type `.tournament forcewin <handle>` to grant victory to a user"
                            )
                        else:
                            draw = True if ranklist[1].rank == 1 else False
                            scores = f"{ranklist[0].points}-{ranklist[1].points}" if res[
                                1]['player1'] == res[1][
                                    ranklist[0].
                                    id] else f"{ranklist[1].points}-{ranklist[0].points}"
                            match_resp = await api.post_match_results(
                                res[1]['tournament_id'], res[1]['match_id'],
                                scores,
                                res[1][ranklist[0].id] if not draw else "tie")
                            if not match_resp or 'errors' in match_resp:
                                await discord_.send_message(
                                    channel,
                                    "Some error occurred while validating tournament match. \n\nType `.tournament forcewin <handle>` to grant victory to a user manually"
                                )
                                if match_resp and 'errors' in match_resp:
                                    logging_channel = await client.fetch_channel(
                                        os.environ.get("LOGGING_CHANNEL"))
                                    await logging_channel.send(
                                        f"Error while validating tournament rounds: {match_resp['errors']}"
                                    )
                                continue
                            winner_handle = db.get_handle(
                                round_info.guild, ranklist[0].id)
                            await discord_.send_message(
                                channel,
                                f"{f'Congrats **{winner_handle}** for qualifying to the next round. :tada:' if not draw else 'The round ended in a draw!'}\n\nTo view the list of future tournament rounds, type `.tournament matches`"
                            )
                            if await tournament_helper.validate_tournament_completion(
                                    round_info.guild, api, db):
                                await api.finish_tournament(
                                    res[1]['tournament_id'])
                                await asyncio.sleep(3)
                                winner_handle = await tournament_helper.get_winner(
                                    res[1]['tournament_id'], api)
                                await channel.send(
                                    embed=tournament_helper.
                                    tournament_over_embed(
                                        round_info.guild, winner_handle, db))
                                db.add_to_finished_tournaments(
                                    db.get_tournament_info(round_info.guild),
                                    winner_handle)
                                db.delete_tournament(round_info.guild)

        except Exception as e:
            logging_channel = await client.fetch_channel(
                os.environ.get("LOGGING_CHANNEL"))
            await logging_channel.send(
                f"Error while updating rounds: {str(traceback.format_exc())}")