예제 #1
0
def getSubmissions(request, *args, **kwargs):
    submissions = []

    cont = Contest.getCurrent()
    if not cont:
        return HttpResponse(
            Page(h1(" "), h1("Contest is Over", cls="center")))

    user = User.getCurrent(request)
    Submission.forEach(lambda x: submissions.append(x) if x.user.id == user.id
                       and cont.start <= x.timestamp <= cont.end else None)
    if len(submissions) == 0:
        return HttpResponse(Page(h1("No Submissions Yet", cls="page-title"), ))
    return HttpResponse(
        Page(
            h2("Your Submissions", cls="page-title"),
            SubmissionTable(
                sorted(submissions,
                       key=lambda sub: (sub.problem.title, -sub.timestamp))),
            div(cls="modal",
                tabindex="-1",
                role="dialog",
                contents=[
                    div(cls="modal-dialog",
                        role="document",
                        contents=[div(id="modal-content")])
                ])))
예제 #2
0
 def __init__(self, submission: Submission):
     subTime = submission.timestamp
     probName = submission.problem.title
     cls = "gray" if submission.status == Submission.STATUS_REVIEW else "red" if submission.result != "ok" else ""
     self.html = div(
         cls="modal-content",
         contents=[
             div(cls=f"modal-header {cls}",
                 contents=[
                     h.h5(f"Submission to {probName} at ",
                          h.span(subTime, cls="time-format")), """
             <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                 <span aria-hidden="true">&times;</span>
             </button>"""
                 ]),
             div(cls="modal-body",
                 contents=[
                     h.strong(
                         "Language: <span class='language-format'>{}</span>"
                         .format(submission.language)),
                     h.br(),
                     h.strong("Result: "),
                     verdict_name[submission.getContestantResult()],
                     h.br(),
                     h.br(),
                     h.strong("Code:"),
                     h.code(code_encode(submission.code), cls="code"),
                 ])
         ])
예제 #3
0
    def __init__(self, prob: Problem, user: User):
        probpath = f"/problems/{prob.id}"

        btn = f"rejudgeAll('{prob.id}')" if user.isAdmin() else None

        title = prob.title
        if not user.isAdmin():
            # Compute problem status
            icon = ''
            result = ''
            for sub in Submission.all():
                if sub.problem != prob or sub.user != user or sub.status == Submission.STATUS_REVIEW:
                    continue

                if sub.user == user and "ok" == sub.result:
                    icon = "check"
                    break
                else:
                    icon = "times"

            if icon != '':
                result = f'<i class="fa fa-{icon}"></i> '

            title = result + title

        self.html = Card(title, prob.description, probpath, rejudge=btn)
예제 #4
0
def rejudge(request):
    """Ajax method: Rejudge a single submission `id`"""
    user = User.getCurrent(request)
    id = request.POST["id"]
    submission = Submission.get(id)
    runCode(submission, user)
    return JsonResponse(submission.result, safe=False)
예제 #5
0
def get_user_subs_map(contest: Contest) -> dict:
    contest_prob_ids = [prob.id for prob in contest.problems]
    subs = {}
    for sub in Submission.all():
        if contest.start <= sub.timestamp <= contest.end and not sub.user.isAdmin() and sub.problem.id in contest_prob_ids:
            subs[sub.user.id] = subs.get(sub.user.id, [])
            subs[sub.user.id].append(sub)

    return subs
예제 #6
0
def judge_submission(request, *args, **kwargs):
    submission = Submission.get(kwargs.get('id'))
    user = User.getCurrent(request)
    version = int(request.POST["version"])
    force = kwargs.get('force') == "force"
    if submission.version != version:
        return JsonResponse(f"CHANGES", safe=False)
    elif not submission.checkoutToJudge(user.id, force):
        return JsonResponse(
            f"CONFLICT:{User.get(submission.checkout).username}", safe=False)
    return HttpResponse(SubmissionCard(submission, user, force))
예제 #7
0
def viewDiff(request, *args, **kwargs):
    submission = Submission.get(kwargs.get('id'))
    user = User.getCurrent(request)
    problem = submission.problem

    answers = submission.readFilesForDisplay('out')

    diffTables = []
    for i in range(len(problem.testData)):
        if i < problem.samples:
            caseType = "Sample"
            caseNo = i
        else:
            caseType = "Judge"
            caseNo = i - problem.samples

        diffTables.append(
            h.div(
                h.
                h3(f"{caseType} Case #{caseNo} (Expected Output | Contestant Output)",
                   id=f"case{i}diff"),
                h.div(
                    h.script(
                        f"document.getElementById('case{i}result').innerHTML = 'Result: ' + verdict_name.{submission.results[i]}"
                    ),
                    id=f"case{i}result",
                ),
                generateDiffTable(problem.testData[i].output, answers[i]),
            ))
        pass

    return HttpResponse(
        div(cls="center",
            contents=[
                h.link(
                    rel="stylesheet",
                    href=
                    "/static/styles/style.css?642ab0bc-f075-4c4c-a2ba-00f55392dafc",
                    type="text/css"),
                h.script(src="/static/lib/jquery/jquery.min.js"),
                h.script(src="/static/lib/jqueryui/jquery-ui.min.js"),
                h.script(
                    src=
                    "/static/scripts/script.js?75c1bf1e-10e8-4c8d-9730-0903f6540439"
                ),
                h2(f"Diffs for {submission.id}", cls="center"),
                h.
                em("Insertions are in <span style=color:darkgreen;background-color:palegreen>green</span>, deletions are in <span style=color:darkred;background-color:#F6B0B0>red</span>"
                   ),
                h.div(contents=diffTables)
            ]))
예제 #8
0
def generateLogReport(request):
    user = User.getCurrent(request)
    contest = Contest.getCurrent() or Contest.getPast()
    if not contest:
        return HttpResponse(
            Page(h1("&nbsp;"), h1("No Contest Available", cls="center")))
    elif contest.isScoreboardOff(user):
        return HttpResponse(
            Page(h1("&nbsp;"), h1("Scoreboard is off.", cls="center")))

    start = contest.start
    end = contest.end

    users = {}

    for sub in Submission.all():
        if start <= sub.timestamp <= end and not sub.user.isAdmin(
        ) and sub.result == "ok":
            username = User.get(sub.user.id).username
            problemName = Problem.get(sub.problem.id).title

            if username not in users.keys():
                users[username] = {}
            if problemName not in users[username].keys():
                users[username][problemName] = sub
            if sub.timestamp < users[username][problemName].timestamp:
                users[username][problemName] = sub

    correctSubmissions = []
    for user in users.keys():
        for problem in users[user].keys():
            correctSubmissions.append(
                (user, problem, users[user][problem].timestamp))

    correctSubmissions.sort(key=lambda entry: entry[2])

    tableRows = constructTableRows(correctSubmissions)

    return HttpResponse(
        Page(
            h2("Correct Submissions Log", cls="page-title"),
            h.table(
                h.thead(
                    h.tr(
                        h.th("Contestant Name"),
                        h.th("Problem title"),
                        h.th("Time"),
                    )), h.tbody(*tableRows))))
예제 #9
0
def changeResult(request, *args, **kwargs):
    version = int(request.POST["version"])
    id = request.POST["id"]
    sub = Submission.get(id)
    if not sub:
        return JsonResponse("Error: no such submission", safe=False)

    if sub.changeResult(request.POST["result"], request.POST["status"],
                        version):
        sub.save()
    else:
        return JsonResponse(
            "The submission has been changed by another judge since you loaded it. Please reload the sumbission to "
            "modify it.",
            safe=False)
    return JsonResponse("ok", safe=False)
예제 #10
0
def download(request):
    id = request.POST["id"]
    submission = Submission.get(id)

    buf = io.BytesIO()
    with ZipFile(buf, 'w') as zip:
        sourceFile = f"source.{exts[submission.language]}"
        zip.writestr(sourceFile, submission.code)

        for index in range(submission.problem.tests):
            for fileType in ["in", "out", "answer", "error"]:
                filename = f"/db/submissions/{id}/{fileType}{index}.txt"
                output_dest_filename = f"{fileType}{index}.txt"
                if os.path.exists(filename):
                    zip.write(filename, output_dest_filename)

    data = {"download.zip": base64.b64encode(buf.getvalue()).decode('ascii')}

    return JsonResponse(json.dumps(data), safe=False)
예제 #11
0
    def __init__(self, contest):
        logger.warn(f"Submissions: {Submission.all()}")
        subs = sorted(filter(
            lambda sub: sub.user.type != "admin" and contest.start <= sub.
            timestamp <= contest.end, Submission.all()),
                      key=lambda s: s.timestamp)

        self.html = h.table(
            h.thead(
                h.tr(
                    h.th("Contestant"),
                    h.th("Problem"),
                    h.th("Id"),
                    h.th("Language"),
                    h.th("Result"),
                    h.th("Status"),
                    h.th("Checkout"),
                )),
            h.tbody(*map(lambda sub: SubmissionRow(sub), subs)),
            id="submissions")
예제 #12
0
def rejudgeAll(request):
    """Ajax method: Rejudge all submissions for problem `id`"""

    user = User.getCurrent(request)
    ctime = time.time() * 1000
    id = request.POST["id"]

    subsToRejudge = [
        sub for sub in Submission.all() if sub.problem.id == id
        and sub.timestamp < ctime and sub.result != 'reject'
    ]
    if not Status.instance().startRejudge(id, subsToRejudge):
        return JsonResponse(
            "Another rejudge all is still progress. See System Status below to monitor progress.",
            safe=False)

    RejudgeThread(user, subsToRejudge).start()

    return JsonResponse(
        "Rejudge started. Click System Status below to monitor progress.",
        safe=False)
예제 #13
0
def runCode(sub: Submission, user: User) -> list:
    """Executes submission `sub` and returns lists of data files"""
    extension = exts[sub.language]

    # Use semaphore to throttle number of concurrent submissions
    with Submission.runningSubmissions:
        try:
            shutil.rmtree(f"/tmp/{id}", ignore_errors=True)
            os.makedirs(f"/tmp/{sub.id}", exist_ok=True)

            # Copy the code over to the runner /tmp folder
            writeFile(f"/tmp/{sub.id}/code.{extension}", sub.code)

            prob = sub.problem

            if sub.type == Submission.TYPE_TEST and not user.isAdmin():
                numTests = prob.samples
            elif sub.type == Submission.TYPE_CUSTOM:
                numTests = 1
            else:
                numTests = prob.tests

            # Copy the input over to the tmp folder for the runner
            if sub.type == Submission.TYPE_CUSTOM:
                writeFile(f"/tmp/{sub.id}/in0.txt", sub.custominput)
            else:
                for i in range(numTests):
                    shutil.copyfile(f"/db/problems/{prob.id}/input/in{i}.txt",
                                    f"/tmp/{sub.id}/in{i}.txt")

            # Output files will go here
            os.makedirs(f"/tmp/{sub.id}/out", exist_ok=True)

            # Run the runner
            cmd = f"docker run --rm --network=none -m 256MB -v /tmp/{sub.id}/:/source {OC_DOCKERIMAGE_BASE}-{sub.language}-runner {numTests} {prob.timelimit} > /tmp/{sub.id}/result.txt"
            logger.debug(cmd)
            rc = os.system(cmd)

            overall_result = readFile(f"/tmp/{sub.id}/result.txt")

            if rc != 0 or not overall_result:
                # Test failed to complete properly

                logger.warn(
                    f"Result of submission {sub.id}: rc={rc}, overall_result={overall_result}"
                )

                sub.result = "internal_error"
                if sub.type == Submission.TYPE_SUBMIT:
                    sub.save()
                return [], [], [], []

            logger.info("Overall result: '" + overall_result + "'")

            # Check for compile error
            if overall_result == "compile_error\n":
                logger.info("Compile error")
                sub.result = "compile_error"
                sub.delete()
                sub.compile = readFile(f"/tmp/{sub.id}/out/compile_error.txt")
                return None, None, None, None

            # Submission ran; process test results

            inputs = []
            outputs = []
            answers = []
            errors = []
            results = []
            result = "ok"

            all_samples_correct = True
            for i in range(numTests):
                if sub.type == Submission.TYPE_CUSTOM:
                    inputs.append(sub.custominput)
                    answers.append("")
                else:
                    inputs.append(sub.problem.testData[i].input)
                    answers.append(
                        readFile(f"/db/problems/{prob.id}/output/out{i}.txt"))

                errors.append(readFile(f"/tmp/{sub.id}/out/err{i}.txt"))
                outputs.append(readFile(f"/tmp/{sub.id}/out/out{i}.txt"))

                anstrip = strip(answers[-1])
                outstrip = strip(outputs[-1])
                answerLines = anstrip.split('\n')
                outLines = outstrip.split('\n')

                res = readFile(f"/tmp/{sub.id}/out/result{i}.txt")
                if res == None:
                    res = "tle"
                elif res == "ok" and anstrip != outstrip:
                    if sub.type == Submission.TYPE_CUSTOM:
                        pass  # custom input cannot produce incorrect result
                    elif compareStrings(outLines, answerLines):
                        res = "incomplete_output"
                    elif compareStrings(answerLines, outLines):
                        res = "extra_output"
                    else:
                        res = "wrong_answer"

                results.append(res)

                # Make result the first incorrect result
                if res != "ok" and result == "ok":
                    result = res

                if i < prob.samples and res != "ok":
                    all_samples_correct = False

            may_autojudge = True
            if res == "wrong_answer" and sub.result == "presentation_error":
                # During a rejudge, do not replace "presentation_error" with "wrong_answer"
                pass
            else:
                sub.result = result

            if Contest.getCurrent():
                if Contest.getCurrent(
                ).tieBreaker and all_samples_correct and sub.result in [
                        "runtime_error", "tle"
                ]:
                    # Force review of submissions where all sample tests were correct if samples break ties
                    may_autojudge = False

            if sub.result == "ok" or sub.type == Submission.TYPE_TEST or (
                    may_autojudge and sub.result in ["runtime_error", "tle"]):
                sub.status = Submission.STATUS_JUDGED

            sub.results = results

            logger.debug(f"Result of testing {sub.id}: {sub}")

            saveData(sub, inputs, 'in')
            saveData(sub, outputs, 'out')
            saveData(sub, answers, 'answer')
            saveData(sub, errors, 'error')
            if sub.type == Submission.TYPE_SUBMIT:
                sub.save()

            return inputs, outputs, answers, errors

        finally:
            shutil.rmtree(f"/tmp/{sub.id}", ignore_errors=True)
예제 #14
0
def saveData(sub: Submission, data: list, fileType: str):
    for i in range(len(data)):
        if sub.type == Submission.TYPE_SUBMIT:
            writeFile(f"/db/submissions/{sub.id}/{fileType}{i}.txt", data[i])
        data[i] = Submission.truncateForDisplay(data[i])
예제 #15
0
 def __init__(self, submission: Submission, user, force):
     subTime = submission.timestamp
     probName = submission.problem.title
     cls = "red" if submission.result != "ok" else ""
     self.html = div(
         cls="modal-content",
         contents=[
             div(cls=f"modal-header {cls}",
                 contents=[
                     h.h5(
                         f"{probName} from {submission.user.username} at ",
                         h.span(subTime, cls="time-format"),
                         f" (id {submission.id})",
                     ), """
             <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                 <span aria-hidden="true">&times;</span>
             </button>"""
                 ]),
             div(cls="modal-body",
                 contents=[
                     h.input(type="hidden",
                             id="version",
                             value=f"{submission.version}"),
                     h.strong(
                         "Result: ",
                         h.select(
                             cls=f"result-choice {submission.id}",
                             contents=[*resultOptions(submission.result)])),
                     h.strong(
                         "&emsp;Status: ",
                         h.select(
                             cls=f"status-choice {submission.id}",
                             contents=[*statusOptions(submission.status)])),
                     h.span("&emsp;"),
                     h.button(
                         "Save",
                         type="button",
                         onclick=
                         f"changeSubmissionResult('{submission.id}', '{submission.version}')",
                         cls="btn btn-primary"),
                     h.span(" "),
                     h.button("Retest",
                              type="button",
                              onclick=f"rejudge('{submission.id}')",
                              cls="btn btn-primary rejudge"),
                     h.span(" "),
                     h.button("Download",
                              type="button",
                              onclick=f"download('{submission.id}')",
                              cls="btn btn-primary rejudge"),
                     h.br(),
                     h.br(),
                     h.strong(
                         f"Language: <span class='language-format'>{submission.language}</span>"
                     ),
                     h.code(code_encode(submission.code), cls="code"),
                     div(cls="result-tabs",
                         id="result-tabs",
                         contents=[
                             h.ul(*map(lambda x: TestCaseTab(x, submission),
                                       enumerate(submission.results))),
                             *map(
                                 lambda x: TestCaseData(x, submission),
                                 zip(
                                     range(submission.problem.tests),
                                     submission.readFilesForDisplay('in'),
                                     submission.readFilesForDisplay('out'),
                                     submission.readFilesForDisplay(
                                         'error'),
                                     submission.readFilesForDisplay(
                                         'answer')))
                         ])
                 ])
         ])
예제 #16
0
 def __init__(self, x, cont):
     num, prob = x
     subs = filter(
         lambda sub: sub.problem == prob and cont.start <= sub.timestamp <=
         cont.end, Submission.all())
     self.html = div(*map(SubmissionCard, subs), id=f"tabs-{num}")
예제 #17
0
def judge_submission_close(request):
    submission = Submission.get(request.POST["id"])
    user = User.getCurrent(request)
    if submission.checkout == user.id:
        submission.checkout = None
    return JsonResponse('ok', safe=False)
예제 #18
0
def contestant_submission(request, *args, **kwargs):
    return HttpResponse(SubmissionCard(Submission.get(kwargs.get('id'))))
예제 #19
0
def addSubmission(probId, lang, code, user, type, custominput):
    sub = Submission()
    sub.problem = Problem.get(probId)
    sub.language = lang
    sub.code = code
    sub.result = Submission.RESULT_PENDING
    sub.custominput = custominput
    sub.user = user
    sub.timestamp = time.time() * 1000
    sub.type = type
    sub.status = Submission.STATUS_REVIEW

    if type == Submission.TYPE_SUBMIT:
        sub.save()
    else:
        sub.id = str(uuid4())

    return sub