def _make_contest_embed_for_ranklist(ranklist): contest = ranklist.contest assert contest.phase != 'BEFORE', f'Contest {contest.id} has not started.' embed = discord_common.cf_color_embed(title=contest.name, url=contest.url) phase = contest.phase.capitalize().replace('_', ' ') embed.add_field(name='Phase', value=phase) if ranklist.is_rated: embed.add_field(name='Deltas', value=ranklist.deltas_status) now = time.time() en = '\N{EN SPACE}' if contest.phase == 'CODING': elapsed = cf_common.pretty_time_format(now - contest.startTimeSeconds, shorten=True) remaining = cf_common.pretty_time_format(contest.end_time - now, shorten=True) msg = f'{elapsed} elapsed{en}|{en}{remaining} remaining' embed.add_field(name='Tick tock', value=msg, inline=False) else: start = _contest_start_time_format(contest, dt.timezone.utc) duration = _contest_duration_format(contest) since = cf_common.pretty_time_format(now - contest.end_time, only_most_significant=True) msg = f'{start}{en}|{en}{duration}{en}|{en}Ended {since} ago' embed.add_field(name='When', value=msg, inline=False) return embed
def _make_contest_embed_for_ranklist(ranklist): contest = ranklist.contest assert (contest.phase != "BEFORE"), f"Contest {contest.id} has not started." embed = discord_common.cf_color_embed(title=contest.name, url=contest.url) phase = contest.phase.capitalize().replace("_", " ") embed.add_field(name="Phase", value=phase) if ranklist.is_rated: embed.add_field(name="Deltas", value=ranklist.deltas_status) now = time.time() en = "\N{EN SPACE}" if contest.phase == "CODING": elapsed = cf_common.pretty_time_format(now - contest.startTimeSeconds, shorten=True) remaining = cf_common.pretty_time_format(contest.end_time - now, shorten=True) msg = f"{elapsed} elapsed{en}|{en}{remaining} remaining" embed.add_field(name="Tick tock", value=msg, inline=False) else: start = _contest_start_time_format(contest, dt.timezone.utc) duration = _contest_duration_format(contest) since = cf_common.pretty_time_format(now - contest.end_time, only_most_significant=True) msg = f"{start}{en}|{en}{duration}{en}|{en}Ended {since} ago" embed.add_field(name="When", value=msg, inline=False) return embed
def _make_contest_embed_for_vc_ranklist(ranklist, vc_start_time=None, vc_end_time=None): contest = ranklist.contest embed = discord_common.cf_color_embed(title=contest.name, url=contest.url) embed.set_author(name='VC Standings') now = time.time() if vc_start_time and vc_end_time: en = '\N{EN SPACE}' elapsed = cf_common.pretty_time_format(now - vc_start_time, shorten=True) remaining = cf_common.pretty_time_format(max(0,vc_end_time - now), shorten=True) msg = f'{elapsed} elapsed{en}|{en}{remaining} remaining' embed.add_field(name='Tick tock', value=msg, inline=False) return embed
async def gotgud(self, ctx): (handle, ) = await cf_common.resolve_handles(ctx, self.converter, ("!" + str(ctx.author), )) user_id = ctx.message.author.id active = cf_common.user_db.check_challenge(user_id) if not active: await ctx.send(f"You do not have an active challenge") return submissions = await cf.user.status(handle=handle) solved = { sub.problem.name for sub in submissions if sub.verdict == "OK" } challenge_id, issue_time, name, contestId, index, delta = active if not name in solved: await ctx.send("You haven't completed your challenge.") return delta = _GITGUD_SCORE_DISTRIB[delta // 100 + 3] finish_time = int(datetime.datetime.now().timestamp()) rc = cf_common.user_db.complete_challenge(user_id, challenge_id, finish_time, delta) if rc == 1: duration = cf_common.pretty_time_format(finish_time - issue_time) await ctx.send( f"Challenge completed in {duration}. {handle} gained {delta} points." ) else: await ctx.send("You have already claimed your points")
async def draw(self, ctx): active = cf_common.user_db.check_duel_draw(ctx.author.id) if not active: raise DuelCogError(f'{ctx.author.mention}, you are not in a duel.') duelid, challenger_id, challengee_id, start_time, dtype = active now = datetime.datetime.now().timestamp() if now - start_time < _DUEL_NO_DRAW_TIME: draw_time = cf_common.pretty_time_format(start_time + _DUEL_NO_DRAW_TIME - now) await ctx.send( f'Think more {ctx.author.mention}. You can offer a draw in {draw_time}.' ) return if not duelid in self.draw_offers: self.draw_offers[duelid] = ctx.author.id offeree_id = challenger_id if ctx.author.id != challenger_id else challengee_id offeree = ctx.guild.get_member(offeree_id) await ctx.send( f'{ctx.author.mention} is offering a draw to {offeree.mention}!' ) return if self.draw_offers[duelid] == ctx.author.id: await ctx.send( f'{ctx.author.mention}, you\'ve already offered a draw.') return offerer = ctx.guild.get_member(self.draw_offers[duelid]) embed = complete_duel(duelid, ctx.guild.id, Winner.DRAW, offerer, ctx.author, now, 0.5, dtype) await ctx.send( f'{ctx.author.mention} accepted draw offer by {offerer.mention}.', embed=embed)
def make_line(entry): ( duelid, start_time, finish_time, name, challenger, challengee, winner, ) = entry duel_time = cf_common.pretty_time_format(finish_time - start_time, shorten=True, always_seconds=True) problem = cf_common.cache2.problem_cache.problem_by_name[name] when = cf_common.days_ago(start_time) idstr = f"{duelid}: " if winner != Winner.DRAW: loser = get_cf_user( challenger if winner == Winner.CHALLENGEE else challengee, guild_id, ) winner = get_cf_user( challenger if winner == Winner.CHALLENGER else challengee, guild_id, ) return f"{idstr if show_id else str()}[{name}]({problem.url}) [{problem.rating}] won by [{winner.handle}]({winner.url}) vs [{loser.handle}]({loser.url}) {when} in {duel_time}" else: challenger = get_cf_user(challenger, guild_id) challengee = get_cf_user(challengee, guild_id) return f"{idstr if show_id else str()}[{name}]({problem.url}) [{problem.rating}] drawn by [{challenger.handle}]({challenger.url}) and [{challengee.handle}]({challengee.url}) {when} after {duel_time}"
async def gotgud(self, ctx): handle, = await cf_common.resolve_handles(ctx, self.converter, ('!' + str(ctx.author), )) user_id = ctx.message.author.id active = cf_common.user_db.check_challenge(user_id) if not active: await ctx.send(f'You do not have an active challenge') return submissions = await cf.user.status(handle=handle) solved = { sub.problem.name for sub in submissions if sub.verdict == 'OK' } challenge_id, issue_time, name, contestId, index, delta = active if not name in solved: await ctx.send('You haven\'t completed your challenge.') return score_distrib = [2, 3, 5, 8, 12, 17, 23] delta = score_distrib[delta // 100 + 3] finish_time = int(datetime.datetime.now().timestamp()) rc = cf_common.user_db.complete_challenge(user_id, challenge_id, finish_time, delta) if rc == 1: duration = cf_common.pretty_time_format(finish_time - issue_time) await ctx.send( f'Challenge completed in {duration}. {handle} gained {delta} points.' ) else: await ctx.send('You have already claimed your points')
def make_line(entry): start_time, name, challenger, challengee = entry problem = cf_common.cache2.problem_cache.problem_by_name[name] now = datetime.datetime.now().timestamp() when = cf_common.pretty_time_format(now - start_time, shorten=True, always_seconds=True) challenger = get_cf_user(challenger, ctx.guild.id) challengee = get_cf_user(challengee, ctx.guild.id) return f'[{challenger.handle}]({challenger.url}) vs [{challengee.handle}]({challengee.url}): [{name}]({problem.url}) [{problem.rating}] {when}'
def duel_to_string(duel): start_time, finish_time, problem_name, challenger, challengee = duel duel_time = cf_common.pretty_time_format(finish_time - start_time, shorten=True, always_seconds=True) when = cf_common.days_ago(start_time) loser_id = challenger if member.id != challenger else challengee loser = get_cf_user(loser_id, ctx.guild.id) problem = cf_common.cache2.problem_cache.problem_by_name[problem_name] return f'**[{problem.name}]({problem.url})** [{problem.rating}] versus [{loser.handle}]({loser.url}) {when} in {duel_time}'
async def complete(self, ctx): active = cf_common.user_db.check_duel_complete(ctx.author.id) if not active: raise DuelCogError(f'{ctx.author.mention}, you are not in a duel.') duelid, challenger_id, challengee_id, start_time, problem_name, contest_id, index, dtype = active UNSOLVED = 0 TESTING = -1 async def get_solve_time(userid): handle = cf_common.user_db.get_handle(userid, ctx.guild.id) subs = [sub for sub in await cf.user.status(handle=handle) if (sub.verdict == 'OK' or sub.verdict == 'TESTING') and sub.problem.contestId == contest_id and sub.problem.index == index] if not subs: return UNSOLVED if 'TESTING' in [sub.verdict for sub in subs]: return TESTING return min(subs, key=lambda sub: sub.creationTimeSeconds).creationTimeSeconds challenger_time = await get_solve_time(challenger_id) challengee_time = await get_solve_time(challengee_id) if challenger_time == TESTING or challengee_time == TESTING: await ctx.send(f'Wait a bit, {ctx.author.mention}. A submission is still being judged.') return challenger = ctx.guild.get_member(challenger_id) challengee = ctx.guild.get_member(challengee_id) if challenger_time and challengee_time: if challenger_time != challengee_time: diff = cf_common.pretty_time_format(abs(challengee_time - challenger_time), always_seconds=True) winner = challenger if challenger_time < challengee_time else challengee loser = challenger if challenger_time > challengee_time else challengee win_status = Winner.CHALLENGER if winner == challenger else Winner.CHALLENGEE embed = complete_duel(duelid, ctx.guild.id, win_status, winner, loser, min(challenger_time, challengee_time), 1, dtype) await ctx.send(f'Both {challenger.mention} and {challengee.mention} solved it but {winner.mention} was {diff} faster!', embed=embed) else: embed = complete_duel(duelid, ctx.guild.id, Winner.DRAW, challenger, challengee, challenger_time, 0.5, dtype) await ctx.send(f"{challenger.mention} and {challengee.mention} solved the problem in the exact same amount of time! It's a draw!", embed=embed) elif challenger_time: embed = complete_duel(duelid, ctx.guild.id, Winner.CHALLENGER, challenger, challengee, challenger_time, 1, dtype) await ctx.send(f'{challenger.mention} beat {challengee.mention} in a duel!', embed=embed) elif challengee_time: embed = complete_duel(duelid, ctx.guild.id, Winner.CHALLENGEE, challengee, challenger, challengee_time, 1, dtype) await ctx.send(f'{challengee.mention} beat {challenger.mention} in a duel!', embed=embed) else: await ctx.send('Nobody solved the problem yet.')
async def nogud(self, ctx): await cf_common.resolve_handles(ctx, self.converter, ('!' + str(ctx.author),)) user_id = ctx.message.author.id active = cf_common.user_db.check_challenge(user_id) if not active: await ctx.send(f'You do not have an active challenge') return challenge_id, issue_time, name, contestId, index, delta = active finish_time = int(datetime.datetime.now().timestamp()) if finish_time - issue_time < _GITGUD_NO_SKIP_TIME: skip_time = cf_common.pretty_time_format(issue_time + _GITGUD_NO_SKIP_TIME - finish_time) await ctx.send(f'Think more. You can skip your challenge in {skip_time}.') return cf_common.user_db.skip_challenge(user_id, challenge_id, Gitgud.NOGUD) await ctx.send(f'Challenge skipped.')
async def uptime(self, ctx): """Replies with how long TLE has been up.""" await ctx.send('TLE has been running for ' + pretty_time_format(time.time() - self.start_time))
async def complete(self, ctx): """Record your win and move on to the next opponent!""" status = cf_common.user_db.get_tour_status() if status == 0: raise DuelCogError(f"Tournament is not going on :/") active = cf_common.user_db.check_match_complete(ctx.author.id) if not active: raise DuelCogError(f"{ctx.author.mention}, you are not in a duel.") ( duelid, challenger_id, challengee_id, start_time, problem_name, contest_id, index, dtype, ) = active UNSOLVED = 0 TESTING = -1 async def get_solve_time(userid): handle = cf_common.user_db.get_handle(userid, ctx.guild.id) subs = [ sub for sub in await cf.user.status(handle=handle) if (sub.verdict == "OK" or sub.verdict == "TESTING") and sub. problem.contestId == contest_id and sub.problem.index == index ] if not subs: return UNSOLVED if "TESTING" in [sub.verdict for sub in subs]: return TESTING return min( subs, key=lambda sub: sub.creationTimeSeconds).creationTimeSeconds challenger_time = await get_solve_time(challenger_id) challengee_time = await get_solve_time(challengee_id) if challenger_time == TESTING or challengee_time == TESTING: await ctx.send( f"Wait a bit, {ctx.author.mention}. A submission is still being judged." ) return challenger = ctx.guild.get_member(challenger_id) challengee = ctx.guild.get_member(challengee_id) if challenger_time and challengee_time: if challenger_time != challengee_time: diff = cf_common.pretty_time_format(abs(challengee_time - challenger_time), always_seconds=True) winner = (challenger if challenger_time < challengee_time else challengee) loser = (challenger if challenger_time > challengee_time else challengee) win_status = (Winner.CHALLENGER if winner == challenger else Winner.CHALLENGEE) await complete_duel( duelid, ctx.guild.id, win_status, winner, loser, min(challenger_time, challengee_time), 1, dtype, ) await ctx.send( f"Both {challenger.mention} and {challengee.mention} solved it but {winner.mention} was {diff} faster!" ) else: await complete_duel( duelid, ctx.guild.id, Winner.DRAW, challenger, challengee, challenger_time, 0.5, dtype, ) await ctx.send( f"{challenger.mention} and {challengee.mention} solved the problem in the exact same amount of time! It's a draw!" ) elif challenger_time: await complete_duel( duelid, ctx.guild.id, Winner.CHALLENGER, challenger, challengee, challenger_time, 1, dtype, ) await ctx.send( f"{challenger.mention} beat {challengee.mention} in a duel!") elif challengee_time: await complete_duel( duelid, ctx.guild.id, Winner.CHALLENGEE, challengee, challenger, challengee_time, 1, dtype, ) await ctx.send( f"{challengee.mention} beat {challenger.mention} in a duel!") else: await ctx.send("Nobody solved the problem yet.")