async def gitgud(ctx: lightbulb.Context) -> None: # TODO Fix converters for slash commands points = ctx.options.points filters = ctx.options.filters query = Query() gitgud_util = Gitgud_utils() # get the user's dmoj handle username = query.get_handle(ctx.author.id, ctx.get_guild().id) # user = await query.get_user(username) if username is None: return await ctx.respond("You are not linked to a DMOJ Account. " "Please link your account before continuing") user = await query.get_user(username) if points is None: points = [0, 0] closest = -1000 for key in RATING_TO_POINT: if abs(key - user.rating) <= abs(closest - user.rating): closest = key points[0] = RATING_TO_POINT[closest] points[1] = points[0] # return if the user haven't finished the previous problem current = gitgud_util.get_current(username, ctx.get_guild().id) if current is not None and current.problem_id is not None: if not gitgud_util.has_solved(username, current.problem_id): # User has a current problem unsolved problem = await query.get_problem(current.problem_id) embed = hikari.Embed( description=f"You currently have an uncompleted " f"challenge, [{problem.name}]" f"(https://dmoj.ca/problem/{problem.code})", color=0xFCDB05, ) return await ctx.respond(embed=embed) filter_list = [] for filter in filters: if filter in SHORTHANDS: filter_list.append(SHORTHANDS[filter]) filters = filter_list embed, problem = await gimme_common(username, points, filters) if embed is None: return await ctx.respond("No problems that satisfies the filter") gitgud_util.bind(username, ctx.get_guild().id, problem.code, problem.points, datetime.now()) embed.description = "Points: %s\nProblem Types ||%s||" % (problem.points, ", ".join(problem.types)) return await ctx.respond(embed=embed)
async def gitlog(self, ctx, username=None): """ Show the past gitgud history of a user """ query = Query() username = username or query.get_handle(ctx.author.id, ctx.guild.id) try: user = await query.get_user(username) username = user.username except TypeError: username = None if username is None: return await ctx.send("You have not entered a valid DMOJ handle or linked with a DMOJ Account") gitgud_util = Gitgud_utils() history = gitgud_util.get_all(username, ctx.guild.id) if len(history) == 0: embed = discord.Embed(description="User have not completed any challenge") return await ctx.send(embed=embed) # paginate count = 0 page_cnt = min(10, len(history)//10 + bool(len(history)%10)) embeds = [] content = "" paginator = Pagination.CustomEmbedPaginator(ctx, timeout=60, remove_reactions=True) paginator.add_reaction('⏮️', "first") paginator.add_reaction('⏪', "back") paginator.add_reaction('⏩', "next") paginator.add_reaction('⏭️', "last") for solved in history: # print(solved.problem_id) problem = await query.get_problem(solved.problem_id) days = (datetime.now() - solved.time).days if days==0: days_str = "today" elif days==1: days_str = "yesterday" else: days_str = f"{days} days ago" content += f"[{problem.name}](https://dmoj.ca/{problem.code}) [+{solved.point}] ({days_str})\n" count += 1 if count % 10 == 0: embed = discord.Embed() embed.add_field(name=f"Gitgud Log for {username} (page {count//10}/{page_cnt})", value=content, inline=True) embeds.append(embed) content = "" if count == 100: break if count % 10 != 0: embed = discord.Embed() embed.add_field(name=f"Gitlog for {username} (page {count//10 + 1}/{page_cnt})", value=content, inline=True) embeds.append(embed) return await paginator.run(embeds)
async def nogud(ctx): query = Query() gitgud_util = Gitgud_utils() username = query.get_handle(ctx.author.id, ctx.get_guild().id) if username is None: return await ctx.respond("You do not have a linked DMOJ account") current = gitgud_util.get_current(username, ctx.get_guild().id) if current is None or current.problem_id is None: return await ctx.respond("Nothing to cancel") gitgud_util.clear(username, ctx.get_guild().id) return await ctx.respond("Challenge skipped")
async def gitlog(ctx): """ Show the past gitgud history of a user """ query = Query() username = ctx.options.username username = username or query.get_handle(ctx.author.id, ctx.get_guild().id) try: user = await query.get_user(username) username = user.username except TypeError: username = None if username is None: return await ctx.respond("You have not entered a valid DMOJ handle " "or linked with a DMOJ Account") gitgud_util = Gitgud_utils() history = gitgud_util.get_all(username, ctx.get_guild().id) if len(history) == 0: embed = hikari.Embed(description="User have not completed any " "challenge") return await ctx.respond(embed=embed) # paginate pag = lightbulb.utils.EmbedPaginator() for idx, solved in enumerate(history): # problem = solved.problem_id or await query.get_problem(solved.problem_id) problem = await query.get_problem(solved.problem_id) days = (datetime.now() - solved.time).days if days == 0: days_str = "today" elif days == 1: days_str = "yesterday" else: days_str = f"{days} days ago" pag.add_line(f"[{problem.name}](https://dmoj.ca/problem/{problem.code}) " f"[+{solved.point}] ({days_str})") if idx == 100: break @pag.embed_factory() def build_embed(page_index, content): return hikari.Embed(color=0xFCDB05,).add_field( name=f"Gitgud Log for {username} " f"(page {page_index})", # Can't put total length :/ value=content, inline=True, ) navigator = nav.ButtonNavigator(pag.build_pages()) await navigator.run(ctx)
async def gotgud(ctx): query = Query() gitgud_util = Gitgud_utils() username = query.get_handle(ctx.author.id, ctx.get_guild().id) if username is None: return await ctx.respond("You are not linked with a DMOJ Account") user = await query.get_user(username) current = gitgud_util.get_current(username, ctx.get_guild().id) closest = -1000 for key in RATING_TO_POINT: if abs(key - user.rating) <= abs(closest - user.rating): closest = key # convert rating to point and get difference rating_point = RATING_TO_POINT[closest] if current is None or current.problem_id is None: return await ctx.respond("No pending challenges") # check if user is scamming the bot :monkey: if gitgud_util.has_solved(username, current.problem_id): # get closest rating closest = -1000 for key in RATING_TO_POINT: if abs(key - user.rating) <= abs(closest - user.rating): closest = key # convert rating to point and get difference rating_point = RATING_TO_POINT[closest] point_diff = POINT_VALUES.index(current.point) - POINT_VALUES.index(rating_point) point = 10 + 2 * (point_diff) point = max(point, 0) gitgud_util.insert(username, ctx.get_guild().id, point, current.problem_id, datetime.now()) gitgud_util.clear(username, ctx.get_guild().id) completion_time = datetime.now() - current.time # convert from timedelta to readable string ret = "" cnt = 0 if completion_time.days // 365 != 0: ret += f" {completion_time.days // 365} years" cnt += 1 if completion_time.days % 365 != 0: ret += f" {completion_time.days % 365} days" cnt += 1 if completion_time.seconds // 3600 != 0: ret += f" {completion_time.seconds // 3600} hours" cnt += 1 if cnt < 3 and completion_time.seconds % 3600 // 60 != 0: ret += f" {completion_time.seconds % 3600 // 60} minutes" cnt += 1 if cnt < 3 and completion_time.seconds % 60 != 0: ret += f" {completion_time.seconds % 60} seconds" return await ctx.respond(f"Challenge took{ret}. " f"{current.handle} gained {point} points") else: return await ctx.respond("You have not completed the challenge")
async def nogud(self, ctx): ''' Cancels any unfinished challenge ''' query = Query() gitgud_util = Gitgud_utils() username = query.get_handle(ctx.author.id, ctx.guild.id) if username is None: return await ctx.send('You do not have a linked DMOJ account') current = gitgud_util.get_current(username, ctx.guild.id) if current is None or current.problem_id is None: return await ctx.send('Nothing to cancel') gitgud_util.clear(username, ctx.guild.id) return await ctx.send('Challenge skipped')
async def get_unsolved_problem(self, username, guild_id, increment, types, low=1, high=50): unsolved = self.get_unsolved_problems(username, types, low, high) if len(unsolved) == 0: return None problem = random.choice(unsolved) gitgud_util = Gitgud_utils() gitgud_util.bind(username, guild_id, problem.code, problem.points * increment, datetime.now()) points = str(problem.points) if problem.partial: points += 'p' memory = problem.memory_limit if memory >= 1024 * 1024: memory = '%dG' % (memory // 1024 // 1024) elif memory >= 1024: memory = '%dM' % (memory // 1024) else: memory = '%dK' % (memory) embed = discord.Embed( title=problem.name, url='https://dmoj.ca/problem/%s' % problem.code, description='Points: %s\nProblem Types: ||%s||' % (points, ', '.join(problem.types)), color=0xfcdb05, ) embed.set_thumbnail(url=await self.get_pfp(username)) embed.add_field(name='Group', value=problem.group, inline=True) embed.add_field(name='Time', value='%ss' % problem.time_limit, inline=True) embed.add_field(name='Memory', value=memory, inline=True) # print(embed) return embed
async def gitgud(self, ctx, points: typing.Optional[point_range], *filters): """ Recommend a problem and gain point upon completion SHORTHANDS: - adhoc - math - bf - ctf - ds - d&c - dp - geo - gt - greedy - regex - string """ filters = list(filters) query = Query() gitgud_util = Gitgud_utils() # get the user's dmoj handle username = query.get_handle(ctx.author.id, ctx.guild.id) # user = await query.get_user(username) if username is None: return await ctx.send("You are not linked to a DMOJ Account. " "Please link your account before continuing") user = await query.get_user(username) if points is None: points = [0, 0] closest = -1000 for key in RATING_TO_POINT: if abs(key - user.rating) <= abs(closest - user.rating): closest = key points[0] = RATING_TO_POINT[closest] points[1] = points[0] # return if the user haven't finished the previous problem current = gitgud_util.get_current(username, ctx.guild.id) if current is not None and current.problem_id is not None: if not gitgud_util.has_solved(username, current.problem_id): # User has a current problem unsolved problem = await query.get_problem(current.problem_id) embed = discord.Embed( description=f"You currently have an uncompleted " f"challenge, [{problem.name}]" f"(https://dmoj.ca/problem/{problem.code})", color=0xfcdb05, ) return await ctx.send(embed=embed) filter_list = [] for filter in filters: if filter in SHORTHANDS: filter_list.append(SHORTHANDS[filter]) filters = filter_list embed, problem = await gimme_common(username, points, filters) if embed is None: return await ctx.send("No problems that satisfies the filter") gitgud_util.bind(username, ctx.guild.id, problem.code, problem.points, datetime.now()) embed.description = "Points: %s\nProblem Types ||%s||" % \ (problem.points, ', '.join(problem.types)) return await ctx.send(embed=embed)
async def gitlog(self, ctx, username=None): ''' Show the past gitgud history of a user ''' query = Query() username = username or query.get_handle(ctx.author.id, ctx.guild.id) try: user = await query.get_user(username) username = user.username except TypeError: username = None if username is None: return await ctx.send('You have not entered a valid DMOJ handle ' 'or linked with a DMOJ Account') gitgud_util = Gitgud_utils() history = gitgud_util.get_all(username, ctx.guild.id) if len(history) == 0: embed = discord.Embed(description='User have not completed any ' 'challenge') return await ctx.send(embed=embed) # paginate count = 0 page_cnt = min(10, len(history) // 10 + bool(len(history) % 10)) embeds = [] content = '' paginator = Pagination.CustomEmbedPaginator(ctx, timeout=60, remove_reactions=True) paginator.add_reaction('⏮️', 'first') paginator.add_reaction('⏪', 'back') paginator.add_reaction('⏩', 'next') paginator.add_reaction('⏭️', 'last') for solved in history: problem = await query.get_problem(solved.problem_id) days = (datetime.now() - solved.time).days if days == 0: days_str = 'today' elif days == 1: days_str = 'yesterday' else: days_str = f'{days} days ago' content += f'[{problem.name}](https://dmoj.ca/problem/{problem.code}) ' \ f'[+{solved.point}] ({days_str})\n' count += 1 if count % 10 == 0: embed = discord.Embed(color=0xfcdb05, ) embed.add_field(name=f'Gitgud Log for {username} ' f'(page {count//10}/{page_cnt})', value=content, inline=True) embeds.append(embed) content = '' if count == 100: break if count % 10 != 0: embed = discord.Embed() embed.add_field(name=f'Gitlog for {username} ' f'(page {count//10 + 1}/{page_cnt})', value=content, inline=True) embeds.append(embed) return await paginator.run(embeds)
async def gitgud(self, ctx, points: typing.Optional[point_range], *filters): """ Recommend a problem and gain point upon completion SHORTHANDS: - adhoc - math - bf - ctf - ds - d&c - dp - geo - gt - greedy - regex - string """ filters = list(filters) query = Query() gitgud_util = Gitgud_utils() # get the user's dmoj handle username = query.get_handle(ctx.author.id, ctx.guild.id) # user = await query.get_user(username) if username is None: return await ctx.send(f"You are not linked to a DMOJ Account. Please link your account before continuing") user = await query.get_user(username) if points is None: points = [0, 0] closest = -1000 for key in RATING_TO_POINT: if abs(key - user.rating) <= abs(closest - user.rating): closest = key points[0] = RATING_TO_POINT[closest] points[1] = points[0] # return if the user haven't finished the previous problem current = gitgud_util.get_current(username, ctx.guild.id) if current is not None and current.problem_id is not None: if current.point == 0 and await query.solved(username, current.problem_id): gitgud_util.clear(username, ctx.guild.id) else: problem = await query.get_problem(current.problem_id) embed = discord.Embed( description=f"You currently have an uncompleted challenge, [{problem.name}](https://dmoj.ca/{problem.code})" ) return await ctx.send(embed=embed) filter_list = [] for filter in filters: if filter in SHORTHANDS: filter_list.append(SHORTHANDS[filter]) filters = filter_list result = await query.get_unsolved_problem(username, ctx.guild.id, 1, filters, points[0], points[1]) if result is None: return await ctx.send("No problems that satisfies the filter") return await ctx.send(embed=result)