async def link(self, ctx, username: str): """Links your discord account to your dmoj account""" # Check if user exists query = Query() user = await query.get_user(username) if user is None: await ctx.send(f"{username} does not exist on DMOJ") return username = user.username if query.get_handle(ctx.author.id, ctx.guild.id): await ctx.send('%s, your handle is already linked with %s.' % (ctx.author.mention, query.get_handle(ctx.author.id, ctx.guild.id))) return if query.get_handle_user(username, ctx.guild.id): await ctx.send('This handle is already linked with another user') return problem = query.get_random_problem() if problem is None: await ctx.send('No problems are cached.. ' 'Pls do something about that') # Will implement this # Just cache the problems and get a random one return await ctx.send( '%s, submit a compiler error to <https://dmoj.ca/problem/%s> ' 'within 60 seconds' % (ctx.author.mention, problem.code)) await asyncio.sleep(60) submissions = await query.get_latest_submissions(username, 10) # if the user links twice, it might break the db # Should add decorator to prevent this if query.get_handle(ctx.author.id, ctx.guild.id): return for submission in submissions: if (submission.result == 'CE' and submission.problem[0].code == problem.code): handle = Handle_DB() handle.id = ctx.author.id handle.handle = username handle.user_id = user.id handle.guild_id = ctx.guild.id session.add(handle) session.commit() return await ctx.send( "%s, you now have linked your account to %s." % (ctx.author.name, username)) else: return await ctx.send('I don\'t see anything :monkey: ' '(Failed to link accounts)')
async def _set(self, ctx, member: discord.Member, username: str): """Manually link two accounts together""" query = Query() user = await query.get_user(username) if user is None: await ctx.send(f'{username} does not exist on dmoj') return username = user.username if query.get_handle(member.id, ctx.guild.id): await ctx.send( '%s, this handle is already linked with %s.' % (ctx.author.mention, query.get_handle(member.id, ctx.guild.id)) ) return if query.get_handle_user(username, ctx.guild.id): await ctx.send('This handle is already linked with another user') return handle = Handle_DB() handle.id = member.id handle.handle = username handle.user_id = user.id handle.guild_id = ctx.guild.id session.add(handle) session.commit() return await ctx.send("%s, %s is now linked with %s." % (ctx.author.name, member.name, username))
async def get_contests(self, tag=None, organization=None) -> List[Contest_DB]: a = API() page = 1 await a.get_contests(tag=tag, organization=organization, page=page) q = session.query(Contest_DB).\ filter(self.parse(Contest_DB.tags, tag)).\ filter(self.parse(Contest_DB.organizations, organization)) if a.data.total_objects == q.count(): return q.all() for contest in a.data.objects: qq = session.query(Contest_DB).\ filter(Contest_DB.key == contest.key) if qq.count() == 0: session.add(Contest_DB(contest)) while a.data.has_more: page += 1 await a.get_contests(tag=tag, organization=organization, page=page) for contest in a.data.objects: qq = session.query(Contest_DB).\ filter(Contest_DB.key == contest.key) if qq.count() == 0: session.add(Contest_DB(contest)) session.commit() return q.all()
async def get_problems(self, partial=None, group=None, _type=None, organization=None, search=None, cached=False) -> List[Problem_DB]: q = session.query(Problem_DB).\ filter(self.parse(Problem_DB.partial, partial)).\ filter(self.parse(Problem_DB.group, group)).\ filter(self.parse(Problem_DB.types, _type)).\ filter(self.parse(Problem_DB.organizations, organization)) if cached: return q.all() a = API() if search is not None: # Can't bother to implement something with db # maybe future me can do this await a.get_problems(partial=partial, group=group, _type=_type, organization=organization, search=search) return list(map(Problem_DB, a.data.objects)) page = 1 await a.get_problems(partial=partial, group=group, _type=_type, organization=organization, search=search, page=page) if a.data.total_objects == q.count(): return q.all() for problem in a.data.objects: qq = session.query(Problem_DB).\ filter(Problem_DB.code == problem.code) if qq.count() == 0: session.add(Problem_DB(problem)) while a.data.has_more: page += 1 await a.get_problems(partial=partial, group=group, _type=_type, organization=organization, search=search, page=page) for problem in a.data.objects: qq = session.query(Problem_DB).\ filter(Problem_DB.code == problem.code) if qq.count() == 0: session.add(Problem_DB(problem)) session.commit() return q.all()
async def async_init(self): language_qq = session.query(Language_DB).\ filter(Language_DB.key.in_(self._languages)) language_q = session.query(Language_DB.key).\ filter(Language_DB.key.in_(self._languages)).all() language_q = list(map(itemgetter(0), language_q)) for language_key in self._languages: if language_key not in language_q: api = API() await api.get_languages() for language in api.data.objects: if language.key == language_key: session.add(Language_DB(language)) session.commit() break self.languages = language_qq.all() organization_qq = session.query(Organization_DB).\ filter(Organization_DB.id.in_(self._organizations)) organization_q = session.query(Organization_DB.id).\ filter(Organization_DB.id.in_(self._organizations)).all() organization_q = list(map(itemgetter(0), organization_q)) for organization_id in self._organizations: if organization_id not in organization_q: api = API() await api.get_organizations() for organization in api.data.objects: if organization.id == organization_id: session.add(Organization_DB(organization)) session.commit() break self.organizations = organization_qq.all()
def refresh_data(): fetch = requests.get('http://network:5000/devices/') devices = fetch.json() for device in devices: del device["id"] active = device.pop("active_connection") upload = device.pop("upload_speed") download = device.pop("download_speed") found_device = session.query(StaticData).filter_by( mac_address=device["mac_address"]).first() if found_device: static_data_id = found_device.id else: new_device = StaticData(**device) session.add(new_device) session.commit() static_data_id = new_device.id snap_shot = { "static_data_id": static_data_id, "time_stamp": datetime.now(), "active_connection": active, "upload_speed": upload, "download_speed": download } dynamic_data = DynamicData(**snap_shot) session.add(dynamic_data) session.commit()
async def get_users(self, organization=None) -> List[User_DB]: a = API() page = 1 await a.get_users(organization=organization, page=page) q = session.query(User_DB).\ filter(self.parse(User_DB.organizations, organization)) if a.data.total_objects == q.count(): return q.all() for user in a.data.objects: qq = session.query(User_DB).\ filter(User_DB.id == user.id) if qq.count() == 0: session.add(User_DB(user)) while a.data.has_more: page += 1 await a.get_users(organization=organization, page=page) for user in a.data.objects: qq = session.query(User_DB).\ filter(User_DB.id == user.id) if qq.count() == 0: session.add(User_DB(user)) session.commit() return q.all()
async def async_init(self): organization_qq = session.query(Organization_DB).filter( Organization_DB.id.in_(self._organizations)) organization_q = session.query(Organization_DB.id).filter( Organization_DB.id.in_(self._organizations)).all() organization_q = list(map(itemgetter(0), organization_q)) for organization_id in self._organizations: if organization_id not in organization_q: api = API() await api.get_organizations() for organization in api.data.objects: if organization.id not in organization_q and organization.id in self._organizations: session.add(Organization_DB(organization)) session.commit() break self.organizations = organization_qq.all() # perhaps I should check if it's the general or detailed version self._problem_codes = list(map(itemgetter("code"), self._problems)) problem_qq = session.query(Problem_DB).filter( Problem_DB.code.in_(self._problem_codes)) problem_q = session.query(Problem_DB.code).filter( Problem_DB.code.in_(self._problem_codes)).all() problem_q = list(map(itemgetter(0), problem_q)) for problem_dict in self._problems: problem_code = problem_dict["code"] try: if problem_code not in problem_q: api = API() await api.get_problem(problem_code) session.add(Problem_DB(api.data.object)) session.commit() except ObjectNotFound: pass self.problems = problem_qq.all()
async def link(ctx: lightbulb.Context) -> None: username = ctx.options.username # Check if user exists query = Query() try: user = await query.get_user(username) if user is None: raise ObjectNotFound() except ObjectNotFound: await ctx.respond(escape_markdown(f"{username} does not exist on DMOJ")) return username = user.username if query.get_handle(ctx.author.id, ctx.get_guild().id): await ctx.respond( "%s, your handle is already linked with %s." % (ctx.author.mention, query.get_handle(ctx.author.id, ctx.get_guild().id)) ) return if query.get_handle_user(username, ctx.get_guild().id): await ctx.respond("This handle is already linked with another user") return # verify from dmoj user description description = await query.get_user_description(username) userKey = hashlib.sha256(str(ctx.author.id).encode()).hexdigest() if userKey not in description: await ctx.respond( "Put `" + userKey + "` in your DMOJ user description (https://dmoj.ca/edit/profile/) " "and run the command again." ) return handle = Handle_DB() handle.id = ctx.author.id handle.handle = username handle.user_id = user.id handle.guild_id = ctx.get_guild().id session.add(handle) session.commit() await ctx.respond(escape_markdown("%s, you now have linked your account to %s" % (ctx.author, username))) rank_to_role = {} rc = lightbulb.RoleConverter(ctx) for role_id in ctx.get_guild().get_roles(): role = await rc.convert(str(role_id)) if role.name in RANKS: rank_to_role[role.name] = role rank = rating_to_rank(user.rating) # TODO Add guild specific option to disable updating roles if rank in rank_to_role: await _update_rank(ctx.member, rank_to_role[rank], "Dmoj account linked") else: await ctx.respond("You are missing the `" + rank + "` role")
def insert(self, handle, guild_id, point, problem, time): db = Gitgud_DB() db.handle = handle db.guild_id = guild_id db.point = point db.problem_id = problem db.time = time session.add(db) session.commit()
async def _set(self, ctx, member, username: str): """Manually link two accounts together""" query = Query() member = await query.parseUser(ctx, member) if username != "+remove": user = await query.get_user(username) if user is None: await ctx.send(f'{username} does not exist on dmoj') return username = user.username handle = query.get_handle(member.id, ctx.guild.id) if handle == username: return await ctx.send( f'{member.display_name} is already linked with {handle}') if handle: handle = session.query(Handle_DB)\ .filter(Handle_DB.id == member.id)\ .filter(Handle_DB.guild_id == ctx.guild.id).first() session.delete(handle) session.commit() await ctx.send( f'Unlinked {member.display_name} with handle {handle.handle}') if username == "+remove": return if query.get_handle_user(username, ctx.guild.id): await ctx.send('This handle is already linked with another user') return handle = Handle_DB() handle.id = member.id handle.handle = username handle.user_id = user.id handle.guild_id = ctx.guild.id session.add(handle) session.commit() await ctx.send(f"Linked {member.name} with {username}.") rank_to_role = { role.name: role for role in ctx.guild.roles if role.name in RANKS } rank = self.rating_to_rank(user.rating) if rank in rank_to_role: await self._update_rank(ctx.author, rank_to_role[rank], 'Dmoj account linked') else: await ctx.send("You are missing the " + rank.name + " role")
async def link(self, ctx, username: str): '''Links your discord account to your dmoj account''' # Check if user exists query = Query() user = await query.get_user(username) if user is None: await ctx.send(f'{username} does not exist on DMOJ') return username = user.username if query.get_handle(ctx.author.id, ctx.guild.id): await ctx.send('%s, your handle is already linked with %s.' % (ctx.author.mention, query.get_handle(ctx.author.id, ctx.guild.id))) return if query.get_handle_user(username, ctx.guild.id): await ctx.send('This handle is already linked with another user') return # verify from dmoj user description description = await query.get_user_description(username) userKey = hashlib.sha256(str(ctx.author.id).encode()).hexdigest() if userKey not in description: await ctx.send( 'Put `' + userKey + '` in your DMOJ user description (https://dmoj.ca/edit/profile/) ' 'and run the command again.') return handle = Handle_DB() handle.id = ctx.author.id handle.handle = username handle.user_id = user.id handle.guild_id = ctx.guild.id session.add(handle) session.commit() await ctx.send('%s, you now have linked your account to %s' % (ctx.author.name, username)) return rank_to_role = { role.name: role for role in ctx.guild.roles if role.name in RANKS } rank = self.rating_to_rank(user.rating) if rank in rank_to_role: await self._update_rank(ctx.author, rank_to_role[rank], 'Dmoj account linked') else: await ctx.send('You are missing the ' + rank.name + ' role')
async def get_languages(self, common_name=None) -> [Language_DB]: q = session.query(Language_DB).\ filter(self.parse(Language_DB.common_name, common_name)) if q.count(): return q.all() a = API() await a.get_languages(common_name=common_name) languages = list(map(Language_DB, a.data.objects)) for language in languages: session.add(language) session.commit() return languages
async def get_contest(self, key) -> Contest_DB: q = session.query(Contest_DB).\ filter(Contest_DB.key == key) if q.count(): # is_rated checks if it has detailed rows if q.first().is_rated is not None: return q.first() a = API() await a.get_contest(key) if q.count(): q.delete() session.add(Contest_DB(a.data.object)) session.commit() return q.first()
async def get_problem(self, code) -> Problem_DB: q = session.query(Problem_DB).\ filter(Problem_DB.code == code) if q.count(): # has_rating check if it has a detailed row if q.first().short_circuit is not None: return q.first() a = API() await a.get_problem(code) if q.count(): q.delete() session.add(Problem_DB(a.data.object)) session.commit() return q.first()
def bind(self, handle, guild_id, problem_id, point, time): result = self.get_current(handle, guild_id) if result is None: db = CurrentGitgud_DB() db.handle = handle db.guild_id = guild_id db.problem_id = problem_id db.point = point db.time = time session.add(db) else: result.problem_id = problem_id result.point = point result.time = time session.commit()
async def get_user(self, username) -> User_DB: q = session.query(User_DB).\ filter(func.lower(User_DB.username) == func.lower(username)) # if q.count(): # # solved_problems checks if it has detailed rows # if len(q.first().solved_problems) != 0: # return q.first() a = API() await a.get_user(username) if q.count(): # Needs to be fetch, the default (evaluate) is not able to eval # the query q.delete(synchronize_session='fetch') session.add(User_DB(a.data.object)) session.commit() return q.first()
async def get_contest(self, key: str) -> Contest_DB: q = session.query(Contest_DB).\ filter(Contest_DB.key == key) if q.count(): # is_rated checks if it has detailed rows if q.first().is_rated is not None: return q.first() a = API() await a.get_contest(key) # Requery the key to prevent path traversal from killing db q = session.query(Contest_DB).\ filter(Contest_DB.key == a.data.object.key) if q.count(): q.delete() session.add(Contest_DB(a.data.object)) session.commit() return q.first()
async def async_init(self): user = session.query(User_DB).filter(User_DB.username == self._user) if user.count() == 0: api = API() await api.get_user(self._user) session.add(api.data.object) session.commit() self.user = user.first() contest = session.query(Contest_DB).filter( Contest_DB.key == self._contest) if contest.count() == 0: api = API() await api.get_contest(self._contest) session.add(api.data.object) session.commit() self.contest = contest.first()
async def async_old(self): problem_q = session.query(Problem_DB).\ filter(Problem_DB.code == self._problem) if problem_q.count() == 0: api = API() await api.get_problem(self._problem) session.add(Problem_DB(api.data.object)) session.commit() self.problem = [problem_q.first()] user_q = session.query(User_DB).\ filter(User_DB.username == self._user) if user_q.count() == 0: api = API() await api.get_user(self._user) session.add(User_DB(api.data.object)) session.commit() self.user = [user_q.first()] language_q = session.query(Language_DB).\ filter(Language_DB.key == self._language) if language_q.count() == 0: api = API() await api.get_languages() for language in api.data.objects: if language.key == self._language: session.add(Language_DB(language)) session.commit() break self.language = [language_q.first()]
async def async_init(self, problem_q, user_q, language_q, lock_table): if self._problem not in problem_q and self._problem not in lock_table: lock_table[self._problem] = asyncio.Lock() async with lock_table[self._problem]: api = API() await api.get_problem(self._problem) problem = Problem_DB(api.data.object) session.add(problem) problem_q[self._problem] = problem if self._problem in problem_q: self.problem = [problem_q[self._problem]] if self._user not in user_q: api = API() await api.get_user(self._user) user = User_DB(api.data.object) session.add() user_q[self._user] = user self.user = [user_q[self._user]] if self._language not in language_q: api = API() await api.get_languages() for language in api.data.objects: if language.key == self._language: lang = Language_DB(language) session.add(lang) language_q[self._language] = lang break self.language = [language_q[self._language]] if self.problem is None: async with lock_table[self._problem]: self.problem = [problem_q[self._problem]]
async def async_init(self): problem_qq = session.query(Problem_DB).filter( Problem_DB.code.in_(self._solved_problems)) problem_q = session.query(Problem_DB.code).filter( Problem_DB.code.in_(self._solved_problems)).all() problem_q = list(map(itemgetter(0), problem_q)) for problem_code in self._solved_problems: try: if problem_code not in problem_q: api = API() await api.get_problem(problem_code) session.add(Problem_DB(api.data.object)) session.commit() except ObjectNotFound: pass self.solved_problems = problem_qq.all() organization_qq = session.query(Organization_DB).filter( Organization_DB.id.in_(self._organizations)) organization_q = session.query(Organization_DB.id).filter( Organization_DB.id.in_(self._organizations)).all() organization_q = list(map(itemgetter(0), organization_q)) for organization_id in self._organizations: if organization_id not in organization_q: api = API() await api.get_organizations() for organization in api.data.objects: if organization.id not in organization_q and organization.id in self._organizations: session.add(Organization_DB(organization)) session.commit() break self.organizations = organization_qq.all() for contest in self._contests: if contest["rating"]: self.max_rating = max(self.max_rating or 0, contest["rating"]) self._contest_keys = list(map(itemgetter("key"), self._contests)) contest_qq = session.query(Contest_DB).filter( Contest_DB.key.in_(self._contest_keys)) contest_q = session.query(Contest_DB.key).filter( Contest_DB.key.in_(self._contest_keys)).all() contest_q = list(map(itemgetter(0), contest_q)) for contest_key in self._contest_keys: try: if contest_key not in contest_q: api = API() await api.get_contest(contest_key) # This causes db errors, and in the case the above doesn't catch it. # This will be a last ditch effort if session.query(Contest_DB).filter( Contest_DB.key == contest_key).count(): continue session.add(Contest_DB(api.data.object)) session.commit() except ObjectNotFound: pass self.contests = contest_qq.all()
async def async_init(self): problem_qq = session.query(Problem_DB).\ filter(Problem_DB.code.in_(self._solved_problems)) problem_q = session.query(Problem_DB.code).\ filter(Problem_DB.code.in_(self._solved_problems)).all() problem_q = list(map(itemgetter(0), problem_q)) for problem_code in self._solved_problems: try: if problem_code not in problem_q: api = API() await api.get_problem(problem_code) session.add(Problem_DB(api.data.object)) session.commit() except ObjectNotFound: pass self.solved_problems = problem_qq.all() organization_qq = session.query(Organization_DB).\ filter(Organization_DB.id.in_(self._organizations)) organization_q = session.query(Organization_DB.id).\ filter(Organization_DB.id.in_(self._organizations)).all() organization_q = list(map(itemgetter(0), organization_q)) for organization_id in self._organizations: if organization_id not in organization_q: api = API() await api.get_organizations() for organization in api.data.objects: if (organization.id not in organization_q and organization.id in self._organizations): session.add(Organization_DB(organization)) session.commit() break self.organizations = organization_qq.all() def get_key(contest): return contest["key"] self._contest_keys = list(map(get_key, self._contests)) contest_qq = session.query(Contest_DB).\ filter(Contest_DB.key.in_(self._contest_keys)) contest_q = session.query(Contest_DB.key).\ filter(Contest_DB.key.in_(self._contest_keys)).all() contest_q = list(map(itemgetter(0), contest_q)) for contest_key in self._contest_keys: try: if contest_key not in contest_q: api = API() await api.get_contest(contest_key) session.add(Contest_DB(api.data.object)) session.commit() except ObjectNotFound: pass self.contests = contest_qq.all()
async def get_submissions(self, user=None, problem=None, language=None, result=None) -> List[Submission_DB]: # This function is the only one which might take a while to run and # has data that is added reguarly. asyncio.gather can apply to all # functions but this one is the only one which really needs it a = API() page = 1 import time start = time.time() await a.get_submissions(user=user, problem=problem, language=language, result=result, page=page) print("Done Api Call", time.time() - start) start = time.time() q = session.query(Submission_DB) q = q.filter(Submission_DB._user == user) cond_user = self.parse(func.lower(User_DB.username), func.lower(user)) if not cond_user: q = q.join(User_DB, cond_user, aliased=True) cond_problem = self.parse(Problem_DB.code, problem) if not cond_problem: q = q.join(Problem_DB, cond_problem, aliased=True) cond_lang = self.parse(Language_DB.key, language) if not cond_lang: q = q.join(Language_DB, cond_lang, aliased=True) q = q.filter(self.parse(Submission_DB.result, result)) if a.data.total_objects == q.count(): return q.all() def get_id(submission): return submission.id submission_ids = list(map(get_id, a.data.objects)) qq = session.query(Submission_DB.id).\ filter(Submission_DB.id.in_(submission_ids)).all() qq = list(map(itemgetter(0), qq)) for submission in a.data.objects: if submission.id not in qq: session.add(Submission_DB(submission)) total_pages = a.data.total_pages apis = [] to_gather = [] async def get_submission(api, user, problem, language, result, page): try: api.get_submissions(user=user, problem=problem, language=language, result=result, page=page) except: # Sometimes when caching a user with many pages one might not return correctly # this will silently return nothing # Perhaps I should implement some sort of error catching in the cogs pass for _ in range(2, total_pages + 1): page += 1 api = API() to_await = api.get_submissions(user=user, problem=problem, language=language, result=result, page=page) apis.append(api) to_gather.append(to_await) await asyncio.gather(*to_gather) for api in apis: if api.data.objects is None: continue submission_ids = list(map(get_id, api.data.objects)) qq = session.query(Submission_DB.id).\ filter(Submission_DB.id.in_(submission_ids)).all() qq = list(map(itemgetter(0), qq)) for submission in api.data.objects: if submission.id not in qq: session.add(Submission_DB(submission)) session.commit() return q.all()
async def get_participations( self, contest=None, user=None, is_disqualified=None, virtual_participation_number=None) -> List[Participation_DB]: a = API() page = 1 await a.get_participations( contest=contest, user=user, is_disqualified=is_disqualified, virtual_participation_number=virtual_participation_number, page=page) # why the hell are these names so long? cond_contest = self.parse(Contest_DB.key, contest) if not cond_contest: cond_contest = Participation_DB.contest.any(cond_contest) cond_user = self.parse(func.lower(User_DB.username), func.lower(user)) if not cond_user: cond_user = Participation_DB.user.any(cond_user) q = session.query(Participation_DB).\ filter(cond_contest).\ filter(cond_user).\ filter(self.parse(Participation_DB.is_disqualified, is_disqualified)).\ filter(self.parse(Participation_DB.virtual_participation_number, virtual_participation_number)) if a.data.total_objects == q.count(): return q.all() def get_id(participation): return participation.id participation_id = list(map(get_id, a.data.objects)) qq = session.query(Submission_DB.id).\ filter(Submission_DB.id.in_(participation_id)).all() qq = list(map(itemgetter(0), qq)) for submission in a.data.objects: if submission.id not in qq: session.add(Submission_DB(submission)) total_pages = a.data.total_pages for participation in a.data.objects: if participation.id not in participation_id: session.add(Participation_DB(participation)) apis = [] to_gather = [] for _ in range(2, total_pages + 1): page += 1 api = API() to_await = await a.get_participations( contest=contest, user=user, is_disqualified=is_disqualified, virtual_participation_number=virtual_participation_number, page=page) apis.append(api) to_gather.append(to_await) await asyncio.gather(*to_gather) for api in apis: participation_id = list(map(get_id, api.data.objects)) qq = session.query(Submission_DB.id).\ filter(Submission_DB.id.in_(participation_id)).all() qq = list(map(itemgetter(0), qq)) for submission in api.data.objects: if submission.id not in qq: session.add(Submission_DB(submission)) total_pages = api.data.total_pages for participation in api.data.objects: if participation.id not in participation_id: session.add(Participation_DB(participation)) session.commit() return q.all()
async def _set(ctx): """Manually link two accounts together""" # TODO: I don't like the bot spamming replies to itself, figure out a way to lessen that member = ctx.options.member username = ctx.options.handle query = Query() if username != "+remove": try: user = await query.get_user(username) if user is None: raise ObjectNotFound() except ObjectNotFound: await ctx.respond(escape_markdown(f"{username} does not exist on dmoj")) return username = user.username handle = query.get_handle(member.id, ctx.get_guild().id) if handle == username: return await ctx.respond(escape_markdown(f"{member.display_name} is already linked with {handle}")) if handle: handle = ( session.query(Handle_DB) .filter(Handle_DB.id == member.id) .filter(Handle_DB.guild_id == ctx.get_guild().id) .first() ) session.delete(handle) session.commit() await ctx.respond(escape_markdown(f"Unlinked {member.display_name} with handle {handle.handle}")) if username == "+remove": return if query.get_handle_user(username, ctx.get_guild().id): await ctx.respond("This handle is already linked with another user") return handle = Handle_DB() handle.id = member.id handle.handle = username handle.user_id = user.id handle.guild_id = ctx.get_guild().id session.add(handle) session.commit() await ctx.respond(escape_markdown(f"Linked {member.display_name} with {username}")) rank_to_role = {} rc = lightbulb.RoleConverter(ctx) for role_id in ctx.get_guild().get_roles(): role = await rc.convert(str(role_id)) if role.name in RANKS: rank_to_role[role.name] = role rank = rating_to_rank(user.rating) if rank in rank_to_role: await _update_rank(member, rank_to_role[rank], "Dmoj account linked") else: await ctx.respond("You are missing the `" + rank.name + "` role")
async def get_submissions(self, user: str = None, problem: str = None, language: str = None, result: str = None) -> List[Submission_DB]: # This function is the only one which might take a while to run and # has data that is added reguarly. asyncio.gather can apply to all # functions but this one is the only one which really needs it a = API() page = 1 import time start = time.time() await a.get_submissions(user=user, problem=problem, language=language, result=result, page=page) logger.info("Got submissions for %s, time elasped %s", user, time.time() - start) start = time.time() q = session.query(Submission_DB) q = q.filter(Submission_DB._user == user) cond_user = self.parse(func.lower(User_DB.username), func.lower(user)) if not cond_user: q = q.join(User_DB, cond_user, aliased=True) cond_problem = self.parse(Problem_DB.code, problem) if not cond_problem: q = q.join(Problem_DB, cond_problem, aliased=True) cond_lang = self.parse(Language_DB.key, language) if not cond_lang: q = q.join(Language_DB, cond_lang, aliased=True) q = q.filter(self.parse(Submission_DB.result, result)) if a.data.total_objects == q.count(): return q.all() submission_ids = list(map(attrgetter('id'), a.data.objects)) qq = session.query(Submission_DB.id).\ filter(Submission_DB.id.in_(submission_ids)).all() qq = list(map(itemgetter(0), qq)) for submission in a.data.objects: if submission.id not in qq: session.add(Submission_DB(submission)) total_pages = a.data.total_pages apis = [] to_gather = [] for _ in range(2, total_pages + 1): page += 1 api = API() to_await = api.get_submissions(user=user, problem=problem, language=language, result=result, page=page) apis.append(api) to_gather.append(to_await) await asyncio.gather(*to_gather) for api in apis: if api.data.objects is None: continue submission_ids = list(map(attrgetter('id'), api.data.objects)) qq = session.query(Submission_DB.id).\ filter(Submission_DB.id.in_(submission_ids)).all() qq = list(map(itemgetter(0), qq)) for submission in api.data.objects: if submission.id not in qq: session.add(Submission_DB(submission)) session.commit() return q.all()