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
b96b485b61
0
src/maistar_ranking/__init__.py
Normal file
0
src/maistar_ranking/__init__.py
Normal file
64
src/maistar_ranking/admin.py
Normal file
64
src/maistar_ranking/admin.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Created on 19.09.2011
|
||||
|
||||
@author: christian
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from . import forms, models
|
||||
|
||||
|
||||
def recalculate(modeladmin, request, queryset): # @UnusedVariable
|
||||
if isinstance(modeladmin, RankingAdmin):
|
||||
seasons = set()
|
||||
for ranking in queryset:
|
||||
ranking.recalculate()
|
||||
seasons.add(ranking.season)
|
||||
for season in seasons:
|
||||
models.Ranking.objects.calculate_rankings(season)
|
||||
|
||||
|
||||
recalculate.short_description = _("Recalculate")
|
||||
|
||||
|
||||
class RankingAdmin(admin.ModelAdmin):
|
||||
actions = [recalculate]
|
||||
list_display = (
|
||||
'season', 'placement', 'user', 'avg_placement', 'avg_score',
|
||||
'games_count', 'games_good', 'games_won'
|
||||
)
|
||||
list_display_links = ('user',)
|
||||
list_filter = ['season']
|
||||
|
||||
|
||||
class GameAdmin(admin.ModelAdmin):
|
||||
actions = [recalculate]
|
||||
# date_hierarchy = 'event__start'
|
||||
fields = (
|
||||
'event',
|
||||
('player1', 'player1_score', 'player1_placement'),
|
||||
('player2', 'player2_score', 'player2_placement'),
|
||||
('player3', 'player3_score', 'player3_placement'),
|
||||
('player4', 'player4_score', 'player4_placement'),
|
||||
('player5', 'player5_score', 'player5_placement'),
|
||||
('player6', 'player6_score', 'player6_placement'),
|
||||
'comment',
|
||||
'confirmed'
|
||||
)
|
||||
form = forms.GameForm
|
||||
list_display = ('event', 'season', 'player_names', 'comment', 'confirmed')
|
||||
readonly_fields = (
|
||||
'player1_placement', 'player2_placement', 'player3_placement',
|
||||
'player4_placement', 'player5_placement', 'player6_placement'
|
||||
)
|
||||
search_fields = [
|
||||
'player1__username', 'player2__username', 'player3__username',
|
||||
'player4__username', 'player5__username', 'player6__username'
|
||||
]
|
||||
|
||||
|
||||
admin.site.register(models.Game, GameAdmin)
|
||||
admin.site.register(models.Ranking, RankingAdmin)
|
||||
37
src/maistar_ranking/forms.py
Normal file
37
src/maistar_ranking/forms.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
__author__ = 'christian'
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class GameForm(forms.ModelForm):
|
||||
error_css_class = 'error'
|
||||
required_css_class = 'required'
|
||||
|
||||
class Meta(object):
|
||||
fields = [
|
||||
'player1', 'player1_score',
|
||||
'player2', 'player2_score',
|
||||
'player3', 'player3_score',
|
||||
'player4', 'player4_score',
|
||||
'player5', 'player5_score',
|
||||
'player6', 'player6_score',
|
||||
'comment'
|
||||
]
|
||||
model = models.Game
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(GameForm, self).clean()
|
||||
players_in_game = set()
|
||||
for player_nr in (
|
||||
'player1', 'player2', 'player3', 'player4', 'player5', 'player6'):
|
||||
current_player = cleaned_data.get(player_nr)
|
||||
if current_player and current_player in players_in_game:
|
||||
msg = _("%s may only participate once." % current_player)
|
||||
self._errors[player_nr] = self.error_class([msg])
|
||||
del cleaned_data[player_nr]
|
||||
players_in_game.add(current_player)
|
||||
return cleaned_data
|
||||
272
src/maistar_ranking/locale/de/LC_MESSAGES/django.po
Normal file
272
src/maistar_ranking/locale/de/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,272 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kasu.mahjong_ranking\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-01-05 19:23+0100\n"
|
||||
"PO-Revision-Date: 2014-12-11 22:47+0100\n"
|
||||
"Last-Translator: Christian Berg <xeniac.at@gmail.com>\n"
|
||||
"Language-Team: Kasu <verein@kasu.at>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 1.6.11\n"
|
||||
"X-Translated-Using: django-rosetta 0.7.2\n"
|
||||
|
||||
#: admin.py:24
|
||||
msgid "Recalculate"
|
||||
msgstr "Neuberechnen"
|
||||
|
||||
#: forms.py:33
|
||||
#, python-format
|
||||
msgid "%s may only participate once."
|
||||
msgstr "%s darf nur einmal teilnehmen."
|
||||
|
||||
#: models.py:20
|
||||
msgid "Comment"
|
||||
msgstr "Kommentar"
|
||||
|
||||
#: models.py:22
|
||||
msgid "Player 1"
|
||||
msgstr "Spieler 1"
|
||||
|
||||
#: models.py:24 models.py:30 models.py:36 models.py:42 models.py:48
|
||||
#: models.py:54 templates/maistar_ranking/ranking_list.html:20
|
||||
msgid "Score"
|
||||
msgstr "Punkte"
|
||||
|
||||
#: models.py:28
|
||||
msgid "Player 2"
|
||||
msgstr "Spieler 2"
|
||||
|
||||
#: models.py:34
|
||||
msgid "Player 3"
|
||||
msgstr "Spieler 3"
|
||||
|
||||
#: models.py:40
|
||||
msgid "Player 4"
|
||||
msgstr "Spieler 4"
|
||||
|
||||
#: models.py:46
|
||||
msgid "Player 5"
|
||||
msgstr "Spieler 5"
|
||||
|
||||
#: models.py:52
|
||||
msgid "Player 6"
|
||||
msgstr "Spieler 6"
|
||||
|
||||
#: models.py:58
|
||||
msgid "Has been confirmed"
|
||||
msgstr "Wurde bestätigt"
|
||||
|
||||
#: models.py:60
|
||||
msgid "the game only counts whe it has been confirmed"
|
||||
msgstr "das Spiel zählt nur wenn es bestätigt wurde"
|
||||
|
||||
#: models.py:63 models.py:151
|
||||
#: templates/maistar_ranking/player_game_list.html:6
|
||||
#: templates/maistar_ranking/ranking_list.html:4
|
||||
#: templates/maistar_ranking/ranking_list.html:71
|
||||
msgid "Season"
|
||||
msgstr "Saison"
|
||||
|
||||
#: models.py:69
|
||||
msgid "Mai-Star Game with {0} from {1:%Y-%m-%d}"
|
||||
msgstr "Mai-Star Spiel mit {0} vom {1:%Y-%m-%d}"
|
||||
|
||||
#: templates/maistar_ranking/game_form.html:5
|
||||
#: templates/maistar_ranking/game_form.html:16
|
||||
#: templates/maistar_ranking/game_list.html:27
|
||||
#: templates/maistar_ranking/player_game_list.html:46
|
||||
msgid "Edit Game"
|
||||
msgstr "Spiel bearbeiten"
|
||||
|
||||
#: templates/maistar_ranking/game_form.html:5
|
||||
#: templates/maistar_ranking/game_form.html:16
|
||||
#: templates/maistar_ranking/game_list.html:42
|
||||
msgid "Add Game"
|
||||
msgstr "Spiel hinzufügen"
|
||||
|
||||
#: templates/maistar_ranking/game_form.html:78
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
||||
#: templates/maistar_ranking/game_form.html:80
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:4
|
||||
#: templates/maistar_ranking/player_game_list.html:6
|
||||
msgid "Mai-Star Games"
|
||||
msgstr "Mai-Star Spiele"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:7
|
||||
msgid "Played Mai-Star Games"
|
||||
msgstr "Gespielte Mai-Star Spiele"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:12
|
||||
msgid "Game"
|
||||
msgstr "Spiel"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:15
|
||||
msgid "Place"
|
||||
msgstr "Platz"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:19
|
||||
#: templates/maistar_ranking/player_game_list.html:38
|
||||
msgid "Points"
|
||||
msgstr "Punkte"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:24
|
||||
#: templates/maistar_ranking/hanchan_confirm_delete.html:18
|
||||
#: templates/maistar_ranking/hanchan_confirm_delete.html:19
|
||||
#: templates/maistar_ranking/player_game_list.html:43
|
||||
msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:24
|
||||
#: templates/maistar_ranking/player_game_list.html:43
|
||||
msgid "Delete Game"
|
||||
msgstr "Spiel löschen"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:27
|
||||
#: templates/maistar_ranking/player_game_list.html:46
|
||||
msgid "Edit"
|
||||
msgstr "Bearbeiten"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:32
|
||||
msgid "No Mai-Star games have been added to this event yet."
|
||||
msgstr "Für diese Veranstaltung wurden noch keine Mai-Star Spiele erfasst."
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:40
|
||||
#: templates/maistar_ranking/game_list.html:42
|
||||
msgid "Add"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: templates/maistar_ranking/game_list.html:40
|
||||
msgid "Edit Event"
|
||||
msgstr "Veranstaltung bearbeiten"
|
||||
|
||||
#: templates/maistar_ranking/hanchan_confirm_delete.html:4
|
||||
#: templates/maistar_ranking/hanchan_confirm_delete.html:10
|
||||
msgid "Delete game"
|
||||
msgstr "Spiel löschen"
|
||||
|
||||
#: templates/maistar_ranking/hanchan_confirm_delete.html:14
|
||||
#: templates/maistar_ranking/hanchan_confirm_delete.html:15
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#: templates/maistar_ranking/page.html:5
|
||||
msgid "Archive"
|
||||
msgstr "Archiv"
|
||||
|
||||
#: templates/maistar_ranking/page.html:7
|
||||
msgid "Add Event"
|
||||
msgstr "Veranstaltung hinzufügen"
|
||||
|
||||
#: templates/maistar_ranking/player_game_list.html:4
|
||||
msgid "Ladder Score for"
|
||||
msgstr "Ladder Wertung für"
|
||||
|
||||
#: templates/maistar_ranking/player_game_list.html:10
|
||||
msgid "Mai-Star Games with"
|
||||
msgstr "Mai-Star Spiele mit"
|
||||
|
||||
#: templates/maistar_ranking/player_game_list.html:15
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#: templates/maistar_ranking/player_game_list.html:16
|
||||
msgid "Event"
|
||||
msgstr "Veranstaltung"
|
||||
|
||||
#: templates/maistar_ranking/player_game_list.html:17
|
||||
msgid "Players"
|
||||
msgstr "Spieler"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:4
|
||||
msgid "Mai-Star Ranking"
|
||||
msgstr "Mai-Star Platzierung"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:11
|
||||
#: templates/maistar_ranking/ranking_list.html:19
|
||||
msgid "Placement"
|
||||
msgstr "Platzierung"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:12
|
||||
msgid "Avatar"
|
||||
msgstr "Avatar"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:13
|
||||
msgid "Nickname"
|
||||
msgstr "Spitzname"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:14
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:15
|
||||
msgid "Average"
|
||||
msgstr "Durchschnitt"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:16
|
||||
msgid "Games"
|
||||
msgstr "Spiele"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:21
|
||||
msgid "count"
|
||||
msgstr "Anzahl"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:22
|
||||
msgid "good"
|
||||
msgstr "Gut"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:23
|
||||
msgid "won"
|
||||
msgstr "Gewonnen"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:42
|
||||
msgid ""
|
||||
"Unfortunately, nobody has it been done in the ranking.\n"
|
||||
" A player must have 6 games done, to be added to the ranking."
|
||||
msgstr ""
|
||||
"Leider hat es noch niemand in die Wertung geschafft. Spieler, die weniger "
|
||||
"als 6 Spiele innerhalb einer Saison absolviert haben, werden für das "
|
||||
"Endergebnis nicht gewertet."
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:52
|
||||
msgid "Latest Games"
|
||||
msgstr "Letzten Spiele"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:62
|
||||
msgid "Latest Events"
|
||||
msgstr "Letzten Veranstaltungen"
|
||||
|
||||
#: templates/maistar_ranking/ranking_list.html:69
|
||||
msgid "Ladder Archive"
|
||||
msgstr "Archiv"
|
||||
|
||||
#~ msgid "Player List"
|
||||
#~ msgstr "Spieler Liste"
|
||||
|
||||
#~ msgid "Full Name"
|
||||
#~ msgstr "Voller Name"
|
||||
|
||||
#~ msgid "Rank"
|
||||
#~ msgstr "Rang"
|
||||
|
||||
#~ msgid "Games Total"
|
||||
#~ msgstr "Spiele Gesamt"
|
||||
|
||||
#~ msgid "Event does not exist"
|
||||
#~ msgstr "Termin existiert nicht."
|
||||
|
||||
#~ msgid "No user found matching the name %s"
|
||||
#~ msgstr "Kein Benutzer mit dem Namen %s gefunden."
|
||||
60
src/maistar_ranking/managers.py
Normal file
60
src/maistar_ranking/managers.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Created on 22.11.2014
|
||||
|
||||
@author: christian
|
||||
"""
|
||||
from django.db import models
|
||||
|
||||
from . import settings
|
||||
|
||||
|
||||
class GameManager(models.Manager):
|
||||
use_for_related_fields = True
|
||||
|
||||
def player_games(self, player, season=None, **kwargs):
|
||||
queryset = self.filter(
|
||||
models.Q(player1=player) | models.Q(player2=player) |
|
||||
models.Q(player3=player) | models.Q(player4=player) |
|
||||
models.Q(player5=player) | models.Q(player6=player)
|
||||
)
|
||||
if season:
|
||||
queryset = queryset.filter(season=season)
|
||||
if kwargs:
|
||||
queryset = queryset.filter(**kwargs)
|
||||
return queryset
|
||||
|
||||
|
||||
class LadderManager(models.Manager):
|
||||
use_for_related_fields = True
|
||||
|
||||
def calculate_rankings(self, season):
|
||||
"""
|
||||
Berechnet die Jahresrankings für die Spieler neu.
|
||||
@param season: Das Jahr das neu berechnet werden soll
|
||||
@type season: Integer
|
||||
"""
|
||||
rankings = self.filter(season=season)
|
||||
rankings.update(placement=None)
|
||||
rankings = rankings.filter(
|
||||
games_count__gte=settings.MAISTAR_GAMES_FOR_LADDERRANKING) # @IgnorePep8
|
||||
rankings = rankings.order_by('avg_placement', '-avg_score')
|
||||
placement = 1
|
||||
previous_avg_placement = None
|
||||
previous_avg_score = None
|
||||
previous_placement = None
|
||||
for ranking in rankings:
|
||||
if ranking.avg_placement == previous_avg_placement \
|
||||
and ranking.avg_score == previous_avg_score:
|
||||
ranking.placement = previous_placement
|
||||
else:
|
||||
ranking.placement = placement
|
||||
ranking.save(force_update=True)
|
||||
previous_avg_placement = ranking.avg_placement
|
||||
previous_avg_score = ranking.avg_score
|
||||
previous_placement = ranking.placement
|
||||
placement += 1
|
||||
|
||||
def get_seasons(self):
|
||||
return self.values_list('season', flat=True).order_by(
|
||||
'season').distinct()
|
||||
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)
|
||||
24
src/maistar_ranking/settings.py
Normal file
24
src/maistar_ranking/settings.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
Global Settings for the Maistar Ranking System
|
||||
|
||||
Created on 22.11.2014
|
||||
|
||||
@author: christian
|
||||
"""
|
||||
|
||||
from datetime import date
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
AUTH_USER_MODEL = settings.AUTH_USER_MODEL
|
||||
|
||||
MAISTAR_GAMES_FOR_LADDERRANKING = getattr(
|
||||
settings, 'MAISTAR_GAMES_FOR_LADDERRANKING', 6
|
||||
)
|
||||
|
||||
MAISTAR_SEASON_START = getattr(
|
||||
settings, 'MAISTAR_SEASON_START', date(year=1, month=8, day=1)
|
||||
)
|
||||
|
||||
|
||||
87
src/maistar_ranking/templates/maistar_ranking/game_form.html
Normal file
87
src/maistar_ranking/templates/maistar_ranking/game_form.html
Normal file
@@ -0,0 +1,87 @@
|
||||
{% extends "events/event_detail.html" %}
|
||||
{% load i18n comments fieldset_extras %}
|
||||
|
||||
{% block title %}
|
||||
{% if game.id %}{% trans "Edit Game" %}{% else %}{% trans "Add Game" %}{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block maincontent %}
|
||||
{% for error in form.errors %}<p class="error">{{error}}</p>{% endfor %}
|
||||
|
||||
{% for error in form.non_field_errors %}<p class="error">{{error}}</p>{% endfor %}
|
||||
|
||||
<form class="grid_12" method="post">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<legend>{% if game.id %}{% trans "Edit Game" %}{% else %} {% trans "Add Game" %}{% endif %}</legend>
|
||||
|
||||
<p>
|
||||
<label for="id_player1" class="field_name {{ form.player1.css_classes }}">{{ form.player1.label }}</label>
|
||||
{{ form.player1 }}
|
||||
<label for="id_player1_score" class="{{ form.player1_score.css_classes }}">{{ form.player1_score.label }}</label>
|
||||
{{ form.player1_score}}
|
||||
</p>
|
||||
{% if form.player1.errors %}{{ form.player1.errors }}{% endif %}
|
||||
{% if form.player1_score.errors %}{{ form.player1_score.errors }}{% endif %}
|
||||
<p>
|
||||
<label for="id_player2" class="field_name {{ form.player2.css_classes }}">{{ form.player2.label }}</label>
|
||||
{{ form.player2 }}
|
||||
<label for="id_player2_score" class="{{ form.player2_score.css_classes }}">{{ form.player2_score.label }}</label>
|
||||
{{ form.player2_score}}
|
||||
</p>
|
||||
{% if form.player2.errors %}{{ form.player2.errors }}{% endif %}
|
||||
{% if form.player2_score.errors %}{{ form.player2_score.errors }}{% endif %}
|
||||
|
||||
<p>
|
||||
<label for="id_player3" class="field_name {{ form.player3.css_classes }}">{{ form.player3.label }}</label>
|
||||
{{ form.player3 }}
|
||||
<label for="id_player3_score" class="{{ form.player3_score.css_classes }}">{{ form.player3_score.label }}</label>
|
||||
{{ form.player3_score}}
|
||||
</p>
|
||||
{% if form.player3.errors %}{{ form.player3.errors }}{% endif %}
|
||||
{% if form.player3_score.errors %}{{ form.player3_score.errors }}{% endif %}
|
||||
|
||||
<p>
|
||||
<label for="id_player4" class="field_name {{ form.player4.css_classes }}">{{ form.player4.label }}</label>
|
||||
{{ form.player4 }}
|
||||
<label for="id_player4_score" class="{{ form.player4_score.css_classes }}">{{ form.player4_score.label }}</label>
|
||||
{{ form.player4_score}}
|
||||
</p>
|
||||
{% if form.player4.errors %}{{ form.player4.errors }}{% endif %}
|
||||
{% if form.player4_score.errors %}{{ form.player4_score.errors }}{% endif %}
|
||||
|
||||
<p>
|
||||
<label for="id_player5" class="field_name {{ form.player5.css_classes }}">{{ form.player5.label }}</label>
|
||||
{{ form.player5 }}
|
||||
<label for="id_player5_score" class="{{ form.player5_score.css_classes }}">{{ form.player5_score.label }}</label>
|
||||
{{ form.player5_score}}
|
||||
</p>
|
||||
{% if form.player5.errors %}{{ form.player5.errors }}{% endif %}
|
||||
{% if form.player5_score.errors %}{{ form.player5_score.errors }}{% endif %}
|
||||
|
||||
<p>
|
||||
<label for="id_player6" class="field_name {{ form.player6.css_classes }}">{{ form.player6.label }}</label>
|
||||
{{ form.player6 }}
|
||||
<label for="id_player6_score" class="{{ form.player6_score.css_classes }}">{{ form.player6_score.label }}</label>
|
||||
{{ form.player6_score}}
|
||||
</p>
|
||||
{% if form.player6.errors %}{{ form.player6.errors }}{% endif %}
|
||||
{% if form.player6_score.errors %}{{ form.player6_score.errors }}{% endif %}
|
||||
|
||||
<p>
|
||||
<label for="id_comment" class="field_name {{ form.comment.css_classes }}">{{ form.comment.label }}</label>
|
||||
{{ form.comment }}
|
||||
</p>
|
||||
<p class="buttonbar">
|
||||
<a href="{{game.get_absolute_url}}" class="button"><img
|
||||
src="{{STATIC_URL}}icons/arrow_undo.png"
|
||||
alt="{% trans 'Back' %}"/> {% trans 'Back' %}</a>
|
||||
<button type="submit"><img src="{{STATIC_URL}}icons/table_save.png"
|
||||
alt="{% trans 'Save' %}"/> {% trans 'Save' %}
|
||||
</button>
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block buttonbar %}{% endblock %}
|
||||
44
src/maistar_ranking/templates/maistar_ranking/game_list.html
Normal file
44
src/maistar_ranking/templates/maistar_ranking/game_list.html
Normal file
@@ -0,0 +1,44 @@
|
||||
{% extends "events/event_detail.html" %}
|
||||
{% load i18n humanize %}
|
||||
|
||||
{% block title %}{% trans 'Mai-Star Games' %} - {{ event.name }}{% endblock %}
|
||||
|
||||
{% block maincontent %}
|
||||
<h2 class="grid_12">{% trans 'Played Mai-Star Games' %}</h2>
|
||||
<p> </p>
|
||||
{% for game in game_list %}
|
||||
<article id="{{ game.pk }}">
|
||||
|
||||
<h3 class="grid_12">{{ forloop.counter|ordinal }} {% trans 'Game' %}</h3>
|
||||
{% for player in game.player_list %}
|
||||
<div class="grid_2 center">
|
||||
<h4>{{ player.placement|ordinal }} {% trans 'Place' %}</h4>
|
||||
<a href="{% url 'maistar-player-games' username=player.user.username season=game.season %}"><img
|
||||
src="{% if player.membership.thumbnail %}{{player.membership.thumbnail.url}}{% else %}{{STATIC_URL}}img/unknown_thumbnail.png{% endif %}" alt=""/></a>
|
||||
<p><a href="{% url 'maistar-player-games' username=player.user.username season=game.season %}">{{player.user.username}}</a><br/>
|
||||
{{player.score}} {% trans 'Points' %}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="grid_12 buttonbar">
|
||||
{% if perms.maistar_ranking.delete_dame %}
|
||||
<a class="button" href="{% url 'maistar-delete-game' game.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}"/> {% trans 'Delete Game' %}</a>
|
||||
{% endif %}
|
||||
{% if perms.maistar_ranking.change_game %}
|
||||
<a class="button" href="{% url 'maistar-edit-game' game.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" /> {% trans 'Edit Game' %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</article>
|
||||
{% empty %}
|
||||
<p class="grid_12">{% trans 'No Mai-Star games have been added to this event yet.'%}</p>
|
||||
{% endfor %}
|
||||
<p> </p>
|
||||
{% endblock %}
|
||||
|
||||
{% block buttonbar %}
|
||||
{% if perms.maistar_ranking.add_game %}
|
||||
<a class="button" href="{{event.get_edit_url}}"><img src="{{STATIC_URL}}icons/calendar_edit.png"
|
||||
alt="{% trans 'Add' %}"/> {% trans 'Edit Event' %}</a>
|
||||
<a class="button" href="{% url 'maistar-add-game' event.id %}"><img src="{{STATIC_URL}}icons/add.png"
|
||||
alt="{% trans 'Add' %}"/> {% trans 'Add Game' %}</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,26 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n comments %}
|
||||
|
||||
{% block meta_title %}{% trans 'Delete game' %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Delete game" %}</legend>
|
||||
{% include 'form.html' %}
|
||||
<p class="buttonbar">
|
||||
<button type="button" onclick="window.history.back()">
|
||||
<img src="{{STATIC_URL}}icons/cancel.png" alt="{% trans 'Cancel' %}"/>
|
||||
{% trans 'Cancel' %}
|
||||
</button>
|
||||
<button type="submit">
|
||||
<img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}"/>
|
||||
{% trans 'Delete' %}
|
||||
</button>
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block buttonbar %}{% endblock %}
|
||||
9
src/maistar_ranking/templates/maistar_ranking/page.html
Normal file
9
src/maistar_ranking/templates/maistar_ranking/page.html
Normal file
@@ -0,0 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block additional_nav_elements %}
|
||||
<a href="{% url 'season_ranking-archive' %}" class="{% if is_archive %}active{% endif %}">{% trans 'Archive' %}</a>
|
||||
{% if perms.events.add_event %}
|
||||
<a href="{% url 'event-form' %}" class="{% ifequal request.path '/events/add/' %}active{% endifequal %}">{% trans 'Add Event' %}</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,55 @@
|
||||
{% extends "membership/membership_detail.html" %}
|
||||
{% load i18n humanize %}
|
||||
|
||||
{% block title %} {% trans 'Ladder Score for' %} {{membership.user.username}} {% endblock %}
|
||||
|
||||
{% block teaser %} <h2>{% trans 'Mai-Star Games' %}: {{membership.user.username}} <br/> {% trans 'Season' %} {{season}}</h2> {% endblock %}
|
||||
|
||||
{% block score_list %}
|
||||
<div class="grid_12">
|
||||
<h2>{% trans 'Mai-Star Games with' %} {{ membership.user.username }} - {{season}}</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">{% trans 'Date' %}</th>
|
||||
<th rowspan="2">{% trans 'Event' %}</th>
|
||||
<th colspan="6">{% trans 'Players' %}</th>
|
||||
<th rowspan="2"></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ '1'|ordinal }}</th>
|
||||
<th>{{ '2'|ordinal }}</th>
|
||||
<th>{{ '3'|ordinal }}</th>
|
||||
<th>{{ '4'|ordinal }}</th>
|
||||
<th>{{ '5'|ordinal }}</th>
|
||||
<th>{{ '6'|ordinal }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for game in game_list %}
|
||||
<tr>
|
||||
<td class="center">{{ game.event.start|date:'SHORT_DATE_FORMAT' }}</td>
|
||||
<td><a href="{{ game.get_absolute_url }}">{{ game.event.name }}</a></td>
|
||||
</td>
|
||||
{% for player in game.player_list %}
|
||||
<td class="center">
|
||||
<a href="{% url 'maistar-player-games' username=player.user.username season=season %}">{{ player.user.username }}</a>
|
||||
<br/>{{player.score}} {% trans 'Points' %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
<td>
|
||||
{% if perms.maistar_ranking.delete_game %}
|
||||
<a href="{% url 'maistar-delete-game' game.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Game' %}"/></a>
|
||||
{% endif %}
|
||||
{% if perms.maistar_ranking.change_game %}
|
||||
<a href="{% url 'maistar-edit-game' game.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Game' %}"/></a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,79 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n comments humanize %}
|
||||
|
||||
{% block teaser %} <h2>{% trans 'Mai-Star Ranking' %} - {% trans 'Season' %} {{season}}</h2> {% endblock %}
|
||||
|
||||
{% block maincontent %}
|
||||
<main class="grid_12">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2">{% trans "Placement" %}</th>
|
||||
<th rowspan="2">{% trans "Avatar" %}</th>
|
||||
<th rowspan="2">{% trans "Nickname" %}</th>
|
||||
<th rowspan="2">{% trans "Name" %}</th>
|
||||
<th colspan="2">{% trans 'Average' %}</th>
|
||||
<th colspan="3">{% trans 'Games' %}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans 'Placement' %}</th>
|
||||
<th>{% trans "Score" %}</th>
|
||||
<th>{% trans "count" %}</th>
|
||||
<th>{% trans "good" %}</th>
|
||||
<th>{% trans "won" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for player in ranking_list %}
|
||||
{% with player.user.get_profile as profile %}
|
||||
<tr>
|
||||
<td class="center">{{ player.placement|ordinal }}</td>
|
||||
<td><a href="{{ player.get_absolute_url }}"><img src="{% if profile.thumbnail %}{{profile.thumbnail.url}}{% else %}{{STATIC_URL}}img/unknown_thumbnail.png{% endif %}" class="avatar" alt="{{ player.user }}"/></a></td>
|
||||
<td><a href="{{ player.get_absolute_url }}">{{player.user}}</a></td>
|
||||
<td>{% if user.is_authenticated %}{{profile.last_name}} {{profile.first_name}}{% else %} ---{% endif %}</td>
|
||||
<td class="right">{{player.avg_placement|floatformat:0 }}</td>
|
||||
<td class="right">{{player.avg_score|intcomma }}</td>
|
||||
<td class="right">{{player.games_count}}</td>
|
||||
<td class="right">{{player.games_good}}</td>
|
||||
<td class="right">{{player.games_won}}</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="8">{% blocktrans %}Unfortunately, nobody has it been done in the ranking.
|
||||
A player must have 6 games done, to be added to the ranking.{% endblocktrans %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
||||
{% block redbox %}
|
||||
<h2>{% trans 'Latest Games' %}</h2>
|
||||
<ul class="list">
|
||||
{% for game in latest_games %}
|
||||
<li class="hanchan">
|
||||
<a href="{% url 'maistar-game-list' game.event.pk %}">{{game.event.start|date:'SHORT_DATE_FORMAT'}}:</a>
|
||||
<small>{{game.player_names}}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h3>{% trans 'Latest Events' %}</h3>
|
||||
<ul class="list">
|
||||
{% for event in latest_events %}
|
||||
<li class="event"><a href="{% url 'maistar-game-list' event.pk %}">{{event.name}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h3>{% trans 'Ladder Archive' %}</h3>
|
||||
<form name="season_select">
|
||||
<label for="season">{% trans 'Season' %}</label>
|
||||
<select id="season" name="season" size="1" onChange="window.location.href = document.season_select.season.options[document.season_select.season.selectedIndex].value;">
|
||||
{% for season_link in season_list%}
|
||||
<option value="{% url 'maistar-ranking' season=season_link %}" {% ifequal season season_link %}selected="selected"{% endifequal %}>{{ season_link }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
32
src/maistar_ranking/urls.py
Normal file
32
src/maistar_ranking/urls.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Created on 03.10.2011
|
||||
|
||||
@author: christian
|
||||
"""
|
||||
from django.conf.urls import * # @UnusedWildImport
|
||||
from django.views.generic import RedirectView
|
||||
from .views import DeleteGame, ListGames, ListPlayerGames, \
|
||||
ListRankings, GameForm
|
||||
|
||||
|
||||
urlpatterns = patterns(
|
||||
'maistar_ranking.views',
|
||||
url('^$', RedirectView.as_view(pattern_name='maistar-ranking', permanent=True)),
|
||||
url(r'ranking/$', ListRankings.as_view(), name="maistar-ranking"),
|
||||
url(r'ranking/(?P<season>[\d]+)/$', ListRankings.as_view(),
|
||||
name="maistar-ranking"), # @IgnorePep8
|
||||
url(r'event/(?P<event>[\d]+)/$', ListGames.as_view(),
|
||||
name="maistar-game-list"), # @IgnorePep8
|
||||
url(r'event/(?P<event>[\d]+)/add/$', GameForm.as_view(),
|
||||
name="maistar-add-game"), # @IgnorePep8
|
||||
url(r'game/(?P<game>[\d]+)/edit/$', GameForm.as_view(),
|
||||
name="maistar-edit-game"), # @IgnorePep8
|
||||
url(r'game/(?P<game>[\d]+)/delete/$', DeleteGame.as_view(),
|
||||
name="maistar-delete-game"), # @IgnorePep8
|
||||
url(r'player/(?P<username>[\-\.\d\w]+)/$', ListPlayerGames.as_view(),
|
||||
name="maistar-player-games"), # @IgnorePep8
|
||||
url(r'player/(?P<username>[\-\.\d\w]+)/(?P<season>[\d]+)/$',
|
||||
ListPlayerGames.as_view(), name="maistar-player-games"), # @IgnorePep8
|
||||
|
||||
)
|
||||
121
src/maistar_ranking/views.py
Normal file
121
src/maistar_ranking/views.py
Normal file
@@ -0,0 +1,121 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from datetime import date
|
||||
|
||||
from django.contrib import auth
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views import generic
|
||||
|
||||
from events.models import Event
|
||||
from events.views import EventDetailMixin
|
||||
from membership.models import Membership
|
||||
from utils.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||
from mahjong_ranking.views import PlayerScore
|
||||
from . import forms, models
|
||||
|
||||
|
||||
class GameForm(EventDetailMixin, PermissionRequiredMixin, generic.UpdateView):
|
||||
model = models.Game
|
||||
permission_required = 'maistar_ranking.add_game'
|
||||
form_class = forms.GameForm
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
if 'game' in self.kwargs:
|
||||
game = get_object_or_404(models.Game, pk=self.kwargs['game'])
|
||||
elif 'event' in self.kwargs:
|
||||
self.event = get_object_or_404(Event, pk=self.kwargs['event'])
|
||||
game = models.Game(event=self.event)
|
||||
return game
|
||||
|
||||
|
||||
class DeleteGame(EventDetailMixin, PermissionRequiredMixin, generic.DeleteView):
|
||||
"""
|
||||
Fragt zuerst nach, ob die Hanchan wirklich gelöscht werden soll.
|
||||
Wir die Frage mit "Ja" beantwortet, wird die die Hanchan gelöscht.
|
||||
"""
|
||||
model = models.Game
|
||||
permission_required = 'maistar_ranking.delete_game'
|
||||
pk_url_kwarg = 'hanchan'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse(
|
||||
'maistar_ranking-game-list',
|
||||
kwargs={'event': self.object.event.pk}
|
||||
)
|
||||
|
||||
|
||||
class UpdateGame(EventDetailMixin, PermissionRequiredMixin, generic.UpdateView):
|
||||
"""
|
||||
Ein Formular um eine neues Spiel anzulegen, bzw. eine bestehendes zu
|
||||
bearbeiten.
|
||||
"""
|
||||
model = models.Game
|
||||
permission_required = 'maistar_ranking.update_game'
|
||||
|
||||
def get_object(self, queryset=None): # @UnusedVariable
|
||||
game = models.Game.objects.get(id=self.kwargs['game'])
|
||||
self.event = game.event
|
||||
return game
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = generic.UpdateView.get_context_data(self, **kwargs)
|
||||
context['event'] = self.event
|
||||
return context
|
||||
|
||||
|
||||
class ListGames(EventDetailMixin, generic.ListView):
|
||||
"""
|
||||
Auflistung aller Spiele welche während einer Veranstaltung gespielt wurden.
|
||||
"""
|
||||
model = models.Game
|
||||
|
||||
def get_queryset(self):
|
||||
self.event = get_object_or_404(models.Event, pk=self.kwargs['event'])
|
||||
return models.Game.objects.filter(event=self.event).select_related()
|
||||
|
||||
|
||||
class ListPlayerGames(PlayerScore):
|
||||
template_name = 'maistar_ranking/player_game_list.html'
|
||||
paginate_by = 25
|
||||
context_object_name = 'game_list'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(ListPlayerGames, self).get_context_data()
|
||||
context['membership'] = Membership.objects.get(user=self.user)
|
||||
context['season_list'] = models.Ranking.objects.filter(user=self.user).values_list('season', flat=True)
|
||||
context['season'] = self.season
|
||||
return context
|
||||
|
||||
def get_queryset(self, **kwargs):
|
||||
self.user = get_object_or_404(auth.get_user_model(),
|
||||
username=self.kwargs.get('username'))
|
||||
self.season = self.kwargs.get('season', date.today().year)
|
||||
return models.Game.objects.player_games(player=self.user,
|
||||
season=self.season)
|
||||
|
||||
|
||||
class ListRankings(generic.ListView):
|
||||
model = models.Ranking
|
||||
paginate_by = 50
|
||||
season = None
|
||||
is_archive = False
|
||||
|
||||
def get_queryset(self):
|
||||
self.season = int(self.kwargs.get('season', date.today().year))
|
||||
queryset = models.Ranking.objects.filter(
|
||||
season=self.season,
|
||||
placement__isnull=False
|
||||
)
|
||||
queryset = queryset.select_related()
|
||||
return queryset
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = generic.ListView.get_context_data(self, **kwargs)
|
||||
context['is_archive'] = self.is_archive
|
||||
context['season'] = self.season
|
||||
context['season_list'] = models.Ranking.objects.get_seasons()
|
||||
context['latest_games'] = models.Game.objects.filter(confirmed=True)[:3]
|
||||
context['latest_events'] = Event.objects.archive()[:3]
|
||||
return context
|
||||
Reference in New Issue
Block a user