recalculating only the new hanchans shoud do the trick now.
the racalc cronjob reports erronous partly recalculations now. A lot of code cleanups
This commit is contained in:
@@ -5,10 +5,10 @@
|
|||||||
"author": "Christian Berg",
|
"author": "Christian Berg",
|
||||||
"license": "GPLv3",
|
"license": "GPLv3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "^0.4.5",
|
"grunt": ">=0.4.5",
|
||||||
"grunt-contrib-less": "^1.0.1",
|
"grunt-contrib-less": ">=1.0.1",
|
||||||
"grunt-contrib-watch": "^0.6.1",
|
"grunt-contrib-watch": ">=0.6.1",
|
||||||
"grunt-more-css": "^0.1.0"
|
"grunt-more-css": ">=0.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ckeditor-dev": "git://github.com/ckeditor/ckeditor-dev.git"
|
"ckeditor-dev": "git://github.com/ckeditor/ckeditor-dev.git"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ from django.utils.translation import ugettext as _
|
|||||||
|
|
||||||
from content.models import Article
|
from content.models import Article
|
||||||
|
|
||||||
MAX_ARTICLE_ITEMS = 10 # Maximum count of articles in the news RSS feed.
|
MAX_ARTICLE_ITEMS = 10 # Maximum count of articles in the news RSS feed.
|
||||||
MAX_COMMENT_ITEMS = 40 # Maximum count of comments in the comments RSS feed.
|
MAX_COMMENT_ITEMS = 40 # Maximum count of comments in the comments RSS feed.
|
||||||
|
|
||||||
|
|
||||||
# Start ignoring PyLintBear (R0201)
|
# Start ignoring PyLintBear (R0201)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class WYSIWYGEditorMixin(PermissionRequiredMixin):
|
|||||||
request, *args, **kwargs)
|
request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ArticleArchiveMixin():
|
class ArticleArchiveMixin(object):
|
||||||
"""Mixin to add common context data to Views of the news archive."""
|
"""Mixin to add common context data to Views of the news archive."""
|
||||||
category = None
|
category = None
|
||||||
|
|
||||||
|
|||||||
@@ -39,5 +39,4 @@ class EventDetailMixin(object):
|
|||||||
context['event'] = self.object
|
context['event'] = self.object
|
||||||
elif hasattr(self, 'object') and hasattr(self.object, 'event'):
|
elif hasattr(self, 'object') and hasattr(self.object, 'event'):
|
||||||
context['event'] = self.object.event
|
context['event'] = self.object.event
|
||||||
print(context)
|
|
||||||
return context
|
return context
|
||||||
|
|||||||
@@ -212,11 +212,11 @@ LOGGING = {
|
|||||||
},
|
},
|
||||||
'handlers': {
|
'handlers': {
|
||||||
'null': {
|
'null': {
|
||||||
'level': 'DEBUG',
|
'level': 'INFO',
|
||||||
'class': 'logging.NullHandler',
|
'class': 'logging.NullHandler',
|
||||||
},
|
},
|
||||||
'console': {
|
'console': {
|
||||||
'level': 'DEBUG',
|
'level': 'INFO',
|
||||||
'class': 'logging.StreamHandler',
|
'class': 'logging.StreamHandler',
|
||||||
'formatter': 'simple'
|
'formatter': 'simple'
|
||||||
},
|
},
|
||||||
@@ -239,7 +239,7 @@ LOGGING = {
|
|||||||
},
|
},
|
||||||
'kasu': {
|
'kasu': {
|
||||||
'handlers': ['console', 'mail_admins'],
|
'handlers': ['console', 'mail_admins'],
|
||||||
'level': 'DEBUG',
|
'level': 'INFO',
|
||||||
'propagate': False,
|
'propagate': False,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ ul.tabs {
|
|||||||
padding: 0.5em 0 0 0;
|
padding: 0.5em 0 0 0;
|
||||||
border-radius: 10px 10px 0 0;
|
border-radius: 10px 10px 0 0;
|
||||||
background-color: #bc0a19;
|
background-color: #bc0a19;
|
||||||
background: linear-gradient(to bottom, #000000 0%, #45484d 100%);
|
background: linear-gradient(to bottom, #000 0%, #45484d 100%);
|
||||||
}
|
}
|
||||||
ul.tabs li {
|
ul.tabs li {
|
||||||
background-color: #fa665a;
|
background-color: #fa665a;
|
||||||
@@ -325,7 +325,7 @@ ul.tabs li.active a {
|
|||||||
min-height: 500px;
|
min-height: 500px;
|
||||||
}
|
}
|
||||||
.disabled {
|
.disabled {
|
||||||
color: #cccccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
.comment {
|
.comment {
|
||||||
display: table;
|
display: table;
|
||||||
@@ -425,7 +425,7 @@ ul.errorlist li {
|
|||||||
}
|
}
|
||||||
.pagination a.disabled,
|
.pagination a.disabled,
|
||||||
.pagination a.disabled:hover {
|
.pagination a.disabled:hover {
|
||||||
color: #666666;
|
color: #666;
|
||||||
}
|
}
|
||||||
.pagination a.previous {
|
.pagination a.previous {
|
||||||
float: left;
|
float: left;
|
||||||
@@ -732,7 +732,7 @@ ul.errorlist li {
|
|||||||
}
|
}
|
||||||
#toggle:checked ~ .toggle,
|
#toggle:checked ~ .toggle,
|
||||||
.toggle:hover {
|
.toggle:hover {
|
||||||
background: #45abd6;
|
background: #45ABD6;
|
||||||
}
|
}
|
||||||
#usernav a {
|
#usernav a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ DAN_RANKS = (
|
|||||||
DAN_RANKS_DICT = dict([(dan, points) for points, dan in DAN_RANKS])
|
DAN_RANKS_DICT = dict([(dan, points) for points, dan in DAN_RANKS])
|
||||||
MIN_HANCHANS_FOR_LADDER = 5
|
MIN_HANCHANS_FOR_LADDER = 5
|
||||||
|
|
||||||
logger = logging.getLogger('kasu.mahjong_ranking')
|
LOGGER = logging.getLogger('kasu.mahjong_ranking')
|
||||||
|
|
||||||
|
|
||||||
def set_dirty(event=None, season=None, user=None, hanchan_date=None):
|
def set_dirty(event=None, season=None, user=None, hanchan_date=None):
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ Recalculate Mahjong Rankings...
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
from mahjong_ranking import LOGGER
|
||||||
from mahjong_ranking import models
|
from mahjong_ranking import models
|
||||||
|
|
||||||
|
|
||||||
@@ -14,5 +16,16 @@ class Command(BaseCommand):
|
|||||||
help = "Recalculate all Kyu/Dan Rankings"
|
help = "Recalculate all Kyu/Dan Rankings"
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
old_attr = {'dan': None, 'dan_points': None,
|
||||||
|
'kyu': None, 'kyu_points': None, 'won_hanchans': None,
|
||||||
|
'good_hanchans': None, 'hanchan_count': None}
|
||||||
for ranking in models.KyuDanRanking.objects.all():
|
for ranking in models.KyuDanRanking.objects.all():
|
||||||
|
old_attr = {attr: getattr(ranking, attr) for attr in old_attr.keys()}
|
||||||
ranking.recalculate()
|
ranking.recalculate()
|
||||||
|
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)}
|
||||||
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
from mahjong_ranking import models
|
from mahjong_ranking import models
|
||||||
from . import logger, MIN_HANCHANS_FOR_LADDER
|
from . import LOGGER, MIN_HANCHANS_FOR_LADDER
|
||||||
|
|
||||||
|
|
||||||
class DenormalizationUpdateMiddleware(object): # Ignore PyLintBear (R0903)
|
class DenormalizationUpdateMiddleware(object): # Ignore PyLintBear (R0903)
|
||||||
@@ -57,7 +57,7 @@ class DenormalizationUpdateMiddleware(object): # Ignore PyLintBear (R0903)
|
|||||||
ranking.save(force_update=True)
|
ranking.save(force_update=True)
|
||||||
|
|
||||||
for season in season_queue:
|
for season in season_queue:
|
||||||
logger.info(u'Recalculate placements for Season %d', season)
|
LOGGER.info(u'Recalculate placements for Season %d', season)
|
||||||
season_rankings = models.SeasonRanking.objects.filter(
|
season_rankings = models.SeasonRanking.objects.filter(
|
||||||
season=season, hanchan_count__gt=MIN_HANCHANS_FOR_LADDER
|
season=season, hanchan_count__gt=MIN_HANCHANS_FOR_LADDER
|
||||||
).order_by('avg_placement', '-avg_score')
|
).order_by('avg_placement', '-avg_score')
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from django.utils import timezone
|
|||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from events.models import Event
|
from events.models import Event
|
||||||
from . import KYU_RANKS, DAN_RANKS, DAN_RANKS_DICT, logger, set_dirty
|
from . import KYU_RANKS, DAN_RANKS, DAN_RANKS_DICT, LOGGER, set_dirty
|
||||||
from . import managers
|
from . import managers
|
||||||
|
|
||||||
kyu_dan_rankings = set()
|
kyu_dan_rankings = set()
|
||||||
@@ -50,7 +50,7 @@ class EventRanking(models.Model):
|
|||||||
können zwar sehr leicht errechnet werden, es macht trotzdem Sinn
|
können zwar sehr leicht errechnet werden, es macht trotzdem Sinn
|
||||||
sie zwischen zu speichern.
|
sie zwischen zu speichern.
|
||||||
"""
|
"""
|
||||||
logger.info(
|
LOGGER.info(
|
||||||
u'Recalculate EventRanking for Player %s in %s',
|
u'Recalculate EventRanking for Player %s in %s',
|
||||||
self.user, self.event.name
|
self.user, self.event.name
|
||||||
)
|
)
|
||||||
@@ -235,7 +235,7 @@ class Hanchan(models.Model):
|
|||||||
Bestimmt die Platzierung eines der Spieler einer Hanchan und speichert
|
Bestimmt die Platzierung eines der Spieler einer Hanchan und speichert
|
||||||
diese beim jeweiligen Spieler ab.
|
diese beim jeweiligen Spieler ab.
|
||||||
"""
|
"""
|
||||||
logger.debug("Berechne die Platzierungen neu...")
|
LOGGER.debug("Berechne die Platzierungen neu...")
|
||||||
player_names = []
|
player_names = []
|
||||||
other_player_placement = 0
|
other_player_placement = 0
|
||||||
other_player_game_score = 0
|
other_player_game_score = 0
|
||||||
@@ -370,18 +370,18 @@ class KyuDanRanking(models.Model):
|
|||||||
self.wins_in_a_row = 0
|
self.wins_in_a_row = 0
|
||||||
|
|
||||||
if self.dan and self.wins_in_a_row >= 3 and self.dan < 9:
|
if self.dan and self.wins_in_a_row >= 3 and self.dan < 9:
|
||||||
logger.info(
|
LOGGER.info(
|
||||||
'adding bonuspoints for 3 wins in a row for %s', self.user)
|
'adding bonuspoints for 3 wins in a row for %s', self.user)
|
||||||
new_dan_rank = self.dan + 1
|
new_dan_rank = self.dan + 1
|
||||||
new_dan_points = DAN_RANKS_DICT[new_dan_rank] + 1
|
new_dan_points = DAN_RANKS_DICT[new_dan_rank] + 1
|
||||||
bonus_points = new_dan_points - self.dan_points
|
bonus_points = new_dan_points - self.dan_points
|
||||||
|
|
||||||
logger.debug("Stats for %s:", self.user)
|
LOGGER.debug("Stats for %s:", self.user)
|
||||||
logger.debug("current dan_points: %d", self.dan_points)
|
LOGGER.debug("current dan_points: %d", self.dan_points)
|
||||||
logger.debug("current dan: %d", self.dan)
|
LOGGER.debug("current dan: %d", self.dan)
|
||||||
logger.debug(
|
LOGGER.debug(
|
||||||
"min required points for the next dan: %d", new_dan_points)
|
"min required points for the next dan: %d", new_dan_points)
|
||||||
logger.debug("bonus points to add: %d", bonus_points)
|
LOGGER.debug("bonus points to add: %d", bonus_points)
|
||||||
|
|
||||||
hanchan.dan_points += bonus_points
|
hanchan.dan_points += bonus_points
|
||||||
hanchan.bonus_points += bonus_points
|
hanchan.bonus_points += bonus_points
|
||||||
@@ -444,40 +444,43 @@ class KyuDanRanking(models.Model):
|
|||||||
self.kyu = None
|
self.kyu = None
|
||||||
self.kyu_points = self.legacy_kyu_points or 0
|
self.kyu_points = self.legacy_kyu_points or 0
|
||||||
self.hanchan_count = self.legacy_hanchan_count or 0
|
self.hanchan_count = self.legacy_hanchan_count or 0
|
||||||
|
|
||||||
self.good_hanchans = 0
|
self.good_hanchans = 0
|
||||||
self.won_hanchans = 0
|
self.won_hanchans = 0
|
||||||
|
self.update_rank()
|
||||||
|
|
||||||
logger.info(
|
LOGGER.info(
|
||||||
"recalculating Kyu/Dan points for %s since %s...",
|
"recalculating Kyu/Dan points for %s since %s...",
|
||||||
self.user, str(hanchan_start)
|
self.user, str(hanchan_start)
|
||||||
)
|
)
|
||||||
self.update_rank()
|
valid_hanchans = Hanchan.objects.confirmed_hanchans(
|
||||||
valid_hanchans = Hanchan.objects.confirmed_hanchans(user=self.user)
|
user=self.user).order_by('start')
|
||||||
valid_hanchans = valid_hanchans.order_by('start')
|
|
||||||
if self.legacy_date:
|
if self.legacy_date:
|
||||||
valid_hanchans = valid_hanchans.filter(start__gt=self.legacy_date)
|
valid_hanchans = valid_hanchans.filter(start__gt=self.legacy_date)
|
||||||
""" TODO: Hanchan Punkte nur neu berechnen wenn sie vor hachan_start
|
|
||||||
lag. Es müssen aber alle durch die Schleife rennen, damit die Punkte
|
""" TODO: Hanchan Punkte nur neu berechnen wenn sie nach hachan_start
|
||||||
|
lagen. Es müssen aber alle durch die Schleife rennen, damit die Punkte
|
||||||
richtig gezählt werden."""
|
richtig gezählt werden."""
|
||||||
if hanchan_start:
|
|
||||||
valid_hanchans = valid_hanchans.filter(start__gte=hanchan_start)
|
|
||||||
self.hanchan_count += valid_hanchans.count()
|
self.hanchan_count += valid_hanchans.count()
|
||||||
for hanchan in valid_hanchans:
|
for hanchan in valid_hanchans:
|
||||||
hanchan.get_playerdata(self.user)
|
hanchan.get_playerdata(self.user)
|
||||||
hanchan.bonus_points = 0
|
if hanchan_start and hanchan_start < hanchan.start:
|
||||||
hanchan.player_comment = u""
|
self.dan_points += hanchan.dan_points or 0
|
||||||
self.update_hanchan_points(hanchan)
|
self.kyu_points += hanchan.kyu_points or 0
|
||||||
if hanchan.event.mahjong_tournament:
|
self.update_rank()
|
||||||
self.append_tournament_bonuspoints(hanchan)
|
else:
|
||||||
self.update_rank()
|
hanchan.bonus_points = 0
|
||||||
self.append_3_in_a_row_bonuspoints(hanchan)
|
hanchan.player_comment = u""
|
||||||
self.update_rank()
|
self.update_hanchan_points(hanchan)
|
||||||
|
if hanchan.event.mahjong_tournament:
|
||||||
|
self.append_tournament_bonuspoints(hanchan)
|
||||||
|
self.update_rank()
|
||||||
|
self.append_3_in_a_row_bonuspoints(hanchan)
|
||||||
|
self.update_rank()
|
||||||
|
hanchan.update_playerdata(self.user)
|
||||||
|
hanchan.save(recalculate=False)
|
||||||
self.won_hanchans += 1 if hanchan.placement == 1 else 0
|
self.won_hanchans += 1 if hanchan.placement == 1 else 0
|
||||||
self.good_hanchans += 1 if hanchan.placement == 2 else 0
|
self.good_hanchans += 1 if hanchan.placement == 2 else 0
|
||||||
hanchan.update_playerdata(self.user)
|
LOGGER.debug(
|
||||||
hanchan.save(recalculate=False)
|
|
||||||
logger.debug(
|
|
||||||
'id: %(id)d, start: %(start)s, placement: %(placement)d, '
|
'id: %(id)d, start: %(start)s, placement: %(placement)d, '
|
||||||
'score: %(score)d, kyu points: %(kyu_points)d, dan points: '
|
'score: %(score)d, kyu points: %(kyu_points)d, dan points: '
|
||||||
'%(dan_points)d, bonus points: %(bonus_points)d',
|
'%(dan_points)d, bonus points: %(bonus_points)d',
|
||||||
@@ -498,11 +501,11 @@ class KyuDanRanking(models.Model):
|
|||||||
hanchan.kyu_points = None
|
hanchan.kyu_points = None
|
||||||
hanchan.dan_points = None
|
hanchan.dan_points = None
|
||||||
if hanchan.event.mahjong_tournament:
|
if hanchan.event.mahjong_tournament:
|
||||||
# Für Turniere gelten andere Regeln zur Punktevergabe:
|
"""Für Turniere gelten andere Regeln zur Punktevergabe:
|
||||||
# 1. Platz 4 Punkte
|
1. Platz 4 Punkte
|
||||||
# 2. Platz 3 Punkte
|
2. Platz 3 Punkte
|
||||||
# 3. Platz 2 Punkte
|
3. Platz 2 Punkte
|
||||||
# 4. Platz 1 Punkt
|
4. Platz 1 Punkt"""
|
||||||
tourney_points = 4 - hanchan.placement
|
tourney_points = 4 - hanchan.placement
|
||||||
if self.dan:
|
if self.dan:
|
||||||
hanchan.dan_points = tourney_points
|
hanchan.dan_points = tourney_points
|
||||||
@@ -598,7 +601,7 @@ class SeasonRanking(models.Model):
|
|||||||
self.good_hanchans = 0
|
self.good_hanchans = 0
|
||||||
self.won_hanchans = 0
|
self.won_hanchans = 0
|
||||||
|
|
||||||
logger.info(
|
LOGGER.info(
|
||||||
u'Recalculate LadderRanking for Player %s in Season %s',
|
u'Recalculate LadderRanking for Player %s in Season %s',
|
||||||
self.user, self.season)
|
self.user, self.season)
|
||||||
for hanchan in season_hanchans:
|
for hanchan in season_hanchans:
|
||||||
@@ -616,22 +619,24 @@ class SeasonRanking(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
def update_ranking(sender, instance, **kwargs):
|
def update_ranking(sender, instance, **kwargs):
|
||||||
for user in (instance.player1, instance.player2, instance.player3, instance.player4):
|
for user in (
|
||||||
logger.debug(
|
instance.player1, instance.player2, instance.player3,
|
||||||
|
instance.player4):
|
||||||
|
LOGGER.debug(
|
||||||
"marking %(user)s's kyu/dan for recalculation since %(start)s",
|
"marking %(user)s's kyu/dan for recalculation since %(start)s",
|
||||||
{'user': user, 'start': str(instance.start.date())}
|
{'user': user, 'start': str(instance.start.date())}
|
||||||
)
|
)
|
||||||
set_dirty(user=user.id, hanchan_date=instance.start.date())
|
set_dirty(user=user.id, hanchan_date=instance.start.date())
|
||||||
logger.debug("marking event %s for recalculation.", instance.event)
|
LOGGER.debug("marking event %s for recalculation.", instance.event)
|
||||||
set_dirty(event=instance.event_id, user=user.id)
|
set_dirty(event=instance.event_id, user=user.id)
|
||||||
if instance.season:
|
if instance.season:
|
||||||
logger.debug(
|
LOGGER.debug(
|
||||||
"marking %s's ladder %i season for recalculation.",
|
"marking %s's ladder %i season for recalculation.",
|
||||||
user, instance.season
|
user, instance.season
|
||||||
)
|
)
|
||||||
set_dirty(user=user.id, season=instance.season)
|
set_dirty(user=user.id, season=instance.season)
|
||||||
|
|
||||||
logger.debug("marking season %d for recalculation.", instance.season)
|
LOGGER.debug("marking season %d for recalculation.", instance.season)
|
||||||
set_dirty(season=instance.season)
|
set_dirty(season=instance.season)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class KyuDanTest(TestCase):
|
|||||||
'test_kyu_dan_rankings.json'
|
'test_kyu_dan_rankings.json'
|
||||||
]
|
]
|
||||||
|
|
||||||
def recalc(self):
|
def _test_recalc(self):
|
||||||
"""
|
"""
|
||||||
Test if a Kyu/Dan Ranking recalculation gives the same result as stored.
|
Test if a Kyu/Dan Ranking recalculation gives the same result as stored.
|
||||||
|
|
||||||
@@ -58,10 +58,10 @@ class KyuDanTest(TestCase):
|
|||||||
user=ranking.user,
|
user=ranking.user,
|
||||||
since=ranking.legacy_date
|
since=ranking.legacy_date
|
||||||
)
|
)
|
||||||
|
if not confirmed_hanchans.count():
|
||||||
|
continue
|
||||||
rnd = random.randrange(confirmed_hanchans.count())
|
rnd = random.randrange(confirmed_hanchans.count())
|
||||||
since = confirmed_hanchans[rnd].start
|
since = confirmed_hanchans[rnd].start
|
||||||
print(since)
|
|
||||||
|
|
||||||
ranking.recalculate(hanchan_start=since)
|
ranking.recalculate(hanchan_start=since)
|
||||||
for attr in self.equal_attrs:
|
for attr in self.equal_attrs:
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|||||||
@@ -188,9 +188,11 @@ class SeasonRankingList(MahjongMixin, generic.ListView):
|
|||||||
|
|
||||||
class PlayerScore(LoginRequiredMixin, generic.ListView):
|
class PlayerScore(LoginRequiredMixin, generic.ListView):
|
||||||
paginate_by = 25
|
paginate_by = 25
|
||||||
|
user = auth.get_user_model()
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
user_model = auth.get_user_model()
|
user_model = auth.get_user_model()
|
||||||
|
username = kwargs.get('username')
|
||||||
try:
|
try:
|
||||||
self.user = user_model.objects.get(
|
self.user = user_model.objects.get(
|
||||||
username=self.kwargs.get('username'))
|
username=self.kwargs.get('username'))
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ class Game(models.Model):
|
|||||||
|
|
||||||
objects = managers.GameManager()
|
objects = managers.GameManager()
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
"""Display rankings by placement, best players first."""
|
||||||
|
ordering = ('-event__start', '-id')
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return _("Mai-Star Game with {0} from {1:%Y-%m-%d}").format(
|
return _("Mai-Star Game with {0} from {1:%Y-%m-%d}").format(
|
||||||
self.player_names, self.event.start
|
self.player_names, self.event.start
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ class ListPlayerGames(PlayerScore):
|
|||||||
template_name = 'maistar_ranking/player_game_list.html'
|
template_name = 'maistar_ranking/player_game_list.html'
|
||||||
paginate_by = 25
|
paginate_by = 25
|
||||||
context_object_name = 'game_list'
|
context_object_name = 'game_list'
|
||||||
|
user = None
|
||||||
|
season = None
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(ListPlayerGames, self).get_context_data()
|
context = super(ListPlayerGames, self).get_context_data()
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ class MassMailer(object):
|
|||||||
LOGGER.warning('%s is not a User Object!', recipient)
|
LOGGER.warning('%s is not a User Object!', recipient)
|
||||||
continue
|
continue
|
||||||
mail_context['recipient'] = recipient
|
mail_context['recipient'] = recipient
|
||||||
print(recipient.__dict__)
|
|
||||||
mail_to = "{first_name!s} {last_name!s} <{email!s}>".format(
|
mail_to = "{first_name!s} {last_name!s} <{email!s}>".format(
|
||||||
**recipient.__dict__)
|
**recipient.__dict__)
|
||||||
message = django.core.mail.EmailMultiAlternatives(
|
message = django.core.mail.EmailMultiAlternatives(
|
||||||
|
|||||||
Reference in New Issue
Block a user