예제 #1
0
파일: dbMan.py 프로젝트: AyoubAref/CFTester
 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)
예제 #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
예제 #3
0
파일: dbMan.py 프로젝트: AyoubAref/CFTester
 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)
예제 #4
0
파일: dbMan.py 프로젝트: AyoubAref/CFTester
 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
예제 #5
0
파일: dbMan.py 프로젝트: AyoubAref/CFTester
    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)
예제 #6
0
파일: dbMan.py 프로젝트: AyoubAref/CFTester
    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)
예제 #7
0
파일: dbMan.py 프로젝트: AyoubAref/CFTester
    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')
                })