added new fields to KyuDanRanking that allow to pick up the calculation from the last state of the KyuDanRanking.
last_hanchan_date: it contains the start of the latest hanchan content for this players ranking. wins_in_row: to save the currents wins in a row Added option to calcuclate rankings until a given datetime.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
"""ObjectManagers for the Django Models used in the Mahjong-Ranking."""
|
||||
from datetime import date
|
||||
|
||||
from . import LOGGER
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class HanchanManager(models.Manager):
|
||||
@@ -12,7 +13,7 @@ class HanchanManager(models.Manager):
|
||||
"""
|
||||
use_for_related_fields = True
|
||||
|
||||
def confirmed_hanchans(self, user=None, **filter_args):
|
||||
def confirmed_hanchans(self, user=None, until=None, **filter_args):
|
||||
""" Return all valid and confirmed Hanchans.
|
||||
|
||||
:param user: Only return Hanchans where this user participated.
|
||||
@@ -20,9 +21,12 @@ class HanchanManager(models.Manager):
|
||||
:return: QuerySet Object
|
||||
"""
|
||||
if user:
|
||||
return self.user_hanchans(user, confirmed=True, **filter_args)
|
||||
else:
|
||||
return self.filter(confirmed=True, **filter_args)
|
||||
return self.user_hanchans(user, confirmed=True, until=until,
|
||||
**filter_args)
|
||||
hanchans = self.filter(confirmed=True, **filter_args)
|
||||
if until:
|
||||
hanchans = hanchans.filter(start__lte=until)
|
||||
return hanchans
|
||||
|
||||
def dan_hanchans(self, user, **filter_args):
|
||||
""" Return all Hanchans where a specific user has participated and had
|
||||
@@ -39,7 +43,7 @@ class HanchanManager(models.Manager):
|
||||
models.Q(player4=user, player4_dan_points__isnull=False)
|
||||
).filter(confirmed=True, **filter_args)
|
||||
queryset = queryset.select_related().order_by('-start')
|
||||
[ hanchan.get_playerdata(user) for hanchan in queryset ]
|
||||
[hanchan.get_playerdata(user) for hanchan in queryset]
|
||||
return queryset
|
||||
|
||||
def kyu_hanchans(self, user, **filter_args):
|
||||
@@ -57,20 +61,23 @@ class HanchanManager(models.Manager):
|
||||
models.Q(player4=user, player4_kyu_points__isnull=False)
|
||||
).filter(confirmed=True, **filter_args)
|
||||
queryset = queryset.select_related().order_by('-start')
|
||||
[ hanchan.get_playerdata(user) for hanchan in queryset ]
|
||||
[hanchan.get_playerdata(user) for hanchan in queryset]
|
||||
return queryset
|
||||
|
||||
def season_hanchans(self, user=None, season=None):
|
||||
def season_hanchans(self, user=None, season=None, until=None):
|
||||
"""Return all Hanchans that belong to a given or the current season.
|
||||
|
||||
:param user: Only return Hanchans where this user participated.
|
||||
:param season: the year of the wanted season, current year if None.
|
||||
:return: QuerySet Object
|
||||
"""
|
||||
season = season or date.today().year
|
||||
return self.confirmed_hanchans(user=user, season=season)
|
||||
try:
|
||||
season = season or until.year
|
||||
except AttributeError:
|
||||
season = date.today().year
|
||||
return self.confirmed_hanchans(user=user, season=season, until=until)
|
||||
|
||||
def user_hanchans(self, user, since=None, **filter_args):
|
||||
def user_hanchans(self, user, since=None, until=None, **filter_args):
|
||||
"""Return all Hanchans where a specific user has participated.
|
||||
|
||||
:param user: Return Hanchans where this user participated.
|
||||
@@ -82,12 +89,13 @@ class HanchanManager(models.Manager):
|
||||
models.Q(player1=user) | models.Q(player2=user) |
|
||||
models.Q(player3=user) | models.Q(player4=user)
|
||||
)
|
||||
queryset = queryset.filter(**filter_args)
|
||||
if since:
|
||||
queryset = queryset.filter(start__gte=since, **filter_args)
|
||||
else:
|
||||
queryset = queryset.filter(**filter_args)
|
||||
queryset = queryset.filter(start__gte=since)
|
||||
if until:
|
||||
queryset = queryset.filter(start__lte=until)
|
||||
queryset = queryset.select_related().order_by('-start')
|
||||
[ hanchan.get_playerdata(user) for hanchan in queryset ]
|
||||
[hanchan.get_playerdata(user) for hanchan in queryset]
|
||||
return queryset
|
||||
|
||||
def unconfirmed_hanchans(self, user=None, **filter_args):
|
||||
@@ -158,8 +166,27 @@ class SeasonRankingManager(models.Manager):
|
||||
})
|
||||
return json_data
|
||||
|
||||
class KyuDanRankingManager(models.Manager):
|
||||
def update(self, season=None, until=None, force_recalc=False):
|
||||
try:
|
||||
season = season or until.year
|
||||
except AttributeError:
|
||||
season = date.today().year
|
||||
if until or force_recalc:
|
||||
for ranking in self.filter(season=season):
|
||||
ranking.recalculate(until=until)
|
||||
for placement, ranking in enumerate(self.season_rankings(season)):
|
||||
ranking.placement = placement
|
||||
ranking.save(force_update=True, update_fields=['placement'])
|
||||
|
||||
def season_rankings(self, season=None):
|
||||
season = season or date.today().year
|
||||
rankings = self.filter(
|
||||
season=season,
|
||||
hanchan_count__gt=settings.MIN_HANCHANS_FOR_LADDER)
|
||||
return rankings.order_by('avg_placement', '-avg_score')
|
||||
|
||||
|
||||
class KyuDanRankingManager(models.Manager):
|
||||
def json_data(self):
|
||||
""" Get all Rankings for a given Season and return them as a list of
|
||||
dict objects, suitable for JSON exports and other processings.
|
||||
@@ -172,9 +199,12 @@ class KyuDanRankingManager(models.Manager):
|
||||
values = values.values('user_id', 'user__username',
|
||||
'user__first_name', 'user__last_name',
|
||||
'dan', 'dan_points', 'kyu', 'kyu_points',
|
||||
'hanchan_count', 'won_hanchans', 'good_hanchans')
|
||||
'hanchan_count', 'won_hanchans', 'good_hanchans',
|
||||
'last_hanchan_date')
|
||||
for user in values:
|
||||
if user['dan']:
|
||||
if user['hanchan_count'] == 0:
|
||||
continue
|
||||
elif user['dan']:
|
||||
rank = '{}. Dan'.format(user['dan'])
|
||||
points = user['dan_points']
|
||||
else:
|
||||
@@ -183,11 +213,31 @@ class KyuDanRankingManager(models.Manager):
|
||||
json_data.append({
|
||||
'user_id': user['user_id'],
|
||||
'username': user['user__username'],
|
||||
'full_name': " ".join([user['user__last_name'], user['user__first_name']]),
|
||||
'full_name': " ".join(
|
||||
[user['user__last_name'], user['user__first_name']]),
|
||||
'rank': rank,
|
||||
'points': points,
|
||||
'hanchan_count': user['hanchan_count'],
|
||||
'good_hanchans': user['good_hanchans'],
|
||||
'won_hanchans': user['won_hanchans']
|
||||
'won_hanchans': user['won_hanchans'],
|
||||
'last_hanchan_date': user['last_hanchan_date']
|
||||
|
||||
})
|
||||
return json_data
|
||||
|
||||
def update(self, since=None, until=None, force_recalc=False):
|
||||
old_attr = {'dan': None, 'dan_points': None,
|
||||
'kyu': None, 'kyu_points': None, 'won_hanchans': None,
|
||||
'good_hanchans': None, 'hanchan_count': None}
|
||||
for ranking in self.all():
|
||||
old_attr = {attr: getattr(ranking, attr) for attr in
|
||||
old_attr.keys()}
|
||||
ranking.calculate(since=since, until=until,
|
||||
force_recalc=force_recalc)
|
||||
for attr, old_value in old_attr.items():
|
||||
if getattr(ranking, attr) != old_value:
|
||||
LOGGER.warning(
|
||||
"%(user)s recalc shows differences in %(attr)s! old: %(old)d, new: %(new)d",
|
||||
{'user': ranking.user, 'attr': attr,
|
||||
'old': old_value, 'new': getattr(ranking, attr)}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user