Skip to content
Open
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
44 changes: 38 additions & 6 deletions tabbycat/draw/views.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import copy
import datetime
import json
import logging
import unicodedata
from itertools import product
from zoneinfo import ZoneInfo

from django.conf import settings
from django.contrib import messages
from django.core.cache import cache
from django.db import DatabaseError, transaction
from django.db.models import OuterRef, Subquery
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils import timezone
from django.utils.cache import get_cache_key
from django.utils.functional import cached_property
from django.utils.html import escape, format_html
from django.utils.safestring import mark_safe
Expand Down Expand Up @@ -64,6 +67,16 @@
logger = logging.getLogger(__name__)


def invalidate_draw_release_caches(tournament, request):
"""Invalidate page cache for PublicDrawForCurrentRoundsView and TournamentPublicHomeView
when the draw is released or unreleased, so the public sees updated content."""
fake_request = copy.deepcopy(request)
fake_request.method = 'GET'
for view_name in ('tournament-public-index', 'draw-public-current-rounds'):
fake_request.path = reverse(view_name, kwargs={'tournament_slug': tournament.slug})
cache.delete(get_cache_key(fake_request))


class BaseDisplayDrawTableView(TournamentMixin, VueTableTemplateView):
"""Base class for views showing a draw table to the public in some way.
Subclasses are *not* necessarily public views; they may be admin/assistant
Expand Down Expand Up @@ -110,7 +123,6 @@ def get_debates_for_round(cls, round):
return round.debate_set_with_prefetches()

def get_tables(self):

# If the view has debates specified specifically, use those in a single table
if hasattr(self, 'get_debates'):
table = PublicDrawTableBuilder(view=self, sort_key=self.sort_key,
Expand Down Expand Up @@ -229,6 +241,17 @@ class PublicDrawForCurrentRoundsView(PublicDrawMixin, BaseDisplayDrawForCurrentR
def is_page_enabled(self, tournament):
return tournament.pref('public_draw') == 'current'

def get_tables(self):
cached_tables = []
for round in self.rounds: # Only return cached tables if all rounds are cached
if cached_table := cache.get('public_draw_table.%s.%s' % (round.id, self.request.LANGUAGE_CODE)):
cached_tables.append(cached_table)
else:
break
else:
return json.dumps(cached_tables)
return super().get_tables()


# ==============================================================================
# Viewing Draw (Briefing Room)
Expand Down Expand Up @@ -793,10 +816,12 @@ def post(self, request, *args, **kwargs):
self.round.draw_status = Round.Status.RELEASED
self.round.save()
self.log_action()

if settings.ENABLE_PUSH_NOTIFICATIONS:
self.send_push_notifications()

cache.set(
'public_draw_table.%s.%s' % (self.round.id, request.LANGUAGE_CODE),
json.dumps([t.jsondict() for t in PublicDrawForCurrentRoundsView(tournament=self.tournament, request=request).get_tables()]),
30, # 30 seconds
)
invalidate_draw_release_caches(self.tournament, request)
messages.success(request, _("Released the draw."))
return super().post(request, *args, **kwargs)

Expand Down Expand Up @@ -860,6 +885,12 @@ def post(self, request, *args, **kwargs):
self.round.draw_status = Round.Status.TEAMS_RELEASED
self.round.save()
self.log_action()
cache.set(
'public_draw_table.%s.%s' % (self.round.id, request.LANGUAGE_CODE),
json.dumps([t.jsondict() for t in PublicDrawForCurrentRoundsView(tournament=self.tournament, request=request).get_tables()]),
30, # 30 seconds
)
invalidate_draw_release_caches(self.tournament, request)

messages.success(request, _("Released the draw (teams only)."))
return super().post(request, *args, **kwargs)
Expand All @@ -878,6 +909,7 @@ def post(self, request, *args, **kwargs):
self.round.draw_status = Round.Status.CONFIRMED
self.round.save()
self.log_action()
invalidate_draw_release_caches(self.tournament, request)
messages.success(request, _("Unreleased the draw."))
return super().post(request, *args, **kwargs)

Expand Down
5 changes: 3 additions & 2 deletions tabbycat/utils/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from django.views.generic import TemplateView, View
from django.views.generic.base import ContextMixin, TemplateResponseMixin

from .tables import BaseTableBuilder

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -62,10 +64,9 @@ class VueTableTemplateView(TemplateView):
def get_context_data(self, **kwargs):
tables = self.get_tables()

tables_dicts = [tb.jsondict() for tb in tables if tb is not None]
tables_dicts = [tb.jsondict() if isinstance(tb, BaseTableBuilder) else tb for tb in tables if tb is not None]
kwargs["tables_data"] = json.dumps(tables_dicts)

kwargs["tables_count"] = list(range(len(tables)))
kwargs["tables_orientation"] = self.tables_orientation
return super().get_context_data(**kwargs)

Expand Down