Exemple #1
0
 def cfLoadProblemSln(userId: str):
     with getConnection() as con:
         r = con.execute(
             'SELECT id, contestId, problemIdx FROM Problem WHERE userId = :userId',
             {
                 'userId': userId
             }).fetchone()
         pid, contestId, problemIdx = None, None, None
         if r != None:
             pid, contestId, problemIdx = r[0], r[1], r[2]
             if con.execute(
                     'SELECT problemId FROM ProblemSln WHERE problemId = :pid',
                 {
                     'pid': pid
                 }).fetchone() != None:
                 return ProblemSln(pid)
         else:
             raise CriticalException(
                 f'There is no problem with Id = {userId}')
         stands = cfSession.get(
             f'https://codeforces.com/api/contest.standings?contestId={contestId}&from=1&count=10&showUnofficial=true'
         ).json()['result']
         if stands['contest']['phase'].lower() != 'finished':
             raise CriticalException(
                 f'The contest is not finished yet, so can\'t download any solutions yet'
             )
         ProblemSln._parseAndstoreSubmissionSln(
             contestId, _findAcceptedSub(contestId, problemIdx, stands),
             pid)
         return ProblemSln(pid)
Exemple #2
0
    def _parseAndStoreSubmissionTests(contestId: int,
                                      subId: int,
                                      problemId: int,
                                      trans: list = None,
                                      transSep: str = None) -> int:
        """
        trans will receive each test case input and output seperated by transSep and its supposed to print the same.
        Also, If input or ouput are empty then the case won't be saved.
        """
        bs = bs4.BeautifulSoup(
            cfSession.get(
                f'https://codeforces.com/contest/{contestId}/submission/{subId}'
            ).text, 'lxml')

        xcsrf = bs.select_one('meta[name="X-Csrf-Token"]').get('content')
        d = cfSession.post(
            'https://codeforces.com/data/submitSource',
            headers={
                'Content-Type':
                'application/x-www-form-urlencoded; charset=UTF-8',
                'X-Csrf-Token': xcsrf
            },
            data=f'submissionId={subId}&csrf_token={xcsrf}').json()
        cnt = 0
        with getConnection() as con:
            for i in range(1, int(d['testCount']) + 1):
                ipt, opt = d[f'input#{i}'].replace(
                    '\r\n',
                    '\n').strip(), d[f'answer#{i}'].replace('\r\n',
                                                            '\n').strip()
                if trans != None:
                    transInput = f'{ipt}\n{transSep}\n{opt}'
                    try:
                        ipt, opt = subprocess.run(
                            trans,
                            text=True,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            check=True,
                            input=transInput).stdout.split(transSep)
                    except subprocess.CalledProcessError as er:
                        raise CriticalException(
                            'Case transformer exited with non-zero code.')
                elif ipt.endswith('...') or opt.endswith('...'):
                    ipt, opt = None, None
                if ipt != None and (str.isspace(ipt) == False
                                    and len(ipt) > 0) and opt != None and (
                                        str.isspace(opt) == False
                                        and len(opt) > 0):
                    cnt += 1
                    con.execute(
                        'INSERT INTO Test(problemId, id, input, answer) VALUES(:problemId, :id, :input, :answer)',
                        {
                            'problemId': problemId,
                            'id': f'CF{i}',
                            'input': ipt,
                            'answer': opt
                        })

        return cnt
Exemple #3
0
 def tryFindAcceptedSub(solverHandle: str) -> int:
     solverSubs = cfSession.get(
         f'https://codeforces.com/api/contest.status?contestId={contestId}&handle={solverHandle}&from=1&count=100000'
     ).json()['result']
     return next(
         (s['id'] for s in solverSubs
          if s['problem']['index'].upper() == problemIdx and s['verdict'] ==
          'OK' and s['programmingLanguage'].find('++') != -1), -1)
Exemple #4
0
 def cfAddContest(contestId: int, problemUserIdPrefix: str = None) -> list:
     if problemUserIdPrefix == None:
         problemUserIdPrefix = str(contestId)
         logging.info(
             'No problem id orefix was supplied so will use contest id instead.'
         )
     probs = cfSession.get(
         f'https://codeforces.com/api/contest.standings?contestId={contestId}&from=1&count=1&showUnofficial=false'
     ).json()['result']['problems']
     res = []
     for p in probs:
         res.append(
             Problem.addProblem(f'{problemUserIdPrefix}{p["index"]}',
                                contestId, p["index"]))
     logging.info(
         f'Added {len(res)} problems from contest {contestId} to db.')
     return res
Exemple #5
0
    def cfLoadTestSet(userId: str, transformerPath: str = None) -> int:
        with getConnection() as con:
            r = con.execute(
                'SELECT id, contestId, problemIdx FROM Problem WHERE userId = :userId',
                {
                    'userId': userId
                }).fetchone()
            pid, contestId, problemIdx = None, None, None
            if r != None:
                pid, contestId, problemIdx = r[0], r[1], r[2]
                con.execute(
                    "DELETE FROM Test WHERE problemId = :pid AND id LIKE 'CF%'",
                    {'pid': pid})
                con.commit()
            else:
                raise CriticalException(
                    f'There is no problem with id: {userId} in db.')
            stands = cfSession.get(
                f'https://codeforces.com/api/contest.standings?contestId={contestId}&from=1&count=10&showUnofficial=true'
            ).json()['result']
            loadSamples = stands['contest']['phase'].lower() != 'finished'
            if loadSamples == False:
                acc = _findAcceptedSub(contestId, problemIdx, stands)
                if acc != None:
                    con.commit()
                    if transformerPath != None:
                        trans, transSep = compiler.compile(
                            transformerPath), '!@#$%^&*()_'
                        trans.append('--seperator')
                        trans.append(transSep)
                    else:
                        trans, transSep = None, None
                    return TestSet._parseAndStoreSubmissionTests(
                        contestId, acc, pid, trans, transSep)
                else:
                    logging.info(
                        f"Couldn't find any accepted submission for problem {userId} so I will load samples instead."
                    )
                    loadSamples = True

            if loadSamples:
                logging.info(f'Loading problem {userId} samples.')
                return TestSet._parseAndStoreProblemSamples(
                    contestId, problemIdx, pid)
Exemple #6
0
    def _parseAndStoreProblemSamples(contestId: int, probIdx: int,
                                     problemId: int) -> int:
        bs = bs4.BeautifulSoup(
            cfSession.get(
                f'https://codeforces.com/contest/{contestId}/problem/{probIdx}'
            ).text, 'lxml')

        samplesDiv: bs4.Tag = bs.select_one('div.sample-tests')
        inputs = samplesDiv.select('div.input>pre')
        outputs = samplesDiv.select('div.output>pre')
        with getConnection() as con:
            for i in range(len(inputs)):
                con.execute(
                    'INSERT INTO Test(problemId, id, input, answer) VALUES(:problemId, :id, :input, :answer)',
                    {
                        'problemId': problemId,
                        'id': f'CF{i+1}',
                        'input': inputs[i].text,
                        'answer': outputs[i].text
                    })
        return len(inputs)
Exemple #7
0
    def _parseAndstoreSubmissionSln(contestId: int, subId: int,
                                    problemId: int) -> None:
        bs = bs4.BeautifulSoup(
            cfSession.get(
                f'https://codeforces.com/contest/{contestId}/submission/{subId}'
            ).text, 'lxml')

        xcsrf = bs.select_one('meta[name="X-Csrf-Token"]').get('content')
        d = cfSession.post(
            'https://codeforces.com/data/submitSource',
            headers={
                'Content-Type':
                'application/x-www-form-urlencoded; charset=UTF-8',
                'X-Csrf-Token': xcsrf
            },
            data=f'submissionId={subId}&csrf_token={xcsrf}').json()
        with getConnection() as con:
            con.execute(
                'INSERT INTO ProblemSln(problemId, source) VALUES(:pid, :src)',
                {
                    'pid': problemId,
                    'src': d['source'].replace('\r\n', '\n')
                })