Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

database for related matches #79

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
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
17 changes: 0 additions & 17 deletions tests/vitriolic/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,6 @@
SITE_ID = 1


class DisableMigrations(object):
"""
Disable the database migrations machinery to speed up test suite.

Trick learned at http://bit.ly/2vjVpNc
"""

def __contains__(self, item):
return True

def __getitem__(self, item):
return None


MIGRATION_MODULES = DisableMigrations()


# Application definition

INSTALLED_APPS = [
Expand Down
24 changes: 6 additions & 18 deletions touchtechnology/common/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import unicode_literals

import functools
import logging
from os.path import join
Expand All @@ -10,11 +8,6 @@
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import (
DateTimeField,
ForeignKey as TreeField,
ManyToManyField,
)
from django.db.models.signals import post_save
from django.urls import reverse_lazy
from django.utils.functional import cached_property
Expand All @@ -26,11 +19,6 @@
from touchtechnology.common.default_settings import SITEMAP_ROOT
from touchtechnology.common.mixins import NodeRelationMixin

try:
from django.db.models import JSONField
except ImportError: # Django 2.2 support
from django.contrib.postgres.fields import JSONField

logger = logging.getLogger(__name__)


Expand All @@ -43,7 +31,7 @@ class SitemapNodeBase(models.Model):
blank=True,
verbose_name=_("Short title"),
help_text=_(
"This is used in navigation menus instead of the longer " "title value."
"This is used in navigation menus instead of the longer title value."
),
)

Expand All @@ -69,7 +57,7 @@ class SitemapNode(NodeRelationMixin, SitemapNodeBase):
Base class which can be used to represent the structure of the site.
"""

parent = TreeField(
parent = models.ForeignKey(
"self",
blank=True,
null=True,
Expand All @@ -87,7 +75,7 @@ class SitemapNode(NodeRelationMixin, SitemapNodeBase):
object = GenericForeignKey("content_type", "object_id")

# Migrate from related table in the content application.
kwargs = JSONField(default=dict)
kwargs = models.JSONField(default=dict)

require_https = BooleanField(
default=False,
Expand All @@ -100,7 +88,7 @@ class SitemapNode(NodeRelationMixin, SitemapNodeBase):
default=True,
verbose_name=_("Enabled"),
help_text=_(
"Set this to 'No' to disable this object and it's " "children on the site."
"Set this to 'No' to disable this object and it's children on the site."
),
)

Expand Down Expand Up @@ -135,7 +123,7 @@ class SitemapNode(NodeRelationMixin, SitemapNodeBase):
),
)

restrict_to_groups = ManyToManyField(
restrict_to_groups = models.ManyToManyField(
to="auth.Group",
blank=True,
verbose_name=_("Restrict to Groups"),
Expand All @@ -146,7 +134,7 @@ class SitemapNode(NodeRelationMixin, SitemapNodeBase):
),
)

last_modified = DateTimeField(auto_now=True)
last_modified = models.DateTimeField(auto_now=True)

def __hash__(self):
return hash(repr(self))
Expand Down
4 changes: 1 addition & 3 deletions touchtechnology/common/templatetags/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@
re.VERBOSE,
)

FORM_FIELD_TEMPLATE = get_template("touchtechnology/common/templatetags/field.html")

register = Library()


Expand Down Expand Up @@ -371,7 +369,7 @@ def field(bf, label=None):
"no_label": not bool(label),
}

return FORM_FIELD_TEMPLATE.render(context)
return render_to_string("touchtechnology/common/templatetags/field.html", context)


@register.inclusion_tag("touchtechnology/common/templatetags/analytics.html")
Expand Down
15 changes: 5 additions & 10 deletions tournamentcontrol/competition/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

from touchtechnology.admin.base import DashboardWidget
from tournamentcontrol.competition.models import Match, Stage, Team
from tournamentcontrol.competition.utils import legitimate_bye_match, team_needs_progressing
from tournamentcontrol.competition.utils import (
legitimate_bye_match,
team_needs_progressing,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -125,10 +128,7 @@ def _can_evaluate(match):
# If there are any unplayed or unprocessed matches in the preceding
# stage, then we do not want to consider this match as viable for
# progression.
logger.debug("Evaluate %r - home_team=%s home_team_eval=%s home_team_eval_related=%s", match, match.home_team, match.home_team_eval, match.home_team_eval_related)
logger.debug("Evaluate %r - away_team=%s away_team_eval=%s away_team_eval_related=%s", match, match.away_team, match.away_team_eval, match.away_team_eval_related)
if _stage_cache[match.stage_id]:
logger.warning("Can't eval %s from stage %r (%s matches)", match, match.stage, _stage_cache[match.stage_id])
return False

# If the home or away team can be determined we would want to progress
Expand All @@ -141,10 +141,8 @@ def _can_evaluate(match):
return True

if match.stage.undecided_teams.exists() and _stage_cache[match.stage_id] == 0:
logger.warning("Found undecided teams and no matches left for %s in stage %r", match, match.stage)
return True

logger.warning("Can't evaluate %r - home_team=%r away_team=%r", match, home_team, away_team)
return False

matches = [m for m in matches if _can_evaluate(m)]
Expand All @@ -167,9 +165,6 @@ def stages_require_progression():
return stages


lazy_stages_require_progression = lazy(stages_require_progression, dict)


#
# Dashboard Widgets
#
Expand Down Expand Up @@ -218,7 +213,7 @@ class ProgressStageWidget(DashboardWidget):
template = "tournamentcontrol/competition/admin/widgets/progress/stages.html"

def _get_context(self):
stages = lazy_stages_require_progression()
stages = stages_require_progression()

context = {"stages": stages}
return context
Expand Down
9 changes: 4 additions & 5 deletions tournamentcontrol/competition/managers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from django.db import models
from tournamentcontrol.competition.query import (
LadderEntryQuerySet, MatchQuerySet,
)

from tournamentcontrol.competition.query import LadderEntryQuerySet, MatchQuerySet


class LadderEntryManager(models.Manager.from_queryset(LadderEntryQuerySet)):
def get_queryset(self):
return super(LadderEntryManager, self).get_queryset()._all()
return super().get_queryset()._all()


class MatchManager(models.Manager.from_queryset(MatchQuerySet)):
def get_queryset(self):
return super(MatchManager, self).get_queryset()._rank_importance()
return super().get_queryset()._rank_importance()._team_titles()
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Generated by Django 4.2.13 on 2024-05-27 20:14

from django.db import migrations

vitriolic_stage_group_position = """
CREATE OR REPLACE FUNCTION vitriolic_stage_group_position(input_str TEXT)
RETURNS TEXT AS $$
DECLARE
stage_num INT := NULL;
group_num INT := NULL;
position_num INT;
result_str TEXT := '';
ordinal_position TEXT := '';
BEGIN
BEGIN
SELECT substring(input_str from 'S(\d+)')::INT INTO stage_num;
EXCEPTION
WHEN OTHERS THEN
stage_num := NULL;
END;

BEGIN
SELECT substring(input_str from 'G(\d+)')::INT INTO group_num;
EXCEPTION
WHEN OTHERS THEN
group_num := NULL;
END;

SELECT substring(input_str from 'P(\d+)')::INT INTO position_num;

ordinal_position := position_num ||
CASE
WHEN position_num % 10 = 1 AND position_num != 11 THEN 'st'
WHEN position_num % 10 = 2 AND position_num != 12 THEN 'nd'
WHEN position_num % 10 = 3 AND position_num != 13 THEN 'rd'
ELSE 'th'
END;

IF stage_num IS NULL AND group_num IS NULL THEN
result_str := ordinal_position;
ELSE
result_str := ordinal_position || ' ';
END IF;

IF stage_num IS NOT NULL THEN
result_str := result_str || 'Stage ' || stage_num || ' ';
END IF;

IF group_num IS NOT NULL THEN
result_str := result_str || 'Group ' || group_num || ' ';
END IF;

RETURN trim(result_str);
END;
$$ LANGUAGE plpgsql;
"""


class Migration(migrations.Migration):
dependencies = [
("competition", "0049_match_live_stream_thumbnail"),
]

operations = [
migrations.RunSQL(
vitriolic_stage_group_position,
"DROP FUNCTION IF EXISTS vitriolic_stage_group_position;",
)
]
38 changes: 22 additions & 16 deletions tournamentcontrol/competition/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,9 @@
from datetime import datetime, timedelta
from decimal import Decimal, InvalidOperation

import requests
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.http import MediaInMemoryUpload

import django
import pytz
import requests
from cloudinary.models import CloudinaryField
from dateutil.relativedelta import relativedelta
from dateutil.rrule import MINUTELY, WEEKLY, rrule, rruleset
Expand All @@ -33,7 +29,10 @@
from django.utils.functional import cached_property, lazy
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import Flow
from googleapiclient.discovery import build
from googleapiclient.http import MediaInMemoryUpload
from requests import HTTPError

from touchtechnology.admin.mixins import AdminUrlMixin as BaseAdminUrlMixin
Expand All @@ -47,15 +46,12 @@
from touchtechnology.common.models import SitemapNodeBase
from tournamentcontrol.competition.constants import (
GENDER_CHOICES,
LiveStreamPrivacy,
PYTZ_TIME_ZONE_CHOICES,
SEASON_MODE_CHOICES,
WIN_LOSE,
LiveStreamPrivacy,
)
from tournamentcontrol.competition.managers import (
LadderEntryManager,
MatchManager,
)
from tournamentcontrol.competition.managers import LadderEntryManager, MatchManager
from tournamentcontrol.competition.mixins import ModelDiffMixin
from tournamentcontrol.competition.query import (
DivisionQuerySet,
Expand Down Expand Up @@ -1946,10 +1942,14 @@ def eval(self, lazy=False):
try:
stage = self.stage.comes_after
except Stage.DoesNotExist:
logger.warning(
"Stage is first, %r should not be attempting to be " "evaluated.", self
)
return (self.home_team, self.away_team)
if self.home_team_eval_related or self.away_team_eval_related:
# This is a match that depends on the result of matches in the same stage.
stage = self.stage
else:
logger.warning(
"Stage is first, %r should not be attempting to be evaluated.", self
)
return (self.home_team, self.away_team)

positions = {
index + 1: team
Expand All @@ -1967,7 +1967,9 @@ def eval(self, lazy=False):
is_team_model = not isinstance(team, Team)
if not is_team_model:
logger.warning("%r is not a Team instance.", team)
if not lazy or not is_team_model:
if not lazy:
team = getattr(self, f"{field}_title")
elif not is_team_model:
team_undecided = getattr(self, f"{field}_undecided")
if team_undecided:
team_eval = team_undecided.formula
Expand All @@ -1983,7 +1985,11 @@ def eval(self, lazy=False):
team_eval
).groups()
except (AttributeError, TypeError):
logger.exception("Failed evaluating `stage_group_position` %s for %s", team_eval, self)
logger.exception(
"Failed evaluating `stage_group_position` %s for %s",
team_eval,
self,
)
else:
try:
try:
Expand Down
Loading
Loading