Anpassungen für das Hosting bei Djangoeurope und damit verbundenen Versionen Django 1.8 und Python 2.7
This commit is contained in:
committed by
Christian Berg
parent
cb4b15b3c6
commit
37d3cb78c1
221
src/maistar_ranking/models.py
Normal file
221
src/maistar_ranking/models.py
Normal file
@@ -0,0 +1,221 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from events.models import Event
|
||||
from membership.models import Membership
|
||||
from . import settings, managers
|
||||
|
||||
|
||||
class Game(models.Model):
|
||||
"""
|
||||
Ein kompettes Spiel Mai-Star bestehend aus 6 Spielern
|
||||
"""
|
||||
|
||||
event = models.ForeignKey(Event, related_name='maistargame_set')
|
||||
comment = models.TextField(_('Comment'), blank=True)
|
||||
player1 = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, verbose_name=_("Player 1"), related_name='+'
|
||||
)
|
||||
player1_score = models.SmallIntegerField(_("Score"))
|
||||
player1_placement = models.PositiveSmallIntegerField(editable=False)
|
||||
|
||||
player2 = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, verbose_name=_("Player 2"), related_name='+'
|
||||
)
|
||||
player2_score = models.SmallIntegerField(_("Score"))
|
||||
player2_placement = models.PositiveSmallIntegerField(editable=False)
|
||||
|
||||
player3 = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, verbose_name=_("Player 3"), related_name='+'
|
||||
)
|
||||
player3_score = models.SmallIntegerField(_("Score"))
|
||||
player3_placement = models.PositiveSmallIntegerField(editable=False)
|
||||
|
||||
player4 = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, verbose_name=_("Player 4"), related_name='+'
|
||||
)
|
||||
player4_score = models.SmallIntegerField(_("Score"))
|
||||
player4_placement = models.PositiveSmallIntegerField(editable=False)
|
||||
|
||||
player5 = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, verbose_name=_("Player 5"), related_name='+'
|
||||
)
|
||||
player5_score = models.SmallIntegerField(_("Score"))
|
||||
player5_placement = models.PositiveSmallIntegerField(editable=False)
|
||||
|
||||
player6 = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, verbose_name=_("Player 6"), related_name='+'
|
||||
)
|
||||
player6_score = models.SmallIntegerField(_("Score"))
|
||||
player6_placement = models.PositiveSmallIntegerField(editable=False)
|
||||
|
||||
confirmed = models.BooleanField(
|
||||
_('Has been confirmed'),
|
||||
default=True,
|
||||
help_text=_('the game only counts whe it has been confirmed')
|
||||
)
|
||||
player_names = models.CharField(max_length=255, editable=False)
|
||||
season = models.PositiveSmallIntegerField(_('Season'), editable=False,
|
||||
db_index=True)
|
||||
|
||||
objects = managers.GameManager()
|
||||
|
||||
def __str__(self):
|
||||
return _("Mai-Star Game with {0} from {1:%Y-%m-%d}").format(
|
||||
self.player_names, self.event.start
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
"""
|
||||
URL zur Hanchanliste des Events wo diese Hanchan gelistet wurde.
|
||||
"""
|
||||
url = reverse('maistar-game-list',
|
||||
kwargs={'event': self.event.pk})
|
||||
return u'%(url)s#%(pk)d' % {'url': url, 'pk': self.pk}
|
||||
|
||||
@property
|
||||
def player_list(self):
|
||||
try:
|
||||
return self._player_list
|
||||
except AttributeError:
|
||||
self._player_list = list()
|
||||
for nr in range(1, 7):
|
||||
self._player_list.append({
|
||||
'user': getattr(self, 'player%d' % nr),
|
||||
'membership': Membership.objects.get(
|
||||
user=getattr(self, 'player%d' % nr)
|
||||
),
|
||||
'score': getattr(self, 'player%d_score' % nr),
|
||||
'placement': getattr(self, 'player%d_placement' % nr),
|
||||
})
|
||||
return self._player_list
|
||||
|
||||
def save(self, force_insert=False, force_update=False, using=None,
|
||||
update_fields=None):
|
||||
u"""
|
||||
Bestimmt die Platzierung eines jeden Spielers noch vor dem speichern.
|
||||
Außerdem wird eine Kommasperierte Liste der Spiele mitgespeichert.
|
||||
"""
|
||||
logging.debug("Berechne die Platzierungen neu...")
|
||||
game_date = self.event.start.date()
|
||||
player_tuples = [
|
||||
(self.player1.id, self.player1.username, self.player1_score),
|
||||
(self.player2.id, self.player2.username, self.player2_score),
|
||||
(self.player3.id, self.player3.username, self.player3_score),
|
||||
(self.player4.id, self.player4.username, self.player4_score),
|
||||
(self.player5.id, self.player5.username, self.player5_score),
|
||||
(self.player6.id, self.player6.username, self.player6_score),
|
||||
]
|
||||
season_start = settings.MAISTAR_SEASON_START.replace(
|
||||
year=game_date.year)
|
||||
|
||||
# sort player by Score:
|
||||
player_tuples = sorted(player_tuples, key=lambda player: player[2],
|
||||
reverse=True)
|
||||
logging.debug(player_tuples)
|
||||
other_player_ranking = 1
|
||||
other_player_score = 0
|
||||
player_names = []
|
||||
ranking = 1
|
||||
player_nr = 1
|
||||
for player_id, player_name, player_score in player_tuples:
|
||||
if player_score == other_player_score:
|
||||
player_ranking = other_player_ranking
|
||||
else:
|
||||
player_ranking = ranking
|
||||
setattr(self, "player%d_id" % player_nr, player_id)
|
||||
setattr(self, "player%d_score" % player_nr, player_score)
|
||||
setattr(self, "player%d_placement" % player_nr, player_ranking)
|
||||
other_player_ranking = player_ranking
|
||||
other_player_score = player_score
|
||||
player_names.append(player_name)
|
||||
player_nr += 1
|
||||
ranking += 1
|
||||
self.player_names = ', '.join(player_names)
|
||||
if game_date >= season_start:
|
||||
self.season = season_start.year
|
||||
else:
|
||||
self.season = season_start.year - 1
|
||||
super(Game, self).save(force_insert=force_insert,
|
||||
force_update=force_update, using=using,
|
||||
update_fields=update_fields)
|
||||
|
||||
|
||||
class Ranking(models.Model):
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL)
|
||||
season = models.PositiveSmallIntegerField(_("Season"))
|
||||
placement = models.PositiveIntegerField(blank=True, null=True)
|
||||
avg_placement = models.PositiveSmallIntegerField(blank=True, null=True)
|
||||
avg_score = models.SmallIntegerField(blank=True, null=True)
|
||||
games_count = models.PositiveSmallIntegerField(default=0)
|
||||
games_good = models.PositiveSmallIntegerField(default=0)
|
||||
games_won = models.PositiveSmallIntegerField(default=0)
|
||||
objects = managers.LadderManager()
|
||||
|
||||
class Meta(object):
|
||||
ordering = ('-season', 'placement', 'avg_placement', '-avg_score',)
|
||||
|
||||
def __str__(self):
|
||||
return "Mai-Star Ranking: %s, Season: %d" % (self.user, self.season)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('maistar-player-games', kwargs={
|
||||
'username': self.user.username,
|
||||
'season': self.season
|
||||
})
|
||||
|
||||
def recalculate(self):
|
||||
logging.info(
|
||||
u'Recalculate Mai-Star Ranking for Player %s in Season %s',
|
||||
self.user, self.season
|
||||
)
|
||||
self.placement = None
|
||||
self.avg_placement = None
|
||||
self.avg_score = None
|
||||
self.games_count = 0
|
||||
self.games_good = 0
|
||||
self.games_won = 0
|
||||
player_score = 0
|
||||
player_placement = 0
|
||||
for game in Game.objects.player_games(self.user, self.season):
|
||||
placement = 0
|
||||
score = 0
|
||||
for player in ('player1', 'player2', 'player3', 'player4',
|
||||
'player5', 'player6'):
|
||||
if getattr(game, player) == self.user:
|
||||
placement = getattr(game, "%s_placement" % player)
|
||||
score = getattr(game, "%s_score" % player)
|
||||
player_placement += placement
|
||||
player_score += score
|
||||
self.games_count += 1
|
||||
self.games_good += 1 if placement <= 3 else 0
|
||||
self.games_won += 1 if placement == 1 else 0
|
||||
if self.games_count > 0:
|
||||
self.avg_placement = round(player_placement / self.games_count)
|
||||
self.avg_score = round(player_score / self.games_count)
|
||||
self.save()
|
||||
|
||||
|
||||
def update_maistar_ranking(sender, instance, **kwargs):
|
||||
for player in instance.player_list:
|
||||
ranking, created = Ranking.objects.get_or_create(
|
||||
user=player['user'],
|
||||
season=instance.season
|
||||
)
|
||||
if created:
|
||||
logging.debug('Created ranking for %s in Season %d',
|
||||
player['user'].username, instance.season)
|
||||
else:
|
||||
logging.debug('Updating ranking for %s in Season %d',
|
||||
player['user'].username, instance.season)
|
||||
ranking.recalculate()
|
||||
Ranking.objects.calculate_rankings(instance.season)
|
||||
|
||||
|
||||
models.signals.post_delete.connect(update_maistar_ranking, sender=Game)
|
||||
models.signals.post_save.connect(update_maistar_ranking, sender=Game)
|
||||
Reference in New Issue
Block a user