Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion cmsranking/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from dataclasses import dataclass
from dataclasses import dataclass, field
import logging
import os
import sys
Expand All @@ -37,6 +37,11 @@ def default_path(name):
return os.path.join(sys.prefix, name)


@dataclass
class PublicConfig:
show_id_column: bool = False


@dataclass
class Config:
# Connection.
Expand All @@ -51,6 +56,9 @@ class Config:
username: str = "usern4me"
password: str = "passw0rd"

# UI.
public: PublicConfig = field(default_factory=PublicConfig)

# Buffers
buffer_size: int = 100

Expand Down
36 changes: 34 additions & 2 deletions cmsranking/RankingWebServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
# Needed for initialization. Do not remove.
import cmsranking.Logger # noqa
from cmscommon.eventsource import EventSource
from cmsranking.Config import load_config
from cmsranking.Config import PublicConfig, load_config
from cmsranking.Contest import Contest
from cmsranking.Entity import InvalidData
from cmsranking.Scoring import ScoringStore
Expand Down Expand Up @@ -473,6 +473,32 @@ def wsgi_app(self, environ, start_response):
return response


class PublicConfigHandler:

def __init__(self, pub_config: PublicConfig):
self.pub_config = pub_config

def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)

@responder
def wsgi_app(self, environ, start_response):
request = Request(environ)
request.encoding_errors = "strict"

response = Response()
response.status_code = 200
response.mimetype = "application/json"
print(str(self.pub_config))
response.data = json.dumps(
self.pub_config,
default=lambda o: o.__dict__,
sort_keys=True,
)

return response


class RoutingHandler:

def __init__(
Expand All @@ -482,20 +508,23 @@ def __init__(
logo_handler: ImageHandler,
score_handler: ScoreHandler,
history_handler: HistoryHandler,
public_config_handler: PublicConfigHandler,
):
self.router = Map([
Rule("/", methods=["GET"], endpoint="root"),
Rule("/history", methods=["GET"], endpoint="history"),
Rule("/scores", methods=["GET"], endpoint="scores"),
Rule("/events", methods=["GET"], endpoint="events"),
Rule("/logo", methods=["GET"], endpoint="logo"),
Rule("/config", methods=["GET"], endpoint="public_config")
], encoding_errors="strict")

self.event_handler = event_handler
self.logo_handler = logo_handler
self.score_handler = score_handler
self.history_handler = history_handler
self.root_handler = root_handler
self.public_config_handler = public_config_handler

def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
Expand All @@ -517,6 +546,8 @@ def wsgi_app(self, environ, start_response):
return self.score_handler(environ, start_response)
elif endpoint == "history":
return self.history_handler(environ, start_response)
elif endpoint == 'public_config':
return self.public_config_handler(environ, start_response)


def main() -> int:
Expand Down Expand Up @@ -593,7 +624,8 @@ def main() -> int:
os.path.join(config.lib_dir, '%(name)s'),
os.path.join(web_dir, 'img', 'logo.png')),
ScoreHandler(stores),
HistoryHandler(stores))
HistoryHandler(stores),
PublicConfigHandler(config.public))

wsgi_app = SharedDataMiddleware(DispatcherMiddleware(
toplevel_handler, {
Expand Down
20 changes: 20 additions & 0 deletions cmsranking/static/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,24 @@ var Config = new function () {
self.get_history_url = function () {
return "history";
}

self.get_public_config_url = function () {
return "config";
}
};

var PublicConfig = {
show_id_column: false
};

$.ajax({
url: Config.get_public_config_url(),
dataType: "json",
async: false,
success: function (data, status, xhr) {
PublicConfig = data;
},
error: function () {
console.error("Error while getting public configuration data");
}
});
10 changes: 5 additions & 5 deletions cmsranking/static/Scoreboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ var Scoreboard = new function () {
<th class=\"sel\"></th> \
<th class=\"rank\">Rank</th> \
<th colspan=\"10\" class=\"f_name\">First Name</th> \
<th colspan=\"10\" class=\"l_name\">Last Name</th> \
<th class=\"user_id\">ID</th> \
<th class=\"team\">Team</th>";
<th colspan=\"10\" class=\"l_name\">Last Name</th>" +
(PublicConfig.show_id_column ? "<th class=\"user_id\">ID</th>" : "") +
"<th class=\"team\">Team</th>";

var contests = DataStore.contest_list;
for (var i in contests) {
Expand Down Expand Up @@ -244,8 +244,8 @@ var Scoreboard = new function () {
<td class=\"sel\"></td> \
<td class=\"rank\">" + user["rank"] + "</td> \
<td colspan=\"10\" class=\"f_name\">" + escapeHTML(user["f_name"]) + "</td> \
<td colspan=\"10\" class=\"l_name\">" + escapeHTML(user["l_name"]) + "</td> \
<td class=\"user_id\">" + user["key"] + "</td>";
<td colspan=\"10\" class=\"l_name\">" + escapeHTML(user["l_name"]) + "</td>" +
(PublicConfig.show_id_column ? "<td class=\"user_id\">" + user["key"] + "</td>" : "");

if (user['team']) {
result += " \
Expand Down
4 changes: 4 additions & 0 deletions config/cms_ranking.sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ buffer_size = 100
#log_dir = "INSTALL_DIR/log/ranking"
# Data directory (the scoreboard data is stored here).
#lib_dir = "INSTALL_DIR/lib/ranking"

# UI
[public]
show_id_column = false