Stylesheets werden nur mit Less erzeugt. Damit können sie gleich
optimiert werden. jQuery wurde entfernt. Übersetzungen wurden korrigiert. Neue sync.sh Datei, welche änderungen mit rsync auf den Server spielt und das neuladen erzwingt.
This commit is contained in:
0
maistar_ranking/__init__.py
Normal file
0
maistar_ranking/__init__.py
Normal file
64
maistar_ranking/admin.py
Normal file
64
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
maistar_ranking/forms.py
Normal file
37
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
|
||||
BIN
maistar_ranking/locale/de/LC_MESSAGES/django.mo
Normal file
BIN
maistar_ranking/locale/de/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
272
maistar_ranking/locale/de/LC_MESSAGES/django.po
Normal file
272
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: 2014-12-14 01:12+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
maistar_ranking/managers.py
Normal file
60
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
maistar_ranking/models.py
Normal file
221
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
maistar_ranking/settings.py
Normal file
24
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
maistar_ranking/templates/maistar_ranking/game_form.html
Normal file
87
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
maistar_ranking/templates/maistar_ranking/game_list.html
Normal file
44
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
maistar_ranking/templates/maistar_ranking/page.html
Normal file
9
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 %}
|
||||
79
maistar_ranking/templates/maistar_ranking/ranking_list.html
Normal file
79
maistar_ranking/templates/maistar_ranking/ranking_list.html
Normal file
@@ -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
maistar_ranking/urls.py
Normal file
32
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')),
|
||||
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
maistar_ranking/views.py
Normal file
121
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