diff --git a/CTFd/cache/__init__.py b/CTFd/cache/__init__.py index a7f92d97..d452712f 100644 --- a/CTFd/cache/__init__.py +++ b/CTFd/cache/__init__.py @@ -1,5 +1,5 @@ from flask import request -from flask_caching import Cache +from flask_caching import Cache, make_template_fragment_key cache = Cache() @@ -27,6 +27,7 @@ def clear_config(): def clear_standings(): from CTFd.models import Users, Teams + from CTFd.constants.static import CacheKeys from CTFd.utils.scores import get_standings, get_team_standings, get_user_standings from CTFd.api.v1.scoreboard import ScoreboardDetail, ScoreboardList from CTFd.api import api @@ -55,11 +56,13 @@ def clear_standings(): cache.delete_memoized(get_team_place) # Clear out HTTP request responses - cache.delete(make_cache_key(path="scoreboard.listing")) cache.delete(make_cache_key(path=api.name + "." + ScoreboardList.endpoint)) cache.delete(make_cache_key(path=api.name + "." + ScoreboardDetail.endpoint)) cache.delete_memoized(ScoreboardList.get) + # Clear out scoreboard templates + cache.delete(make_template_fragment_key(CacheKeys.PUBLIC_SCOREBOARD_TABLE)) + def clear_pages(): from CTFd.utils.config.pages import get_page, get_pages diff --git a/CTFd/constants/__init__.py b/CTFd/constants/__init__.py index fc9a1baf..72b09b35 100644 --- a/CTFd/constants/__init__.py +++ b/CTFd/constants/__init__.py @@ -3,6 +3,7 @@ from enum import Enum from flask import current_app JS_ENUMS = {} +JINJA_ENUMS = {} class RawEnum(Enum): @@ -59,6 +60,7 @@ def JinjaEnum(cls): """ if cls.__name__ not in current_app.jinja_env.globals: current_app.jinja_env.globals[cls.__name__] = cls + JINJA_ENUMS[cls.__name__] = cls else: raise KeyError("{} was already defined as a JinjaEnum".format(cls.__name__)) return cls diff --git a/CTFd/constants/static.py b/CTFd/constants/static.py new file mode 100644 index 00000000..93a380f7 --- /dev/null +++ b/CTFd/constants/static.py @@ -0,0 +1,14 @@ +from CTFd.constants import JinjaEnum, RawEnum + + +@JinjaEnum +class CacheKeys(str, RawEnum): + PUBLIC_SCOREBOARD_TABLE = "public_scoreboard_table" + + +# Placeholder object. Not used, just imported to force initialization of any Enums here +class _StaticsWrapper: + pass + + +Static = _StaticsWrapper() diff --git a/CTFd/scoreboard.py b/CTFd/scoreboard.py index cb1bd88a..7e9b3409 100644 --- a/CTFd/scoreboard.py +++ b/CTFd/scoreboard.py @@ -1,6 +1,5 @@ from flask import Blueprint, render_template -from CTFd.cache import cache, make_cache_key from CTFd.utils import config from CTFd.utils.config.visibility import scores_visible from CTFd.utils.decorators.visibility import check_score_visibility @@ -13,7 +12,6 @@ scoreboard = Blueprint("scoreboard", __name__) @scoreboard.route("/scoreboard") @check_score_visibility -@cache.cached(timeout=60, key_prefix=make_cache_key) def listing(): infos = get_infos() diff --git a/CTFd/themes/core/templates/scoreboard.html b/CTFd/themes/core/templates/scoreboard.html index 9383829f..d657409f 100644 --- a/CTFd/themes/core/templates/scoreboard.html +++ b/CTFd/themes/core/templates/scoreboard.html @@ -15,6 +15,7 @@ + {% cache 60, CacheKeys.PUBLIC_SCOREBOARD_TABLE %} {% if standings %}