예제 #1
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)
예제 #2
0
    def __init__(self, id=None):
        if id != None:
            details = getKey(f"/submissions/{id}/submission.json")
            self.id = details["id"]
            self.user = User.get(details["user"]) or User.getByName(details["user"])    # Ensures backward compatibility with older db's
            self.problem = Problem.get(details["problem"])
            self.timestamp = int(details["timestamp"])
            self.language = details["language"]
            self.code = details["code"]
            self.type = details["type"]
            self.results = details["results"]
            self.result = details["result"]
            self.status = details.get("status", None)
            self.checkout = None  # On server restart, all judges lose their checkouts
            self.version = 0
        else:
            self.id = None
            self.user = None     # Instance of User
            self.problem = None     # Instance of Problem
            self.timestamp = 0        # Time of submission (in milliseconds from time.time() * 1000)
            self.language = None
            self.code = None     # Source code
            self.type = None
            self.results = []      # One result for each test case
            self.result = None     # Overall result
            self.status = None     # One of Submission.STATUS_REVIEW, Submission.STATUS_JUDGED
            self.checkout = None     # id of judge that has submission checked out
            self.version = 1        # Version number for judge changes to this record

        self.inputs = []      # For display only
        self.outputs = []     # For display only
        self.errors = []      # For display only
        self.answers = []     # For display only
        self.compile = None   # Compile error
예제 #3
0
def createUser(request):
    newPassword = generatePassword()
    user = User(
        request.POST["username"],
        request.POST["fullname"],
        newPassword,
        request.POST["type"]
    )
    user.save()
    return JsonResponse(newPassword, safe=False)
예제 #4
0
def sendMessage(request):
    message = Message()
    user = User.getCurrent(request)
    message.fromUser = user
    message.message = html_encode(request.POST["message"])
    message.timestamp = time.time() * 1000
    if user.isAdmin():
        message.toUser = User.get(request.POST["to"])
        message.isGeneral = request.POST["to"] == "general"
        message.replyTo = request.POST.get("replyTo")
    else:
        message.isAdmin = True
    message.save()
    return JsonResponse("ok", safe=False)
예제 #5
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))))
예제 #6
0
def submit(request, *args, **kwargs):
    user = User.getCurrent(request)
    probId = request.POST["problem"]
    lang = request.POST["language"]
    code = request.POST["code"]
    type = request.POST["type"]  # Submission.TYPE_*
    custominput = request.POST.get("input")
    submission = addSubmission(probId, lang, code, user, type, custominput)
    if submission.type == Submission.TYPE_TEST and not submission.problem.samples:
        return JsonResponse({
            "result":
            "internal_error",
            "error":
            "Cannot run test because no sample test cases are defined for this problem. Make sure Number of Sample Cases for this problem is at least 1."
        })

    inputs, outputs, answers, errors = runCode(submission, user)
    response = submission.toJSON()
    if (submission.type == Submission.TYPE_SUBMIT
            or (submission.type == Submission.TYPE_TEST and user.isAdmin())):
        response["result"] = submission.getContestantResult()
        response["results"] = submission.getContestantIndividualResults()

    response["inputs"] = inputs
    response["outputs"] = outputs
    response["answers"] = answers
    response["errors"] = errors
    return JsonResponse(response)
예제 #7
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)
예제 #8
0
def getUsers(request):
    userLists = []
    tmp = []

    for user in User.all():
        tmp.append(user)
        if len(tmp) == 16:
            userLists.append(tmp)
            tmp = []

    if tmp != []:
        userLists.append(tmp)

    users = []
    for lst in userLists:
        users.append(div(*map(UserCard, lst), cls="page-break row"))

    return HttpResponse(
        Page(
            h2("Users", cls="page-title"),
            div(cls="actions",
                contents=[
                    h.button("+ Create Admin",
                             cls="button button-blue create-admin",
                             onclick="createUser('admin')"),
                    h.button("+ Create Participant",
                             cls="button create-participant",
                             onclick="createUser('participant')")
                ]), div(cls="user-cards", contents=users)))
예제 #9
0
def getSubmissions(request, *args, **kwargs):
    submissions = []

    cont = Contest.getCurrent()
    if not cont:
        return HttpResponse(
            Page(h1("&nbsp;"), 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")])
                ])))
예제 #10
0
 def __init__(self, id=None):
     if id != None:
         details = getKey(f"/messages/{id}/message.json")
         self.id = details["id"]
         self.fromUser = User.get(details["from"])
         self.toUser = User.get(details["to"])
         self.isGeneral = bool(details["general"])  # General announcement
         self.isAdmin = bool(details["admin"])  # Message sent to admin
         self.message = details["message"]
         self.timestamp = float(details["timestamp"])
         self.replyTo = details.get("replyTo")
     else:
         self.id = None
         self.fromUser = None
         self.toUser = None
         self.isGeneral = False
         self.isAdmin = False
         self.message = ""
         self.timestamp = 0
         self.replyTo = None
예제 #11
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))
예제 #12
0
def viewProblem(request, *args, **kwargs):
    problem = Problem.get(kwargs.get('id'))
    user = User.getCurrent(request)

    contest = Contest.getCurrent()

    if not problem:
        return JsonResponse(data='', safe=False)

    if not user.isAdmin():
        # Hide the problems till the contest begins for non-admin users
        if not Contest.getCurrent():
            return JsonResponse(data='', safe=False)
        if problem not in Contest.getCurrent().problems:
            return JsonResponse(data='', safe=False)
    contents = []
    if contest == None or contest.showProblInfoBlocks == "On":
        contents = [
            Card("Problem Statement", formatMD(problem.statement), cls="stmt"),
            Card("Input Format", formatMD(problem.input), cls="inp"),
            Card("Output Format", formatMD(problem.output), cls="outp"),
            Card("Constraints",
                 formatMD(problem.constraints),
                 cls="constraints"),
        ]
    contents.append(
        div(cls="samples",
            contents=list(
                map(lambda x: getSample(x[0], x[1]),
                    zip(problem.sampleData, range(problem.samples))))))

    return HttpResponse(
        Page(
            h.input(type="hidden", id="problem-id", value=problem.id),
            h2(problem.title, cls="page-title"),
            div(cls="problem-description", contents=contents), CodeEditor(),
            div(cls="stmt card ui-sortable-handle blk-custom-input",
                contents=[
                    div(cls="card-header",
                        contents=[h2("Custom Input", cls="card-title")]),
                    div(cls="card-contents",
                        contents=[h.textarea(id="custom-input", cls="col-12")])
                ]),
            div(cls="align-right",
                id="custom-code-text",
                contents=[
                    h.input("Custom Input",
                            type="checkbox",
                            id="use-custom-input"),
                    h.button("Test Code",
                             cls="button test-samples button-white"),
                    h.button("Submit Code", cls="button submit-problem")
                ])))
예제 #13
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)
            ]))
예제 #14
0
def getMessages(request):
    timestamp = float(request.POST["timestamp"])
    user = User.getCurrent(request)
    newTime = time.time() * 1000
    messages = Message.messagesSince(timestamp)
    applicable = [
        message.toJSON() for message in messages
        if (message.toUser and message.toUser.id == user.id)
        or message.isGeneral or (message.isAdmin and user.isAdmin())
        or message.fromUser.id == user.id
    ]
    applicable = sorted(applicable,
                        key=lambda msg: msg["timestamp"],
                        reverse=True)
    return JsonResponse({"messages": applicable, "timestamp": newTime})
예제 #15
0
 def __init__(self, user: User):
     cls = "blue" if user.isAdmin() else ""
     self.html = div(cls="col-3",
                     contents=[
                         Card(div(
                             h.strong(h.i("Username:"******"username-hidden"),
                             h.br(cls="username-hidden"),
                             h.p("&quot;", cls="username-hidden"),
                             h2(user.username, cls="card-title"),
                             h.p("&quot;", cls="username-hidden")),
                              div(h.strong(h.i("Fullname:")), h.br(),
                                  f"&quot;{user.fullname}&quot;", h.br(),
                                  h.strong(h.i("Password:"******"&quot;{user.password}&quot;"),
                              delete=f"deleteUser('{user.username}')",
                              cls=cls)
                     ])
예제 #16
0
 def __init__(self, sub):
     checkoutUser = User.get(sub.checkout)
     self.html = h.tr(
         h.td(sub.user.username),
         h.td(sub.problem.title),
         h.td(sub.id),  # cls='time-format', contents=sub.timestamp
         h.td(sub.language),
         h.td(h.i("&nbsp;", cls=f"fa fa-{icons.get(sub.result)}"),
              h.span(verdict_name.get(sub.result))),
         h.td(contents=[
             sub.status,
             h.p(sub.version, id=f"{sub.id}-version", hidden=True)
         ]),
         h.td(
             checkoutUser.username if checkoutUser is not None else "None"),
         id=sub.id,
         cls="submit-row",
     )
예제 #17
0
def listProblems(request):
    user = User.getCurrent(request)
    if Contest.getCurrent() or (Contest.getPast() and user.isAdmin()):
        contest = Contest.getCurrent() or Contest.getPast()
        probCards = []
        for prob in contest.problems:
            probCards.append(ProblemCard(prob, user))

        return HttpResponse(Page(h2("Problems", cls="page-title"), *probCards))
    elif Contest.getFuture():
        contest = Contest.getFuture()
        return HttpResponse(
            Page(h1("&nbsp;"), h1("Contest Starts in", cls="center"),
                 h1(contest.start, cls="countdown jumbotron center")))
    elif Contest.getPast():
        return HttpResponse(
            Page(h1("&nbsp;"), h1("Contest is Over", cls="center")))
    return HttpResponse(
        Page(h1("&nbsp;"), h1("No Contest Created", cls="center")))
예제 #18
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)
예제 #19
0
def deleteUser(request):
    username = request.POST["username"]
    user = User.getByName(username)
    user.delete()
    return JsonResponse("ok", safe=False)
예제 #20
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)
예제 #21
0
def leaderboard(request):
    contest = Contest.getCurrent() or Contest.getPast()
    user = User.getCurrent(request)
    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

    subs = get_user_subs_map(contest)
    
    problemSummary = {}
    for prob in contest.problems:
        problemSummary[prob.id] = [0, 0]

    scores = []
    for userid in subs:
        usersubs = subs[userid]
        scor = score(usersubs, contest, problemSummary)

        # Set displayName to fullname if displayFullname option is true,
        # otherwise, use the username
        displayName = User.get(userid).fullname if contest.displayFullname == True else User.get(userid).username
        
        scores.append((
            displayName,
            scor[0],
            scor[1],
            scor[2],
            scor[3]
        ))
    scores = sorted(scores, key=lambda score: score[1] * 1000000000 + score[2] * 10000000 - score[3], reverse=True)
    
    ranks = [i + 1 for i in range(len(scores))]
    for i in range(1, len(scores)):
        u1 = scores[i]
        u2 = scores[i - 1]
        if (u1[1], u1[2], u1[3]) == (u2[1], u2[2], u2[3]):
            ranks[i] = ranks[i - 1]
    
    scoresDisplay = []
    for (name, solved, samples, points, attempts), rank in zip(scores, ranks):
        scoresDisplay.append(h.tr(
            h.td(rank, cls="center"),
            h.td(name),
            h.td(attempts, cls="center"),
            h.td(solved, cls="center"),
            h.td(samples, cls="center"),
            h.td(points, cls="center")
        ))

    problemSummaryDisplay = []
    for problem in contest.problems:
        problemSummaryDisplay.append(h.tr(
            h.td(problem.title),
            h.td(problemSummary[problem.id][0], cls="center"),
            h.td(problemSummary[problem.id][1], cls="center")
        ))

    return HttpResponse(Page(
        h2("Leaderboard", cls="page-title"),
        div(cls="actions", contents=[
            h.button("Detailed Contest Report", cls="button create-message", onclick="window.location.href='/contestreport'")
        ]),
        h.table(cls="banded", contents=[
            h.thead(
                h.tr(
                    h.th("Rank", cls="center"),
                    h.th("User"),
                    h.th("Attempts", cls="center"),
                    h.th("Problems Solved", cls="center"),
                    h.th("Sample Cases Solved", cls="center"),
                    h.th("Penalty Points", cls="center")
                )
            ),
            h.tbody(
                *scoresDisplay
            )
        ]),
        h2("Problem Summary", cls="page-title"),
        h.table(cls="banded", contents=[
            h.thead(
                h.tr(
                    h.th("Problem", cls="center"),
                    h.th("Attempts", cls="center"),
                    h.th("Solved", cls="center"),
                )
            ),
            h.tbody(
                *problemSummaryDisplay
            )
        ]),
        div(cls="align-right", contents=[
            h.br(),
            h.button("Correct Log", cls="button", onclick="window.location='/correctlog'")
        ] if user and user.isAdmin() else []
        )
    ))
예제 #22
0
def contestreport(request):
    contest = Contest.getCurrent() or Contest.getPast()
    user = User.getCurrent(request)
    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
    problemSummaryreport = []
    
    subs = get_user_subs_map(contest) 

    if start <= time.time() <= end:
        reportcols = [h.th("Rank"), h.th("Contestant"), h.th("Contestant ID"), h.th("Correct"), h.th("Penalty"), ]
    else:
        reportcols = [h.th("Rank"), h.th("Contestant ID"), h.th("Correct"), h.th("Penalty"), ]

    problemSummary = {}
    problems = []
    problemNum = 0
    for prob in contest.problems:
        problemSummary[prob.id] = [0, 0]
        problemNum += 1
        problems.append(prob.id)
        problemSummaryreport.append({"id":prob.id,"title":prob.title,"attempts":0,"correct":0}) 
        reportcols.append(h.th(f"{problemNum}", cls="center"))
    
    scores = []
    for user in subs:
        usersubs = subs[user]
        scor = score(usersubs, contest, problemSummary)
        scores.append((
            User.get(user).username,
            scor[0],
            scor[1],
            scor[2],
            scor[3],
            user
        ))
    
    scores = sorted(scores, key=lambda score: score[1] * 1000000000 + score[2] * 10000000 - score[3], reverse=True)
    ranks = [i + 1 for i in range(len(scores))]
    for i in range(1, len(scores)):
        u1 = scores[i]
        u2 = scores[i - 1]
        if (u1[1], u1[2], u1[3]) == (u2[1], u2[2], u2[3]):
            ranks[i] = ranks[i - 1]

    log = []
    for (name, solved, samples, points, attempts, userid), rank in zip(scores, ranks):
        log.append({"rank": rank, "name": name, "userid": userid, "solved": solved, "points": points})
    
    detailedContestDisplay = []
    for person in log:
        outproblems = []
        submissions = sorted(subs[person["userid"]], key=lambda sub: sub.timestamp) 
        for p in problems:
            p_trys = 0
            earliest_time = 0
            for s in submissions:
                if p == s.problem.id:
                    p_trys += 1
                    if s.result == "ok":
                        earliest_time = s.timestamp
                        break

            if earliest_time: 
                outproblems.append(h.td(f"({p_trys}) {datetime.utcfromtimestamp((earliest_time - start) / 1000).strftime('%H:%M')}"))
                for prob in problemSummaryreport:
                    if prob['id'] == p:
                        prob["attempts"] += p_trys
                        prob["correct"] += 1
                        prob[s.language] = prob.get(s.language, 0) + 1
                        
            elif p_trys:      
                outproblems.append(h.td(f"({p_trys}) -- "))
                for prob in problemSummaryreport:
                    if prob['id'] == p:
                        prob["attempts"] += p_trys
                
            else:
                outproblems.append(h.td(f""))
        
        # Previous logic checked to make sure user was a valid object
        # before retrieving its members. That is why this code does as
        # well
        user = User.getByName(person["name"])
        if user:
            # Set displayName to fullname if displayFullname option is true,
            # otherwise, use the username
            displayName = user.fullname if contest.displayFullname == True else user.username
        else:
            displayName = person["name"]
        
        detailedContestDisplay.append(h.tr(
            h.td(person["rank"]),
            h.td(displayName),
            h.td(person["name"]) if start  <= time.time() <=  end else "",
            h.td(person["solved"]),
            h.td(person["points"]),
            *outproblems
        ))

    lang_col = [h.td("#"), h.td("Title")]
    for lan in all_languages:
        lang_col.append(h.td(all_languages[lan]))
    lang_col.append(h.td("Total Count"))
    problemSummaryDisplay =[]
    LanguageDisplay = []
    i = 0
    for prob in problemSummaryreport:

        i += 1
        problemSummaryDisplay.append(h.tr(
            h.td(i),
            h.td(prob["title"]),
            h.td(prob["attempts"]),
            h.td(prob["correct"]),
        ))

        langcount = []
        total = 0
        for lan in all_languages:
            if lan in prob:
                total += prob[lan]
                langcount.append(h.td(prob[lan]))
            else: langcount.append(h.td(""))

        LanguageDisplay.append(h.tr(
            h.td(i),
            h.td(prob["title"]),
            *langcount,
            h.td(total) if total > 0 else h.td("")
        ))

    return HttpResponse(Page(
        h2("DETAILED STANDINGS", cls="page-title"),
        h.table(cls="banded", contents=[
            h.thead(h.tr(*reportcols)),
            h.tbody(*detailedContestDisplay)
        ]),
        h2("Problem Summary", cls="page-title"),
        h.table(cls="banded", contents=[
            h.thead(
                h.tr(
                    h.td("#"),
                    h.td("Title"),
                    h.td("Attempts"),
                    h.td("Correct")
                )
            ),
            h.tbody(*problemSummaryDisplay)
        ]),
        h2("Language Breakdown", cls="page-title"),
        h.table(cls="banded", contents=[
            h.thead(h.tr(*lang_col)
            ),h.tbody(*LanguageDisplay)
        ]),
        cls='wide-content' # Use a wide format for this page
    ))
예제 #23
0
def displayMessages(request, *args, **kwargs):
    user = User.getCurrent(request)

    messages = []
    if INBOX in request.path:
        if user.isAdmin():
            inbox = {}
            Message.forEach(lambda msg: inbox.update({msg.id: msg})
                            if msg.isAdmin else None)

            # Remove from inbox messages that have been responded to
            Message.forEach(lambda msg: inbox.pop(msg.replyTo)
                            if msg.replyTo in inbox else None)
            messages = list(inbox.values())
        else:
            Message.forEach(lambda msg: messages.append(msg)
                            if (msg.toUser and msg.toUser.id == user.id or msg.
                                fromUser == user or msg.isGeneral) else None)

    elif PROCESSED in request.path:

        def addReply(msg):
            if msg.replyTo in replies:
                replies[msg.replyTo].append(msg)
            else:
                replies[msg.replyTo] = [msg]

        # Find replies
        replies = {}
        Message.forEach(lambda msg: addReply(msg) if msg.replyTo else None)

        messages = [[Message.get(id)] + replies[id] for id in replies.keys()]

    elif ANNOUNCEMENT in request.path:
        Message.forEach(lambda msg: messages.append(msg)
                        if msg.isGeneral else None)

    if len(messages) > 0 and not isinstance(messages[0], list):
        messages = [[msg] for msg in messages]

    messages = [
        *map(lambda msglist: MessageCard(msglist, user),
             sorted(messages, key=lambda msglist: -msglist[0].timestamp))
    ]

    adminDetails = []
    if user.isAdmin():
        userOptions = [
            *map(lambda usr: h.option(usr.username, value=usr.id), User.all())
        ]
        adminDetails = [
            h.h5("To"),
            h.select(cls="form-control recipient",
                     contents=[h.option("general"), *userOptions]),
            h.input(type="hidden", id="replyTo"),
            h.h5("Message")
        ]

    if user.isAdmin():
        filter = div(
            a(href='inbox', contents="Inbox"),
            ' | ',
            a(href='processed', contents="Handled"),
            ' | ',
            a(href='announcements', contents="Announcements"),
        )
    else:
        filter = div()

    return HttpResponse(
        Page(
            h2("Messages", cls="page-title"),
            div(cls="actions",
                contents=[
                    h.button("+ Send Message",
                             cls="button create-message",
                             onclick="createMessage()")
                ]),
            filter,
            Modal(
                "Send Message",
                div(*adminDetails, h.textarea(cls="message col-12")),
                div(
                    h.button(
                        "Cancel", **{
                            "type": "button",
                            "class": "button button-white",
                            "data-dismiss": "modal"
                        }),
                    h.button(
                        "Send", **{
                            "type": "button",
                            "class": "button",
                            "onclick": "sendMessage()"
                        }))),
            div(cls="message-cards", contents=messages),
        ))
예제 #24
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)
예제 #25
0
It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

from contest.auth import generatePassword
from contest.models.user import User

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'opencontest.settings')

user = '******'

usr = User.getByName(user)
if usr:
    password = usr.password
else:
    password = generatePassword()
    usr = User(user, 'Administrator', password, 'admin')
    usr.save()

print(f'Admin username is "{user}".')
print(f'Admin password is "{password}".')

print('Starting server...')
application = get_wsgi_application()