Esempio n. 1
0
    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)')
Esempio n. 2
0
    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))
Esempio n. 3
0
    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()
Esempio n. 4
0
    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()
Esempio n. 5
0
    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()
Esempio n. 7
0
    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()
Esempio n. 8
0
    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()
Esempio n. 9
0
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")
Esempio n. 10
0
 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()
Esempio n. 11
0
    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")
Esempio n. 12
0
    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')
Esempio n. 13
0
    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
Esempio n. 14
0
 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()
Esempio n. 15
0
    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()
Esempio n. 16
0
 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()
Esempio n. 17
0
    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()
Esempio n. 18
0
 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()
Esempio n. 19
0
    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()
Esempio n. 20
0
    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()]
Esempio n. 21
0
    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]]
Esempio n. 22
0
    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()
Esempio n. 23
0
File: api.py Progetto: AndrewQT/JOMD
    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()
Esempio n. 24
0
    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()
Esempio n. 25
0
    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()
Esempio n. 26
0
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")
Esempio n. 27
0
    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()