Skip to content

Commit

Permalink
Add dedicated Practice / Contest Scoreboard buttons
Browse files Browse the repository at this point in the history
Fixes #214
  • Loading branch information
jdabtieu committed Oct 27, 2023
1 parent df6895b commit e0533d4
Show file tree
Hide file tree
Showing 16 changed files with 55 additions and 39 deletions.
12 changes: 9 additions & 3 deletions src/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,8 +678,8 @@ def problems():
categories.sort(key=lambda x: x['category'])

is_ongoing_contest = len(db.execute(
("SELECT id AS n FROM contests WHERE end > datetime('now') AND "
"start <= datetime('now') ORDER BY end DESC")))
"SELECT * FROM contests WHERE end > datetime('now') AND start <= datetime('now')"
))

return render_template('problem/problems.html',
data=data, solved=solved, length=-(-length // 50),
Expand Down Expand Up @@ -786,7 +786,13 @@ def profile(username):
@app.route("/ranking")
def ranking():
user_info = db.execute("SELECT * FROM users WHERE verified=1 ORDER BY total_points DESC")

Check failure on line 788 in src/application.py

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

E501 line too long (93 > 90 characters)

Check failure on line 788 in src/application.py

View workflow job for this annotation

GitHub Actions / build (windows-latest)

E501 line too long (93 > 90 characters)
return render_template("ranking.html", user_data=user_info)

is_ongoing_contest = len(db.execute(
"SELECT * FROM contests WHERE end > datetime('now') AND start <= datetime('now')"
))

return render_template("ranking.html", user_data=user_info,
is_ongoing_contest=is_ongoing_contest)


# Error handling
Expand Down
29 changes: 12 additions & 17 deletions src/templates/contest/contest.html
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}{{ title }}{% endblock %}
{% block active %}Contests{% endblock %}

{% block main %}
<div style="position: relative; margin-bottom: 0.5rem;">
<h1 style="display: inline;">{{ title }}</h1>
{% if scoreboard or check_perm(["ADMIN", "SUPERADMIN"]) %}
{% if check_perm(["ADMIN", "SUPERADMIN"]) %}
<div class="dropdown" style="display: inline; margin-left: 4px;">
<button class="btn btn-secondary dropdown-toggle" type="button"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
style="margin-top: -18px;">Actions</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
{% if scoreboard %}
<a class="dropdown-item" href="{{ request.path }}/scoreboard">Scoreboard</a>
{% endif %}
{% if check_perm(["ADMIN", "SUPERADMIN"]) %}
<a class="dropdown-item"
href="/admin/submissions?contest_id={{ request.path[9:] }}">Submissions</a>
<a class="dropdown-item"
href="{{ request.path }}/addproblem">Add Problem</a>
<a class="dropdown-item"
href="{{ request.path }}/drafts">View Draft Problems</a>
<a class="dropdown-item"
href="{{ request.path }}/notify">Notify Participants</a>
<a class="dropdown-item"
href="/api/contest/scoreboard/{{ request.path[9:] }}?key={{ scoreboard_key }}">Export CTFtime Scoreboard</a>
{% endif %}
<a class="dropdown-item"
href="/admin/submissions?contest_id={{ request.path[9:] }}">Submissions</a>
<a class="dropdown-item"
href="{{ request.path }}/addproblem">Add Problem</a>
<a class="dropdown-item"
href="{{ request.path }}/drafts">View Draft Problems</a>
<a class="dropdown-item"
href="{{ request.path }}/notify">Notify Participants</a>
<a class="dropdown-item"
href="/api/contest/scoreboard/{{ request.path[9:] }}?key={{ scoreboard_key }}">Export CTFtime Scoreboard</a>
</div>
</div>
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion src/templates/contest/contest_problem.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}{{ data["name"] }}{% endblock %}
{% block active %}Contests{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion src/templates/contest/contest_problem_noexist.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}Nonexistent problem{% endblock %}
{% block active %}Contests{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion src/templates/contest/create_problem.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}Create Problem{% endblock %}
{% block active %}Contests{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion src/templates/contest/draft_problems.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}{{ title }} Draft Problems{% endblock %}
{% block active %}Contests{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion src/templates/contest/edit_problem.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}Edit {{ data["name"] }}{% endblock %}
{% block active %}Contests{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion src/templates/contest/export_problem.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}Export {{ data["name"] }}{% endblock %}
{% block active %}Contests{% endblock %}
Expand Down
5 changes: 5 additions & 0 deletions src/templates/contest/layout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "layout.html" %}

{% block contest_leaderboard %}
<li><a class="nav-link" href="{{ '/'.join(request.path.split('/')[:3]) }}/scoreboard">Contest Leaderboard</a></li>
{% endblock %}
2 changes: 1 addition & 1 deletion src/templates/contest/notify.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}Notify Participants{% endblock %}
{% block active %}Contests{% endblock %}
Expand Down
4 changes: 2 additions & 2 deletions src/templates/contest/scoreboard.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% extends "layout.html" %}
{% extends "contest/layout.html" %}

{% block title %}{{ title }} Scoreboard{% endblock %}
{% block active %}Contests{% endblock %}
{% block active %}Contest Leaderboard{% endblock %}

{% block main %}
<h1><a href="{{ request.path[:-11] }}">{{ title }}</a></h1>
Expand Down
3 changes: 2 additions & 1 deletion src/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
<ul class="navbar-nav me-auto">
<li><a class="nav-link" href="/">Home</a></li>
<li><a class="nav-link" href="/problems">Practice</a></li>
<li><a class="nav-link" href="/ranking">Practice Leaderboard</a></li>
<li><a class="nav-link" href="/contests">Contests</a></li>
<li><a class="nav-link" href="/ranking">Rankings</a></li>
{% block contest_leaderboard %}{% endblock %}
{% if check_perm(["ADMIN", "SUPERADMIN", "PROBLEM_MANAGER"]) %}
<li><a class="nav-link" href="/admin/console">Admin Console</a></li>
{% endif %}
Expand Down
16 changes: 13 additions & 3 deletions src/templates/ranking.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
{% extends "layout.html" %}

{% block title %}Rankings{% endblock %}
{% block active %}Rankings{% endblock %}
{% block title %}Practice Leaderboard{% endblock %}
{% block active %}Practice Leaderboard{% endblock %}

{% block main %}
<h1>Rankings</h1>
<h1>Practice Leaderboard</h1>
{% if is_ongoing_contest %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
There is currently an ongoing contest. To view its scoreboard, go to the <a href="/contests">Contests</a> page, enter the contest, and then click "Contest Leaderboard" at the top of the page.
This scoreboard is only for <b>practice problems unrelated to the contest</b>.
<button type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="Close"></button>
</div>
{% endif %}
<div style="overflow-x: auto;">
<table class="table table-hover table-full-width">
<thead class="table-dark">
Expand Down
1 change: 1 addition & 0 deletions src/tests/test_contest.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def test_contest(client, database):

result = client.get('/contest/testingcontest/problem/helloworldtesting')
assert result.status_code == 200
assert b'Contest Leaderboard' in result.data

result = client.post('/contest/testingcontest/problem/helloworldtesting/edit', data={
'name': 'hello world 2',
Expand Down
3 changes: 2 additions & 1 deletion src/tests/test_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def test_pages(client, database):

result = client.get('/ranking')
assert result.status_code == 200
assert b'Rankings' in result.data
assert b'Practice Leaderboard' in result.data
assert b'Contest Leaderboard' not in result.data

result = client.post('/login', data={
'username': 'normal_user',
Expand Down
7 changes: 2 additions & 5 deletions src/views/contest.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ def contest(contest_id):
return redirect("/contests")

title = contest_info[0]["name"]

# Check for scoreboard permission
scoreboard = contest_info[0]["scoreboard_visible"] or check_perm(["ADMIN", "SUPERADMIN"])
scoreboard_key = contest_info[0]["scoreboard_key"]

user_info = db.execute(
Expand Down Expand Up @@ -82,7 +79,7 @@ def contest(contest_id):
}
data.append(keys)

return render_template("contest/contest.html", title=title, scoreboard=scoreboard,
return render_template("contest/contest.html", title=title,
scoreboard_key=scoreboard_key, data=data)


Expand Down Expand Up @@ -409,7 +406,7 @@ def contest_scoreboard(contest_id):
# Ensure proper permissions
if not (contest_info[0]["scoreboard_visible"] or check_perm(["ADMIN", "SUPERADMIN"])):
flash('You are not allowed to view the scoreboard!', 'danger')
return redirect("/contest/" + contest_id)
return redirect(request.referrer)

data = db.execute(
("SELECT user_id, points, lastAC, username FROM contest_users "
Expand Down

0 comments on commit e0533d4

Please sign in to comment.