Fehlerbereinigung.
Mahjong Ranking berechnet nun die richtigen Ränge zu den legendären Kyu/Dan Punkten. Stablie Version bevor die Datenstruktur des Mahjongrankings vereinfacht wird.
This commit is contained in:
committed by
Christian Berg
parent
bafbf38612
commit
79eaeb34ad
@@ -28,7 +28,7 @@ DAN_RANKS = (
|
||||
)
|
||||
|
||||
DAN_RANKS_DICT = dict([(dan, points) for points, dan in DAN_RANKS])
|
||||
MIN_HANCHANS_FOR_LADDER = 10
|
||||
MIN_HANCHANS_FOR_LADDER = 5
|
||||
|
||||
logger = getLogger('kasu.mahjong_ranking')
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ recalculate.short_description = _("Recalculate")
|
||||
class PlayerInline(admin.TabularInline):
|
||||
extra = 4
|
||||
formset = PlayerFormSet
|
||||
readonly_fields = ('placement', 'kyu_points', 'dan_points', 'bonus_points',
|
||||
readonly_fields = ('game_score', 'placement', 'kyu_points', 'dan_points', 'bonus_points',
|
||||
'comment',)
|
||||
max_num = 4
|
||||
model = models.Player
|
||||
@@ -47,7 +47,7 @@ class PlayerInline(admin.TabularInline):
|
||||
class EventRankingAdmin(admin.ModelAdmin):
|
||||
list_filter = ['event']
|
||||
list_display = ('placement', 'user', 'event', 'avg_placement', 'avg_score',
|
||||
'hanchan_count', 'good_hanchans', 'won_hanchans', 'dirty')
|
||||
'hanchan_count', 'good_hanchans', 'won_hanchans')
|
||||
list_display_links = ('user',)
|
||||
actions = [recalculate]
|
||||
|
||||
@@ -70,21 +70,32 @@ class HanchanAdmin(admin.ModelAdmin):
|
||||
class KyuDanAdmin(admin.ModelAdmin):
|
||||
actions = [recalculate]
|
||||
list_display = ('user', 'kyu', 'kyu_points', 'dan', 'dan_points',
|
||||
'hanchan_count', 'dirty')
|
||||
'hanchan_count')
|
||||
readonly_fields = ('user', 'kyu', 'kyu_points', 'dan', 'dan_points')
|
||||
fieldsets = (
|
||||
('Aktueller Dan/Kyū', {
|
||||
'fields': ('user', ('kyu', 'kyu_points'), ('dan', 'dan_points')),
|
||||
'classes': ('grp-collapse grp-open',),
|
||||
}),
|
||||
('Frühere Aufzeichnungen', {
|
||||
'fields': ('legacy_date', ('legacy_kyu_points', 'legacy_dan_points')),
|
||||
'classes': ('grp-collapse grp-closed',),
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
class LadderRankingAdmin(admin.ModelAdmin):
|
||||
actions = [recalculate]
|
||||
list_display = ('placement', 'season', 'user', 'avg_placement',
|
||||
'avg_score', 'hanchan_count', 'good_hanchans',
|
||||
'won_hanchans', 'dirty')
|
||||
'won_hanchans')
|
||||
list_display_links = ('user',)
|
||||
list_filter = ('season',)
|
||||
|
||||
|
||||
class LadderSeasonAdmin(admin.ModelAdmin):
|
||||
actions = [recalculate]
|
||||
list_display = ('name', 'start', 'end', 'dirty')
|
||||
list_display = ('name', 'start', 'end')
|
||||
|
||||
|
||||
admin.site.register(models.EventRanking, EventRankingAdmin)
|
||||
|
||||
@@ -65,24 +65,30 @@ class PlayerForm(forms.ModelForm):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PlayerForm, self).__init__(*args, **kwargs)
|
||||
self.fields['input_score'].widget.attrs['size'] = 6
|
||||
self.fields['input_score'].widget.attrs['type'] = 'number'
|
||||
self.fields['bonus_points'].widget.attrs['readonly'] = True
|
||||
self.fields['bonus_points'].widget.attrs['size'] = 2
|
||||
self.fields['comment'].widget.attrs['readonly'] = True
|
||||
self.fields['score'].widget.attrs['size'] = 6
|
||||
self.fields['score'].widget.attrs['type'] = 'number'
|
||||
|
||||
class Meta(object):
|
||||
model = models.Player
|
||||
fields = ('hanchan', 'user', 'score', 'bonus_points', 'comment')
|
||||
fields = ('hanchan', 'user', 'input_score', 'bonus_points', 'comment')
|
||||
|
||||
|
||||
class PlayerInlineFormSet(BaseInlineFormSet):
|
||||
def clean(self):
|
||||
"""Checks that no two articles have the same title."""
|
||||
if any(self.errors):
|
||||
return
|
||||
playerset = set()
|
||||
for form in self.forms:
|
||||
if form.is_valid() and not form.cleaned_data.get('user'):
|
||||
raise forms.ValidationError(
|
||||
_("A valid Hanchan needs 4 players"))
|
||||
raise forms.ValidationError(_("A valid Hanchan needs 4 players"))
|
||||
player = form.cleaned_data['user']
|
||||
if player in playerset:
|
||||
message = _("Player %s cant attend the game multiple times.") % player
|
||||
raise forms.ValidationError(message)
|
||||
playerset.add(player)
|
||||
self.validate_unique()
|
||||
return False
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ 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: 2015-01-04 11:58+0100\n"
|
||||
"POT-Creation-Date: 2015-08-16 11:34+0200\n"
|
||||
"PO-Revision-Date: 2015-08-16 11:39+0200\n"
|
||||
"Last-Translator: Christian Berg <xeniac.at@gmail.com>\n"
|
||||
"Language-Team: Kasu <verein@kasu.at>\n"
|
||||
"Language: de\n"
|
||||
@@ -17,43 +17,48 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Translated-Using: django-rosetta 0.7.2\n"
|
||||
"X-Generator: Poedit 1.7.1\n"
|
||||
"X-Generator: Poedit 1.8.3\n"
|
||||
|
||||
#: admin.py:35
|
||||
msgid "Recalculate"
|
||||
msgstr "Neuberechnen"
|
||||
|
||||
#: forms.py:21
|
||||
#: forms.py:24
|
||||
msgid "start"
|
||||
msgstr "Beginn"
|
||||
|
||||
#: forms.py:40 models.py:168
|
||||
#: forms.py:41 models.py:164
|
||||
msgid "It's not allowed to enter future games."
|
||||
msgstr "Spiele in der Zukunft sind nicht erlaubt."
|
||||
|
||||
#: forms.py:43
|
||||
#: forms.py:44
|
||||
msgid "Only games running during this event are allowed."
|
||||
msgstr "Nur Spiele während der Veranstaltung sind erlaubt."
|
||||
|
||||
#: forms.py:88
|
||||
#: forms.py:86
|
||||
msgid "A valid Hanchan needs 4 players"
|
||||
msgstr "Eine gültige Hanchan braucht 4 Spieler"
|
||||
|
||||
#: models.py:84 models.py:613 templates/mahjong_ranking/hanchan_form.html:30
|
||||
#: forms.py:89
|
||||
#, python-format
|
||||
msgid "Player %s cant attend the game multiple times."
|
||||
msgstr "%s kann an einem Spiel nicht mehrfach teilnehmen."
|
||||
|
||||
#: models.py:78 models.py:617 templates/mahjong_ranking/hanchan_form.html:26
|
||||
#: templates/mahjong_ranking/player_dan_score.html:19
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:18
|
||||
msgid "Comment"
|
||||
msgstr "Kommentar"
|
||||
|
||||
#: models.py:85
|
||||
#: models.py:79
|
||||
msgid "Has been Confirmed"
|
||||
msgstr "Wurde bestätigt"
|
||||
|
||||
#: models.py:87
|
||||
#: models.py:81
|
||||
msgid "Only valid and confirmed Hanchans will be counted in the rating."
|
||||
msgstr "Nur gültige und bestätigte Hanchans kommen in die Wertung."
|
||||
|
||||
#: models.py:93 templates/mahjong_ranking/hanchan_form.html:23
|
||||
#: models.py:87 templates/mahjong_ranking/hanchan_form.html:19
|
||||
#: templates/mahjong_ranking/player_dan_score.html:17
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:15
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:18
|
||||
@@ -61,7 +66,7 @@ msgstr "Nur gültige und bestätigte Hanchans kommen in die Wertung."
|
||||
msgid "Players"
|
||||
msgstr "Spieler"
|
||||
|
||||
#: models.py:97 templates/mahjong_ranking/ladderranking_list.html:8
|
||||
#: models.py:91 templates/mahjong_ranking/ladderranking_list.html:8
|
||||
#: templates/mahjong_ranking/player_dan_score.html:15
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:14
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:16
|
||||
@@ -69,62 +74,118 @@ msgstr "Spieler"
|
||||
msgid "Start"
|
||||
msgstr "Beginn"
|
||||
|
||||
#: models.py:98
|
||||
#: models.py:92
|
||||
msgid "This is crucial to get the right Hanchans that scores"
|
||||
msgstr "Wichtig damit die richtigen Hanchans in die Wertung kommen."
|
||||
|
||||
#: models.py:99
|
||||
#: models.py:93
|
||||
msgid "Is Valid"
|
||||
msgstr "Ist gültig"
|
||||
|
||||
#: models.py:103
|
||||
#: models.py:97
|
||||
msgid "Hanchan"
|
||||
msgstr "Hanchan"
|
||||
|
||||
#: models.py:104
|
||||
#: models.py:98 templates/mahjong_ranking/eventranking_list.html:18
|
||||
msgid "Hanchans"
|
||||
msgstr "Hanchans"
|
||||
|
||||
#: models.py:125
|
||||
#: models.py:119
|
||||
msgid "For a Hanchan exactly 4 players are needed."
|
||||
msgstr "Eine Hanchan benötigt genau 4 Spieler."
|
||||
|
||||
#: models.py:166
|
||||
#: models.py:160
|
||||
msgid "Hanchan has no event"
|
||||
msgstr "Hanchan gehört zu keiner Veranstaltung."
|
||||
|
||||
#: models.py:170
|
||||
#: models.py:162
|
||||
#, fuzzy
|
||||
#| msgid "Hanchan has no event"
|
||||
msgid "Hanchan has no start time set"
|
||||
msgstr "Hanchan gehört zu keiner Veranstaltung."
|
||||
|
||||
#: models.py:166
|
||||
msgid "Only games during the event are allowed"
|
||||
msgstr "Nur Spiele während der Veranstaltung zählen."
|
||||
|
||||
#: models.py:238
|
||||
#: models.py:236
|
||||
msgid "Kyū/Dan Ranking"
|
||||
msgstr "Kyū/Dan Wertung"
|
||||
|
||||
#: models.py:239
|
||||
#: models.py:237
|
||||
msgid "Kyū/Dan Rankings"
|
||||
msgstr "Kyū/Dan Wertungen"
|
||||
|
||||
#: models.py:500
|
||||
#: models.py:505
|
||||
msgid "Ladder Season"
|
||||
msgstr "Saison"
|
||||
|
||||
#: models.py:501
|
||||
#: models.py:506
|
||||
msgid "Ladder Seasons"
|
||||
msgstr "Saisons"
|
||||
|
||||
#: views.py:148 views.py:165
|
||||
msgid "Event does not exist"
|
||||
msgstr "Veranstaltung existiert nicht"
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:7
|
||||
msgid "Played Hanchans"
|
||||
msgstr "Gespielte Hanchans"
|
||||
|
||||
#: views.py:206
|
||||
msgid "Season does not exist"
|
||||
msgstr "Saison existiert nicht"
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:15
|
||||
msgid "Place"
|
||||
msgstr "Platz"
|
||||
|
||||
#: views.py:300
|
||||
#, python-format
|
||||
msgid "No user found matching the name %s"
|
||||
msgstr "Kein Benutzer mit dem Namen %s gefunden"
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:16
|
||||
#: templates/mahjong_ranking/eventranking_list.html:22
|
||||
#: templates/mahjong_ranking/hanchan_form.html:24
|
||||
#: templates/mahjong_ranking/kyudanranking_list.html:30
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:29
|
||||
msgid "Score"
|
||||
msgstr "Punkte"
|
||||
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:18
|
||||
#: templates/mahjong_ranking/player_dan_score.html:18
|
||||
msgid "Dan Points"
|
||||
msgstr "Dan Punkte"
|
||||
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:20
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:17
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:19
|
||||
msgid "Kyu Points"
|
||||
msgstr "Kyu Punkte"
|
||||
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:34
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:4
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:10
|
||||
#: templates/mahjong_ranking/player_dan_score.html:45
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:34
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:42
|
||||
#: templates/mahjong_ranking/player_ladder_score.html:39
|
||||
msgid "Delete Hanchan"
|
||||
msgstr "Hanchan löschen"
|
||||
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:37
|
||||
#: templates/mahjong_ranking/hanchan_form.html:4
|
||||
#: templates/mahjong_ranking/hanchan_form.html:16
|
||||
#: templates/mahjong_ranking/player_dan_score.html:48
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:37
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:45
|
||||
#: templates/mahjong_ranking/player_ladder_score.html:42
|
||||
msgid "Edit Hanchan"
|
||||
msgstr "Hanchan bearbeiten"
|
||||
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:41
|
||||
msgid "No Hanchan has been added to this event yet."
|
||||
msgstr "Für diese Veranstaltung wurde noch keine Hanchan eingetragen."
|
||||
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:47
|
||||
#: templates/mahjong_ranking/eventranking_list.html:55
|
||||
msgid "Edit Event"
|
||||
msgstr "Veranstaltung bearbeiten"
|
||||
|
||||
#: templates/mahjong_ranking/eventhanchan_list.html:48
|
||||
#: templates/mahjong_ranking/eventranking_list.html:56
|
||||
#: templates/mahjong_ranking/hanchan_form.html:4
|
||||
#: templates/mahjong_ranking/hanchan_form.html:16
|
||||
msgid "Add Hanchan"
|
||||
msgstr "Hanchan hinzufügen"
|
||||
|
||||
#: templates/mahjong_ranking/eventranking_list.html:5
|
||||
#: templates/mahjong_ranking/eventranking_list.html:6
|
||||
@@ -168,14 +229,6 @@ msgstr "Durchschnitt"
|
||||
msgid "Placement"
|
||||
msgstr "Platzierung"
|
||||
|
||||
#: templates/mahjong_ranking/eventranking_list.html:22
|
||||
#: templates/mahjong_ranking/hanchan_form.html:28
|
||||
#: templates/mahjong_ranking/hanchan_list.html:16
|
||||
#: templates/mahjong_ranking/kyudanranking_list.html:30
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:29
|
||||
msgid "Score"
|
||||
msgstr "Punkte"
|
||||
|
||||
#: templates/mahjong_ranking/eventranking_list.html:23
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:30
|
||||
msgid "count"
|
||||
@@ -191,118 +244,30 @@ msgstr "gut"
|
||||
msgid "won"
|
||||
msgstr "gewonnen"
|
||||
|
||||
#: templates/mahjong_ranking/eventranking_list.html:58
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:77
|
||||
msgid "Ladder Archive"
|
||||
msgstr "Ladder Archiv"
|
||||
|
||||
#: templates/mahjong_ranking/eventranking_list.html:65
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:71
|
||||
msgid "Latest Events"
|
||||
msgstr "Letzte Veranstaltungen"
|
||||
|
||||
#: templates/mahjong_ranking/eventranking_list.html:72
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:61
|
||||
msgid "Latest Hanchans"
|
||||
msgstr "Letzten Hanchans"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:4
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:10
|
||||
#: templates/mahjong_ranking/hanchan_list.html:36
|
||||
#: templates/mahjong_ranking/player_dan_score.html:47
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:34
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:42
|
||||
#: templates/mahjong_ranking/player_ladder_score.html:39
|
||||
msgid "Delete Hanchan"
|
||||
msgstr "Hanchan löschen"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:14
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:15
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:16
|
||||
msgid "Cancel"
|
||||
msgstr "Abbruch"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:18
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:19
|
||||
#: templates/mahjong_ranking/hanchan_list.html:35
|
||||
#: templates/mahjong_ranking/player_dan_score.html:46
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:34
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:42
|
||||
#: templates/mahjong_ranking/player_ladder_score.html:39
|
||||
#: templates/mahjong_ranking/hanchan_confirm_delete.html:17
|
||||
msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_form.html:5
|
||||
#: templates/mahjong_ranking/hanchan_form.html:20
|
||||
#: templates/mahjong_ranking/hanchan_list.html:41
|
||||
#: templates/mahjong_ranking/player_dan_score.html:52
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:37
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:45
|
||||
#: templates/mahjong_ranking/player_ladder_score.html:42
|
||||
msgid "Edit Hanchan"
|
||||
msgstr "Hanchan bearbeiten"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_form.html:5
|
||||
#: templates/mahjong_ranking/hanchan_form.html:20
|
||||
#: templates/mahjong_ranking/hanchan_list.html:54
|
||||
msgid "Add Hanchan"
|
||||
msgstr "Hanchan hinzufügen"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_form.html:27
|
||||
#: templates/mahjong_ranking/hanchan_form.html:23
|
||||
msgid "User"
|
||||
msgstr "Benutzer"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_form.html:29
|
||||
#: templates/mahjong_ranking/hanchan_form.html:25
|
||||
msgid "Bonus"
|
||||
msgstr "Bonus"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_form.html:51
|
||||
#: templates/mahjong_ranking/hanchan_form.html:46
|
||||
msgid "back"
|
||||
msgstr "Zurück"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_form.html:52
|
||||
#: templates/mahjong_ranking/hanchan_form.html:47
|
||||
msgid "save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:7
|
||||
msgid "Played Hanchans"
|
||||
msgstr "Gespielte Hanchans"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:15
|
||||
msgid "Place"
|
||||
msgstr "Platz"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:18
|
||||
#: templates/mahjong_ranking/player_dan_score.html:18
|
||||
msgid "Dan Points"
|
||||
msgstr "Dan Punkte"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:20
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:17
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:19
|
||||
msgid "Kyu Points"
|
||||
msgstr "Kyu Punkte"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:40
|
||||
#: templates/mahjong_ranking/player_dan_score.html:51
|
||||
#: templates/mahjong_ranking/player_invalid_score.html:37
|
||||
#: templates/mahjong_ranking/player_kyu_score.html:45
|
||||
#: templates/mahjong_ranking/player_ladder_score.html:42
|
||||
msgid "Edit"
|
||||
msgstr "Bearbeiten"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:45
|
||||
msgid "No Hanchan has been added to this event yet."
|
||||
msgstr "Für diese Veranstaltung wurde noch keine Hanchan eingetragen."
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:52
|
||||
#: templates/mahjong_ranking/hanchan_list.html:54
|
||||
msgid "Add"
|
||||
msgstr "Hinzufügen"
|
||||
|
||||
#: templates/mahjong_ranking/hanchan_list.html:52
|
||||
msgid "Edit Event"
|
||||
msgstr "Veranstaltung bearbeiten"
|
||||
|
||||
#: templates/mahjong_ranking/kyudanranking_list.html:4
|
||||
#: templates/mahjong_ranking/kyudanranking_list.html:5
|
||||
msgid "Player List"
|
||||
@@ -324,7 +289,19 @@ msgstr "Ende"
|
||||
msgid "Participants"
|
||||
msgstr "Teilnehmer"
|
||||
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:79
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:59
|
||||
msgid "Latest Hanchans"
|
||||
msgstr "Letzten Hanchans"
|
||||
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:68
|
||||
msgid "Latest Events"
|
||||
msgstr "Letzte Veranstaltungen"
|
||||
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:74
|
||||
msgid "Ladder Archive"
|
||||
msgstr "Ladder Archiv"
|
||||
|
||||
#: templates/mahjong_ranking/ladderranking_list.html:76
|
||||
#: templates/mahjong_ranking/player_ladder_score.html:51
|
||||
msgid "Season"
|
||||
msgstr "Saison"
|
||||
@@ -387,5 +364,24 @@ msgstr "Hanchans welche in der Ladder zählen"
|
||||
msgid "Go"
|
||||
msgstr "Los"
|
||||
|
||||
#: views.py:149 views.py:166
|
||||
msgid "Event does not exist"
|
||||
msgstr "Veranstaltung existiert nicht"
|
||||
|
||||
#: views.py:207
|
||||
msgid "Season does not exist"
|
||||
msgstr "Saison existiert nicht"
|
||||
|
||||
#: views.py:300
|
||||
#, python-format
|
||||
msgid "No user found matching the name %s"
|
||||
msgstr "Kein Benutzer mit dem Namen %s gefunden"
|
||||
|
||||
#~ msgid "Edit"
|
||||
#~ msgstr "Bearbeiten"
|
||||
|
||||
#~ msgid "Add"
|
||||
#~ msgstr "Hinzufügen"
|
||||
|
||||
#~ msgid "Tournament Hanchans"
|
||||
#~ msgstr "Turnierwertungen"
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('events', '__first__'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EventRanking',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('placement', models.PositiveIntegerField(null=True, blank=True)),
|
||||
('avg_placement', models.FloatField(default=4)),
|
||||
('avg_score', models.FloatField(default=0)),
|
||||
('hanchan_count', models.PositiveIntegerField(default=0)),
|
||||
('good_hanchans', models.PositiveIntegerField(default=0)),
|
||||
('won_hanchans', models.PositiveIntegerField(default=0)),
|
||||
('dirty', models.BooleanField(default=True, editable=False)),
|
||||
('event', models.ForeignKey(to='events.Event')),
|
||||
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'ordering': ('placement', 'avg_placement', '-avg_score'),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Hanchan',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('comment', models.TextField(verbose_name='Anmerkung', blank=True)),
|
||||
('confirmed', models.BooleanField(default=True, help_text='Nur g\xfcltige und best\xe4tigte Hanchans kommen in die Wertung.', verbose_name='Wurde best\xe4tigt')),
|
||||
('player_names', models.CharField(max_length=127, editable=False)),
|
||||
('start', models.DateTimeField(help_text='Wichtig damit die richtigen Hanchans in die Wertung kommen.', verbose_name='Beginn')),
|
||||
('valid', models.BooleanField(default=False, verbose_name='Ist g\xfcltig')),
|
||||
('event', models.ForeignKey(to='events.Event')),
|
||||
],
|
||||
options={
|
||||
'ordering': ('-start',),
|
||||
'verbose_name': 'Hanchan',
|
||||
'verbose_name_plural': 'Hanchans',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KyuDanRanking',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('dan', models.PositiveSmallIntegerField(null=True, blank=True)),
|
||||
('dan_points', models.PositiveIntegerField(default=0)),
|
||||
('kyu', models.PositiveSmallIntegerField(default=10, null=True, blank=True)),
|
||||
('kyu_points', models.PositiveIntegerField(default=0)),
|
||||
('won_hanchans', models.PositiveIntegerField(default=0)),
|
||||
('good_hanchans', models.PositiveIntegerField(default=0)),
|
||||
('hanchan_count', models.PositiveIntegerField(default=0)),
|
||||
('dirty', models.BooleanField(default=True, editable=False)),
|
||||
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'ordering': ('-dan_points', '-kyu_points'),
|
||||
'verbose_name': 'Ky\u016b/Dan Wertung',
|
||||
'verbose_name_plural': 'Ky\u016b/Dan Wertungen',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LadderRanking',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('placement', models.PositiveIntegerField(null=True, blank=True)),
|
||||
('avg_placement', models.FloatField(null=True, blank=True)),
|
||||
('avg_score', models.FloatField(null=True, blank=True)),
|
||||
('hanchan_count', models.PositiveIntegerField(default=0)),
|
||||
('good_hanchans', models.PositiveIntegerField(default=0)),
|
||||
('won_hanchans', models.PositiveIntegerField(default=0)),
|
||||
('dirty', models.BooleanField(default=True, editable=False)),
|
||||
],
|
||||
options={
|
||||
'ordering': ('placement', 'avg_placement', '-avg_score'),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LadderSeason',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('start', models.DateField()),
|
||||
('end', models.DateField()),
|
||||
('dirty', models.BooleanField(default=True, editable=False)),
|
||||
],
|
||||
options={
|
||||
'ordering': ('start',),
|
||||
'verbose_name': 'Saison',
|
||||
'verbose_name_plural': 'Saisons',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Player',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('score', models.PositiveIntegerField(default=0)),
|
||||
('placement', models.PositiveSmallIntegerField(default=None, null=True, blank=True)),
|
||||
('kyu_points', models.PositiveSmallIntegerField(default=None, null=True, blank=True)),
|
||||
('dan_points', models.PositiveSmallIntegerField(default=None, null=True, blank=True)),
|
||||
('bonus_points', models.PositiveSmallIntegerField(default=0, null=True, blank=True)),
|
||||
('comment', models.TextField(verbose_name='Anmerkung', blank=True)),
|
||||
('hanchan', models.ForeignKey(to='mahjong_ranking.Hanchan')),
|
||||
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-score'],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ladderranking',
|
||||
name='season',
|
||||
field=models.ForeignKey(to='mahjong_ranking.LadderSeason'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ladderranking',
|
||||
name='user',
|
||||
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='hanchan',
|
||||
name='players',
|
||||
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Spieler', through='mahjong_ranking.Player'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='hanchan',
|
||||
name='season',
|
||||
field=models.ForeignKey(blank=True, editable=False, to='mahjong_ranking.LadderSeason', null=True),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='player',
|
||||
unique_together=set([('hanchan', 'user')]),
|
||||
),
|
||||
]
|
||||
@@ -1,5 +1,7 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# TODO: Rankings archiv Flag erstellen, womit sie nicht mehr neuberechnet werden dürfen.
|
||||
|
||||
from datetime import date, timedelta
|
||||
|
||||
from django.conf import settings
|
||||
@@ -33,7 +35,6 @@ class EventRanking(models.Model):
|
||||
hanchan_count = models.PositiveIntegerField(default=0)
|
||||
good_hanchans = models.PositiveIntegerField(default=0)
|
||||
won_hanchans = models.PositiveIntegerField(default=0)
|
||||
dirty = models.BooleanField(default=True, editable=False)
|
||||
|
||||
class Meta(object):
|
||||
ordering = ('placement', 'avg_placement', '-avg_score',)
|
||||
@@ -48,10 +49,6 @@ class EventRanking(models.Model):
|
||||
Diese Daten werden benötigt um die Platzierung zu erstellen. Sie
|
||||
können zwar sehr leicht errechnet werden, es macht trotzdem Sinn
|
||||
sie zwischen zu speichern.
|
||||
|
||||
Das Eigenschaft dirty ist ein altes Überbleibsel, um das Objekt
|
||||
zur neuberrechnung zu markieren. Mittlerweile wird ein lokaler
|
||||
Cache dafür verwendet, das ist schneller.
|
||||
"""
|
||||
logger.info(u'Recalculate EventRanking for Player %s in %s', self.user,
|
||||
self.event.name) # @IgnorePep8
|
||||
@@ -59,14 +56,13 @@ class EventRanking(models.Model):
|
||||
event=self.event_id) # @IgnorePep8
|
||||
aggregator = event_hanchans.aggregate(
|
||||
models.Avg('placement'),
|
||||
models.Avg('score'),
|
||||
models.Avg('game_score'),
|
||||
models.Count('pk'))
|
||||
self.avg_placement = aggregator['placement__avg']
|
||||
self.avg_score = aggregator['score__avg']
|
||||
self.hanchan_count = aggregator['pk__count']
|
||||
self.good_hanchans = event_hanchans.filter(placement__lt=3).count()
|
||||
self.won_hanchans = event_hanchans.filter(placement=1).count()
|
||||
self.dirty = False
|
||||
if self.hanchan_count <= 0:
|
||||
self.delete()
|
||||
else:
|
||||
@@ -80,20 +76,16 @@ class Hanchan(models.Model):
|
||||
Außerdem gehört jede Hanchan zu einer Veranstaltung.
|
||||
"""
|
||||
comment = models.TextField(_('Comment'), blank=True)
|
||||
confirmed = models.BooleanField(_('Has been Confirmed'), default=True,
|
||||
help_text=_(
|
||||
'Only valid and confirmed Hanchans will be counted in the rating.')) # @IgnorePep8
|
||||
confirmed = models.BooleanField(_('Has been Confirmed'), default=True, help_text=_('Only valid and confirmed Hanchans will be counted in the rating.')) # @IgnorePep8
|
||||
event = models.ForeignKey(Event)
|
||||
player_names = models.CharField(max_length=127, editable=False)
|
||||
player_names = models.CharField(max_length=255, editable=False)
|
||||
players = models.ManyToManyField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
through='Player',
|
||||
verbose_name=_('Players')
|
||||
)
|
||||
season = models.ForeignKey('LadderSeason', blank=True, null=True,
|
||||
editable=False) # @IgnorePep8
|
||||
start = models.DateTimeField(_('Start'), help_text=_(
|
||||
'This is crucial to get the right Hanchans that scores')) # @IgnorePep8
|
||||
season = models.ForeignKey('LadderSeason', blank=True, null=True, editable=False)
|
||||
start = models.DateTimeField(_('Start'), help_text=_('This is crucial to get the right Hanchans that scores'))
|
||||
valid = models.BooleanField(_('Is Valid'), default=False)
|
||||
|
||||
class Meta(object):
|
||||
@@ -122,22 +114,26 @@ class Hanchan(models.Model):
|
||||
self.valid = False
|
||||
return _('For a Hanchan exactly 4 players are needed.')
|
||||
|
||||
score_sum = self.player_set.aggregate(Sum('score'))['score__sum']
|
||||
score_sum = self.player_set.aggregate(Sum('input_score'))['input_score__sum']
|
||||
if score_sum == 100000:
|
||||
self.valid = True
|
||||
return '4 Spieler, 100.000 Endpunktestand, die Hanchan ist \
|
||||
korrekt!'
|
||||
elif score_sum > 100000 and self.player_set.filter(score=0):
|
||||
self.valid = True
|
||||
return 'Endpunktestand über 100.000, aber jemand ist auf 0 \
|
||||
gefallen. Die Hanchan stimmt.'
|
||||
# elif score_sum > 100000 and self.player_set.filter(score=0):
|
||||
# self.valid = True
|
||||
# return 'Endpunktestand über 100.000, aber jemand ist auf 0 \
|
||||
# gefallen. Die Hanchan stimmt.'
|
||||
elif score_sum < 100000:
|
||||
self.valid = False
|
||||
return 'Endpunktestand weniger als 100.000 Punkte.'
|
||||
elif score_sum > 100000 and not self.player_set.filter(score=0):
|
||||
elif score_sum > 100000:
|
||||
self.valid = False
|
||||
return 'Endpunktestand über 100.000, aber niemand ist auf 0 \
|
||||
gefallen.'
|
||||
return 'Endpunktestand mehr als 100.000 Punkte.'
|
||||
|
||||
#elif score_sum > 100000 and not self.player_set.filter(score=0):
|
||||
# self.valid = False
|
||||
# return 'Endpunktestand über 100.000, aber niemand ist auf 0 \
|
||||
# gefallen.'
|
||||
else:
|
||||
self.valid = False
|
||||
return 'Wir wissen nicht warum, aber das kann nicht passen...'
|
||||
@@ -177,7 +173,7 @@ class Hanchan(models.Model):
|
||||
"""
|
||||
logger.debug("Berechne die Platzierungen neu...")
|
||||
attending_players = self.player_set.select_related('hanchan', 'user')
|
||||
attending_players = attending_players.order_by('-score')
|
||||
attending_players = attending_players.order_by('-game_score')
|
||||
other_player_placement = 0
|
||||
other_player_score = 0
|
||||
placement = 1
|
||||
@@ -185,15 +181,15 @@ class Hanchan(models.Model):
|
||||
logger.info("Compute player pacements for Hanchan Nr. %d", self.pk)
|
||||
for player in attending_players:
|
||||
player_list.append(player.user.username)
|
||||
if player.score <= 0:
|
||||
if player.game_score <= 0:
|
||||
player.placement = 4
|
||||
elif player.score == other_player_score:
|
||||
elif player.game_score == other_player_score:
|
||||
player.placement = other_player_placement
|
||||
else:
|
||||
player.placement = placement
|
||||
placement += 1
|
||||
other_player_placement = player.placement
|
||||
other_player_score = player.score
|
||||
other_player_score = player.game_score
|
||||
player.save(season_id=self.season_id, mark_dirty=True)
|
||||
|
||||
def get_absolute_url(self):
|
||||
@@ -206,21 +202,20 @@ class Hanchan(models.Model):
|
||||
def save(self, **kwargs):
|
||||
logger.debug("Hanchan save() wurde getriggert!")
|
||||
|
||||
self.season = self.season or LadderSeason.objects.get_by_date(
|
||||
self.start)
|
||||
self.season = self.season or LadderSeason.objects.get_by_date(self.start)
|
||||
if self.pk:
|
||||
self.check_validity()
|
||||
self.compute_player_placements()
|
||||
self.player_names = ', '.join(self.player_set.values_list(
|
||||
'user__username', flat=True).order_by('-score'))
|
||||
'user__username', flat=True).order_by('-input_score'))
|
||||
return models.Model.save(self, **kwargs)
|
||||
|
||||
|
||||
class KyuDanRanking(models.Model):
|
||||
u"""
|
||||
Die Einstufung des Spieles im Kyu bzw. Dan System.
|
||||
Die Einstufung des Spielers im Kyu bzw. Dan System.
|
||||
Im Gegensatz zum Ladder Ranking ist das nicht Saison gebunden.
|
||||
daher läuft es getrennt.
|
||||
Deswegen läuft es getrennt.
|
||||
"""
|
||||
user = models.OneToOneField(settings.AUTH_USER_MODEL)
|
||||
dan = models.PositiveSmallIntegerField(blank=True, null=True)
|
||||
@@ -230,8 +225,10 @@ class KyuDanRanking(models.Model):
|
||||
won_hanchans = models.PositiveIntegerField(default=0)
|
||||
good_hanchans = models.PositiveIntegerField(default=0)
|
||||
hanchan_count = models.PositiveIntegerField(default=0)
|
||||
dirty = models.BooleanField(default=True, editable=False)
|
||||
wins_in_a_row = 0
|
||||
legacy_date = models.DateField(blank=True, null=True)
|
||||
legacy_dan_points = models.PositiveIntegerField(default=0)
|
||||
legacy_kyu_points = models.PositiveIntegerField(default=0)
|
||||
|
||||
class Meta(object):
|
||||
ordering = ('-dan_points', '-kyu_points',)
|
||||
@@ -239,10 +236,10 @@ class KyuDanRanking(models.Model):
|
||||
verbose_name_plural = _(u'Kyū/Dan Rankings')
|
||||
|
||||
def __unicode__(self):
|
||||
if self.dan_points:
|
||||
return u"%s - %d. Dan" % (self.user.username, self.dan)
|
||||
if self.dan_points is not None:
|
||||
return u"%s - %d. Dan" % (self.user.username, self.dan or 1)
|
||||
else:
|
||||
return u"%s - %d. Kyu" % (self.user.username, self.kyu)
|
||||
return u"%s - %d. Kyu" % (self.user.username, self.kyu or 10)
|
||||
|
||||
def append_3_in_a_row_bonuspoints(self, hanchan):
|
||||
u"""
|
||||
@@ -312,7 +309,7 @@ class KyuDanRanking(models.Model):
|
||||
self.kyu_points += bonus_points
|
||||
|
||||
def get_absolute_url(self):
|
||||
if self.dan:
|
||||
if self.dan or self.dan_points > 0:
|
||||
return reverse('player-dan-score', args=[self.user.username])
|
||||
else:
|
||||
return reverse('player-kyu-score', args=[self.user.username])
|
||||
@@ -324,80 +321,90 @@ class KyuDanRanking(models.Model):
|
||||
"""
|
||||
logger.debug("recalculating Kyu/Dan punkte for %s...", self.user)
|
||||
valid_hanchans = Player.objects.valid_hanchans(user=self.user_id)
|
||||
if self.legacy_date:
|
||||
valid_hanchans = valid_hanchans.filter(hanchan__start__gt=self.legacy_date)
|
||||
valid_hanchans = valid_hanchans.order_by('hanchan__start')
|
||||
self.kyu_points = 0
|
||||
self.dan_points = 0
|
||||
self.kyu_points = self.legacy_kyu_points or 0
|
||||
self.dan_points = self.legacy_dan_points or 0
|
||||
self.dan = None
|
||||
self.kyu = 10
|
||||
self.update_rank()
|
||||
self.hanchan_count = valid_hanchans.count()
|
||||
self.won_hanchans = valid_hanchans.filter(placement=1).count()
|
||||
self.good_hanchans = valid_hanchans.filter(placement=2).count()
|
||||
logger.info("Neuberechnung der Punkte von %s", self.user)
|
||||
|
||||
for hanchan in valid_hanchans:
|
||||
self.update_points(hanchan)
|
||||
self.append_tournament_bonuspoints(hanchan)
|
||||
for played_hanchan in valid_hanchans:
|
||||
self.update_hanchan_points(played_hanchan)
|
||||
self.append_tournament_bonuspoints(played_hanchan)
|
||||
self.update_rank()
|
||||
self.append_3_in_a_row_bonuspoints(hanchan)
|
||||
self.append_3_in_a_row_bonuspoints(played_hanchan)
|
||||
self.update_rank()
|
||||
hanchan.save(force_update=True, mark_dirty=False)
|
||||
played_hanchan.save(force_update=True, mark_dirty=False)
|
||||
self.save(force_update=True)
|
||||
|
||||
def update_points(self, player):
|
||||
def update_hanchan_points(self, played_hanchan):
|
||||
"""
|
||||
Berechne die Kyu bzw. Dan Punkte für ein Spiel neu.
|
||||
:param player: Das Player Objekt das neuberechnet werden soll.
|
||||
Berechne die Kyu bzw. Dan Punkte für eine Hanchan neu.
|
||||
Für Turniere gelten andere Regeln zur Punktevergabe:
|
||||
1. Platz 4 Punkte
|
||||
2. Platz 3 Punkte
|
||||
3. Platz 2 Punkte
|
||||
4. Platz 1 Punkt
|
||||
:param played_hanchan: Das Player Objekt das neuberechnet werden soll.
|
||||
"""
|
||||
player.bonus_points = 0
|
||||
player.comment = ""
|
||||
player.dan_points = None
|
||||
player.kyu_points = None
|
||||
|
||||
if player.hanchan.event.is_tournament:
|
||||
tourney_points = 4 - player.placement
|
||||
played_hanchan.bonus_points = 0
|
||||
played_hanchan.comment = ""
|
||||
played_hanchan.dan_points = None
|
||||
played_hanchan.kyu_points = None
|
||||
print self.user, played_hanchan.input_score, played_hanchan.game_score
|
||||
if played_hanchan.hanchan.event.is_tournament:
|
||||
tourney_points = 4 - played_hanchan.placement
|
||||
if self.dan:
|
||||
player.dan_points = tourney_points
|
||||
played_hanchan.dan_points = tourney_points
|
||||
else:
|
||||
player.kyu_points = tourney_points
|
||||
played_hanchan.kyu_points = tourney_points
|
||||
elif self.dan:
|
||||
if player.score >= 60000:
|
||||
player.dan_points = 3
|
||||
elif player.score == 0:
|
||||
player.dan_points = -3
|
||||
elif player.placement == 1:
|
||||
player.dan_points = 2
|
||||
elif player.placement == 2:
|
||||
player.dan_points = 1
|
||||
elif player.placement == 3:
|
||||
player.dan_points = -1
|
||||
elif player.placement == 4:
|
||||
player.dan_points = -2
|
||||
elif player.score >= 60000:
|
||||
player.kyu_points = 3
|
||||
elif player.score >= 30000:
|
||||
player.kyu_points = 1
|
||||
elif player.score < 10000:
|
||||
player.kyu_points = -1
|
||||
if played_hanchan.game_score >= 60000:
|
||||
played_hanchan.dan_points = 3
|
||||
elif played_hanchan.game_score == 0:
|
||||
played_hanchan.dan_points = -3
|
||||
elif played_hanchan.placement == 1:
|
||||
played_hanchan.dan_points = 2
|
||||
elif played_hanchan.placement == 2:
|
||||
played_hanchan.dan_points = 1
|
||||
elif played_hanchan.placement == 3:
|
||||
played_hanchan.dan_points = -1
|
||||
elif played_hanchan.placement == 4:
|
||||
played_hanchan.dan_points = -2
|
||||
#Kein Turnier, Spieler nicht im Dan, dann muss er Sie Kyu Punkte bekommen
|
||||
elif played_hanchan.game_score >= 60000:
|
||||
played_hanchan.kyu_points = 3
|
||||
elif played_hanchan.game_score >= 30000:
|
||||
played_hanchan.kyu_points = 1
|
||||
elif played_hanchan.game_score < 10000:
|
||||
played_hanchan.kyu_points = -1
|
||||
else:
|
||||
player.kyu_points = 0
|
||||
played_hanchan.kyu_points = 0
|
||||
|
||||
# Add the hanchans points to the players score
|
||||
if player.dan_points:
|
||||
if self.dan_points + player.dan_points < 0:
|
||||
# Add the hanchans points to the players points
|
||||
if self.dan:
|
||||
if self.dan_points + played_hanchan.dan_points < 0:
|
||||
# Only substract so much points that player has 0 Points:
|
||||
player.dan_points -= (self.dan_points + player.dan_points)
|
||||
self.dan_points += player.dan_points
|
||||
elif player.kyu_points:
|
||||
if self.kyu_points + player.kyu_points < 0:
|
||||
played_hanchan.dan_points -= (self.dan_points + played_hanchan.dan_points)
|
||||
self.dan_points += played_hanchan.dan_points
|
||||
print "Danpunkte des Spielers: {}, Danpunkte der Hanchan {}".format(self.dan_points, played_hanchan.dan_points)
|
||||
else:
|
||||
if self.kyu_points + played_hanchan.kyu_points < 0:
|
||||
# Only substract so much points that player has 0 Points:
|
||||
player.kyu_points -= (self.kyu_points + player.kyu_points)
|
||||
self.kyu_points += player.kyu_points
|
||||
played_hanchan.kyu_points -= (self.kyu_points + played_hanchan.kyu_points)
|
||||
self.kyu_points += played_hanchan.kyu_points
|
||||
|
||||
def update_rank(self):
|
||||
if self.dan and self.dan_points < 0:
|
||||
self.dan_points = 0
|
||||
self.dan = 1
|
||||
elif self.dan:
|
||||
elif self.dan or self.dan_points > 0:
|
||||
old_dan = self.dan
|
||||
for min_points, dan_rank in DAN_RANKS:
|
||||
if self.dan_points > min_points:
|
||||
@@ -429,7 +436,6 @@ class LadderRanking(models.Model):
|
||||
hanchan_count = models.PositiveIntegerField(default=0)
|
||||
good_hanchans = models.PositiveIntegerField(default=0)
|
||||
won_hanchans = models.PositiveIntegerField(default=0)
|
||||
dirty = models.BooleanField(default=True, editable=False)
|
||||
|
||||
class Meta(object):
|
||||
ordering = ('placement', 'avg_placement', '-avg_score',)
|
||||
@@ -443,15 +449,14 @@ class LadderRanking(models.Model):
|
||||
ladder_hanchans = Player.objects.ladder_hanchans(
|
||||
self.user_id, self.season_id)
|
||||
aggregate = ladder_hanchans.aggregate(
|
||||
models.Avg('placement'),
|
||||
models.Avg('score'),
|
||||
models.Count('pk')
|
||||
avg_placement = models.Avg('placement'),
|
||||
avg_score = models.Avg('game_score'),
|
||||
hanchan_count = models.Count('pk')
|
||||
)
|
||||
self.dirty = False
|
||||
self.placement = None
|
||||
self.hanchan_count = aggregate['pk__count']
|
||||
self.avg_placement = aggregate['placement__avg']
|
||||
self.avg_score = aggregate['score__avg']
|
||||
self.hanchan_count = aggregate['hanchan_count']
|
||||
self.avg_placement = aggregate['avg_placement']
|
||||
self.avg_score = aggregate['avg_score']
|
||||
self.good_hanchans = ladder_hanchans.filter(placement=2).count()
|
||||
self.won_hanchans = ladder_hanchans.filter(placement=1).count()
|
||||
self.save(force_update=True)
|
||||
@@ -464,12 +469,12 @@ class LadderSeasonManager(models.Manager):
|
||||
"""
|
||||
current_season = cache.get('current_mahjong_season')
|
||||
if not current_season:
|
||||
try:
|
||||
today = date.today()
|
||||
current_season = self.filter(start__lte=today, end__gte=today)
|
||||
current_season = current_season[0]
|
||||
except IndexError:
|
||||
current_season = None
|
||||
current_year = date.today().year
|
||||
current_season = self.get_or_create(name=current_year, defaults={
|
||||
'name': current_year,
|
||||
'start': date(year=current_year,month=1, day=1),
|
||||
'end': date(year=current_year, month=12, day=31)
|
||||
})[0]
|
||||
cache.set('current_mahjong_season', current_season, 4320)
|
||||
return current_season
|
||||
|
||||
@@ -489,11 +494,10 @@ class LadderSeason(models.Model):
|
||||
u"""
|
||||
Eine Saison für das Kasu interne Ladder-Ranking.
|
||||
"""
|
||||
name = models.CharField(max_length=100)
|
||||
name = models.PositiveSmallIntegerField()
|
||||
start = models.DateField()
|
||||
end = models.DateField()
|
||||
objects = LadderSeasonManager()
|
||||
dirty = models.BooleanField(default=True, editable=False)
|
||||
|
||||
class Meta(object):
|
||||
ordering = ('start',)
|
||||
@@ -501,7 +505,7 @@ class LadderSeason(models.Model):
|
||||
verbose_name_plural = _('Ladder Seasons')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
return str(self.name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
"""
|
||||
@@ -526,7 +530,6 @@ class LadderSeason(models.Model):
|
||||
ranking.placement = placement
|
||||
ranking.save(force_update=True)
|
||||
placement += 1
|
||||
self.dirty = False
|
||||
self.save(force_update=True)
|
||||
|
||||
|
||||
@@ -544,7 +547,7 @@ class PlayerManager(models.Manager):
|
||||
return queryset
|
||||
|
||||
def ladder_hanchans(self, user=None, season=None, num_hanchans=None,
|
||||
max_age=None): # @IgnorePep8
|
||||
max_age=None):
|
||||
queryset = self.valid_hanchans(user).order_by('-hanchan__start')
|
||||
queryset = queryset.select_related()
|
||||
season = season or LadderSeason.objects.current()
|
||||
@@ -589,18 +592,19 @@ class PlayerManager(models.Manager):
|
||||
class Player(models.Model):
|
||||
hanchan = models.ForeignKey(Hanchan)
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL)
|
||||
score = models.PositiveIntegerField(default=0)
|
||||
input_score = models.IntegerField(default=0)
|
||||
game_score = models.PositiveIntegerField(default=0)
|
||||
placement = models.PositiveSmallIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None
|
||||
)
|
||||
kyu_points = models.PositiveSmallIntegerField(
|
||||
kyu_points = models.SmallIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None
|
||||
)
|
||||
dan_points = models.PositiveSmallIntegerField(
|
||||
dan_points = models.SmallIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None
|
||||
@@ -615,13 +619,14 @@ class Player(models.Model):
|
||||
|
||||
class Meta(object):
|
||||
unique_together = ('hanchan', 'user')
|
||||
ordering = ['-score']
|
||||
ordering = ['-input_score']
|
||||
|
||||
def __str__(self):
|
||||
return "{0}'s Punkte vom {1: %d.%m.%Y um %H:%M}".format(
|
||||
self.user.username, self.hanchan.start)
|
||||
|
||||
def save(self, mark_dirty=True, season_id=None, *args, **kwargs):
|
||||
self.game_score = self.input_score if self.input_score > 0 else 0
|
||||
season_id = season_id or self.hanchan.season_id
|
||||
super(Player, self).save(*args, **kwargs)
|
||||
|
||||
@@ -634,7 +639,7 @@ class Player(models.Model):
|
||||
if season_id:
|
||||
logger.debug(
|
||||
"Marking %s's season no. %i ranking for recalculation.",
|
||||
self.user, season_id) # @IgnorePep8
|
||||
self.user, season_id)
|
||||
set_dirty(season=season_id, user=self.user_id)
|
||||
logger.debug("Marking season no %i for recalculation.", season_id)
|
||||
set_dirty(season=season_id)
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
{% for hanchan in hanchan_list %}
|
||||
<div class="grid_12" id="{{ hanchan.pk }}"><h3>{{hanchan.start|time:'H:i'}}: {{ hanchan.player_names }}</h3></div>
|
||||
{% for player in hanchan.player_set.all %}
|
||||
<a class="grid_1" href="{% url 'player-ladder-score' player.user %}"><img src="{% if player.user.get_profile.thumbnail %}{{player.user.get_profile.thumbnail.url}}{% else %}{{STATIC_URL}}img/unknown_thumbnail.png{% endif %}" class="avatar" alt="{{ player.user }}" title="{{ player.user }}"/></a>
|
||||
<a class="grid_1" href="{% url 'player-ladder-score' player.user %}"><img src="{% if player.user.avatar %}{{player.user.thumbnail.url}}{% else %}{{STATIC_URL}}img/unknown_thumbnail.png{% endif %}" class="avatar" alt="{{ player.user }}" title="{{ player.user }}"/></a>
|
||||
<div class="grid_2">
|
||||
<a class="player" href="{% url 'player-ladder-score' player.user %}" title="{{ player.comment }}">{{ player.user }}</a>
|
||||
<p><strong>{{ player.placement|ordinal }} {% trans 'Place' %}</strong><br />
|
||||
<strong>{% trans 'Score' %}:</strong> {{ player.score|intcomma }}<br />
|
||||
<strong>{% trans 'Score' %}:</strong> {{ player.game_score|intcomma }}<br />
|
||||
{% if player.dan_points != None %}
|
||||
<strong>{% trans 'Dan Points' %}:</strong> {{ player.dan_points }}
|
||||
{% else %}
|
||||
@@ -15,7 +15,7 @@
|
||||
<th rowspan="2">{% trans "Nickname" %}</th>
|
||||
<th rowspan="2">{% trans "Name" %}</th>
|
||||
<th colspan="2">{% trans 'Average' %}</th>
|
||||
<th colspan="3">Hanchans</th>
|
||||
<th colspan="3">{% trans 'Hanchans' %}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans 'Placement' %}</th>
|
||||
@@ -26,54 +26,33 @@
|
||||
</tr>
|
||||
</thead>
|
||||
{% for player in eventranking_list %}
|
||||
{% with player.user.get_profile as profile %}
|
||||
<tr>
|
||||
<td class="center">{{player.placement}}.</td>
|
||||
<td class="avatar"><a href="{{ player.user.get_absolute_url }}">
|
||||
{% if profile.thumbnail %}
|
||||
<img src="{{profile.thumbnail.url}}" alt="" />
|
||||
{% else %}
|
||||
<img src="{{STATIC_URL}}img/unknown_thumbnail.png" alt=""/>
|
||||
{% endif %}
|
||||
</a></td>
|
||||
<td><a href="{{ player.user.get_absolute_url }}">{{player.user}}</a></td>
|
||||
<td>{% if user.is_authenticated %}{{profile.last_name}} {{profile.first_name}}{% else %} ---{% endif %}</td>
|
||||
<td class="center">{{player.avg_placement|floatformat:2 }}</td>
|
||||
<td class="right">{{player.avg_score|floatformat:0 }}</td>
|
||||
<td class="center">{{player.placement}}.</td>
|
||||
<td class="avatar"><a href="{{ player.user.get_absolute_url }}">
|
||||
{% if player.user.avatar %}
|
||||
<img src="{{player.user.thumbnail.url}}" alt="" />
|
||||
{% else %}
|
||||
<img src="{{STATIC_URL}}img/unknown_thumbnail.png" alt=""/>
|
||||
{% endif %}
|
||||
</a></td>
|
||||
<td><a href="{{ player.user.get_absolute_url }}">{{player.user}}</a></td>
|
||||
<td>{% if user.is_authenticated %}{{player.user.last_name}} {{player.user.first_name}}{% else %}---{% endif %}</td>
|
||||
<td class="center">{{player.avg_placement|floatformat:2 }}</td>
|
||||
<td class="right">{{player.avg_score|floatformat:0 }}</td>
|
||||
<td class="right">{{player.hanchan_count}}</td>
|
||||
<td class="right">{{player.good_hanchans}}</td>
|
||||
<td class="right">{{player.won_hanchans}}</td>
|
||||
<td class="right">{{player.won_hanchans}}</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% empty %}
|
||||
<tr><td colspan="8">Leider hat es noch niemand in das Ranking geschafft.
|
||||
Ein Spieler wird erst ins Ranking genommen wenn er 5 Hanchans absolviert hat.</td></tr>
|
||||
<tr><td colspan="9">Leider hat es noch niemand in das Ranking geschafft.</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% if is_archive %}
|
||||
<h2>{% trans 'Ladder Archive' %}</h2>
|
||||
<ul class="list">
|
||||
{% for season in season_archive %}
|
||||
<li class="season"><a href="{% url 'mahjong-ladder-archive' season.id %}">{{season.name}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<h2>{% trans 'Latest Events' %}</h2>
|
||||
<ul class="list">
|
||||
{% for event in latest_event_list %}
|
||||
<li class="event"><a href="{% url 'event-hanchan-list' event.pk %}">{{event.name}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h2>{% trans 'Latest Hanchans' %}</h2>
|
||||
<ul class="comment_list">
|
||||
{% for hanchan in latest_hanchan_list %}
|
||||
<li class="hanchan"><a href="{% url 'event-hanchan-list' hanchan.event.pk %}">{{hanchan.event.name}}</a> {{hanchan.start|time:'H:i'}}: {{hanchan.player_names}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% block buttonbar %}
|
||||
{% if perms.mahjong_ranking.add_hanchan %}
|
||||
<a class="button" href="{{event.get_edit_url}}"><span class="fa fa-pencil"></span> {% trans 'Edit Event' %}</a>
|
||||
<a class="button" href="{% url 'add-hanchan-form' event.id %}"><span class="fa fa-plus-circle"></span> {% trans 'Add Hanchan' %}</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -9,6 +9,9 @@
|
||||
<fieldset>
|
||||
<legend>{% trans "Delete Hanchan" %}</legend>
|
||||
{% include 'form.html' %}
|
||||
<div class="grid_2 fa fa-exclamation-triangle fa-5x" ></div>
|
||||
<p class="grid_6">Bist du sicher dass du diese Hanchan und alle Ergebnisse und Wertungen welche sich hierauf beziehen löschen möchtest?</p>
|
||||
<br class="clear">
|
||||
<p class="buttonbar">
|
||||
<button type="button" onclick="window.history.back()"><span class="fa fa-close"></span> {% trans 'Cancel' %}</button>
|
||||
<button type="submit"><span class="fa fa-trash"></span> {% trans 'Delete' %}</button>
|
||||
|
||||
@@ -1,59 +1,52 @@
|
||||
{% extends "events/event_detail.html" %}
|
||||
{% load i18n comments fieldset_extras %}
|
||||
|
||||
{% block title %}
|
||||
{% if hanchan.id %}{% trans "Edit Hanchan" %}{% else %}{% trans "Add Hanchan" %}{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{% if hanchan.id %}{% trans "Edit Hanchan" %}{% else %}{% trans "Add Hanchan" %}{% endif %}{% endblock %}
|
||||
{% block maincontent %}
|
||||
{% get_fieldset "event, start" from form as event_formset %}
|
||||
{% if perms.mahjong_ranking.delete_hanchan %}
|
||||
{% get_fieldset "comment, confirmed" from form as hanchan_formset %}
|
||||
{% else %}
|
||||
{% get_fieldset "comment" from form as hanchan_formset %}
|
||||
{% endif %}
|
||||
{% for hidden in form.hidden_fields %}{% if hidden.errors %}{{ hidden.errors }}{% endif %}{% endfor %}
|
||||
{% get_fieldset "event, start" from form as event_formset %}
|
||||
{% if perms.mahjong_ranking.delete_hanchan %}
|
||||
{% get_fieldset "comment, confirmed" from form as hanchan_formset %}
|
||||
{% else %}
|
||||
{% get_fieldset "comment" from form as hanchan_formset %}
|
||||
{% endif %}
|
||||
{% for hidden in form.hidden_fields %}{% if hidden.errors %}{{ hidden.errors }}{% endif %}{% endfor %}
|
||||
|
||||
<form class="grid_12" method="post">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<legend>{% if hanchan.id %}{% trans "Edit Hanchan" %}{% else %} {% trans "Add Hanchan" %}{% endif %}</legend>
|
||||
{% with event_formset as form %}{% include "form.html" %}{% endwith %}
|
||||
<div>
|
||||
<label class="field_name required">{% trans 'Players' %}</label>
|
||||
{{ formset.management_form }}
|
||||
<table>
|
||||
<tr>
|
||||
<th>{% trans 'User' %}</th>
|
||||
<th>{% trans 'Score' %}</th>
|
||||
<th>{% trans 'Bonus' %}</th>
|
||||
<th width="75%">{% trans 'Comment' %}</th>
|
||||
</tr>
|
||||
{% for form in formset %}
|
||||
<tr>
|
||||
<td class="{{form.user.css_classes}}">{{form.id}} {{form.user}} {% for error in form.user.errors %}<br />{{error}}{% endfor %}</td>
|
||||
<td class="{{form.score.css_classes}}">{{form.score}} {% for error in form.score.errors %}<br />{{error}}{% endfor %}</td>
|
||||
<td class="{{form.bonus_points.css_classes}}">{{form.bonus_points}} {% for error in form.bonus_points.errors %}<br />{{error}}{% endfor %}</td>
|
||||
<td class="{{form.comment.css_classes}}" width="*">{{form.comment}} {% for error in form.comment.errors %}<br />{{error}}{% endfor %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% for error in formset.errors %}<p class="error">{{error}}</p>{% endfor %}
|
||||
|
||||
{% if hanchan.pk and not hanchan.valid %}<p class="error">{{hanchan.check_validity}}</p>{% endif %}
|
||||
|
||||
{% with hanchan_formset as form %}{% include "form.html" %}{% endwith %}
|
||||
{% for error in form.non_field_errors %}<p class="error">{{error}}</p>{% endfor %}
|
||||
|
||||
|
||||
<p class="buttonbar">
|
||||
<a href="{% url 'event-hanchan-list' event.pk %}" class="button"><span class="fa fa-undo"></span> {% trans 'back' %}</a>
|
||||
<button type="submit"><span class="fa fa-hdd-o"></span> {% trans 'save' %}</button>
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
<form class="grid_12" method="post"><fieldset>
|
||||
{% csrf_token %}
|
||||
<legend>{% if hanchan.id %}{% trans "Edit Hanchan" %}{% else %} {% trans "Add Hanchan" %}{% endif %}</legend>
|
||||
{% with event_formset as form %}{% include "form.html" %}{% endwith %}
|
||||
<div>
|
||||
<label class="field_name required">{% trans 'Players' %}</label>
|
||||
{{ formset.management_form }}
|
||||
<table>
|
||||
<tr>
|
||||
<th>{% trans 'User' %}</th>
|
||||
<th>{% trans 'Score' %}</th>
|
||||
<th>{% trans 'Bonus' %}</th>
|
||||
<th width="75%">{% trans 'Comment' %}</th>
|
||||
</tr>
|
||||
{% for form in formset %}
|
||||
<tr>
|
||||
<td class="{{form.user.css_classes}}">{{form.id}} {{form.user}} {% for error in form.user.errors %}<br />{{error}}{% endfor %}</td>
|
||||
<td class="{{form.input_score.css_classes}}">{{form.input_score}} {% for error in form.input_score.errors %}<br />{{error}}{% endfor %}</td>
|
||||
<td class="{{form.bonus_points.css_classes}}">{{form.bonus_points}} {% for error in form.bonus_points.errors %}<br />{{error}}{% endfor %}</td>
|
||||
<td class="{{form.comment.css_classes}}" width="*">{{form.comment}} {% for error in form.comment.errors %}<br />{{error}}{% endfor %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{{ formset.non_form_errors }}
|
||||
{% if hanchan.pk and not hanchan.valid %}<p class="error">{{hanchan.check_validity}}</p>{% endif %}
|
||||
{% with hanchan_formset as form %}
|
||||
{% for error in form.non_field_errors %}<p class="error">{{error}}</p>{% endfor %}
|
||||
{% include "form.html" %}
|
||||
{% endwith %}
|
||||
|
||||
<p class="buttonbar">
|
||||
<a href="{% url 'event-hanchan-list' event.pk %}" class="button"><span class="fa fa-undo"></span> {% trans 'back' %}</a>
|
||||
<button type="submit"><span class="fa fa-hdd-o"></span> {% trans 'save' %}</button>
|
||||
</p>
|
||||
</fieldset></form>
|
||||
{% endblock %}
|
||||
|
||||
{% block buttonbar %}{% endblock %}
|
||||
@@ -38,22 +38,22 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ranking in kyudanranking_list %}{% with ranking.user.get_profile as profile %}
|
||||
{% for ranking in kyudanranking_list %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if profile.thumbnail %}
|
||||
<a href="{{ ranking.get_absolute_url }}"><img src="{{profile.thumbnail.url}}" alt="" /></a>
|
||||
{% if ranking.user.avatar %}
|
||||
<a href="{{ ranking.get_absolute_url }}"><img src="{{ranking.user.thumbnail.url}}" alt="" /></a>
|
||||
{% else %}
|
||||
<a href="{{ ranking.get_absolute_url }}"><img src="{{STATIC_URL}}img/unknown_thumbnail.png" alt=""/></a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td><a href="{{ ranking.get_absolute_url }}">{{ ranking.user }}</a></td>
|
||||
<td>{% if user.is_authenticated %}{{profile.last_name}} {{profile.first_name}}{% else %} ---{% endif %}</td>
|
||||
<td>{% if user.is_authenticated %}{{ranking.user.last_name}} {{ranking.user.first_name}}{% else %}---{% endif %}</td>
|
||||
<td>{% if ranking.dan %} {{ranking.dan}}. Dan {% else %} {{ranking.kyu}} Kyu {% endif %}</td>
|
||||
<td class="right">{% if ranking.dan %} {{ranking.dan_points}} {% else %} {{ranking.kyu_points}} {% endif %}</td>
|
||||
<td class="right">{{ranking.hanchan_count}}</td>
|
||||
</tr>
|
||||
{% endwith %}{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</main>
|
||||
|
||||
@@ -33,19 +33,17 @@
|
||||
</tr>
|
||||
</thead>
|
||||
{% for player in ladderranking_list %}
|
||||
{% with player.user.get_profile as profile %}
|
||||
<tr>
|
||||
<td class="center">{{player.placement}}.</td>
|
||||
<td><a href="{{ player.get_absolute_url }}?season={{season.id}}"><img src="{% if profile.thumbnail %}{{profile.thumbnail.url}}{% else %}{{STATIC_URL}}img/unknown_thumbnail.png{% endif %}" class="avatar" alt=""/></a></td>
|
||||
<td><a href="{{ player.get_absolute_url }}?season={{season.id}}"><img src="{% if player.user.avatar %}{{player.user.thumbnail.url}}{% else %}{{STATIC_URL}}img/unknown_thumbnail.png{% endif %}" class="avatar" alt=""/></a></td>
|
||||
<td><a href="{{ player.get_absolute_url }}?season={{season.id}}">{{player.user}}</a></td>
|
||||
<td>{% if user.is_authenticated %}{{profile.last_name}} {{profile.first_name}}{% else %} ---{% endif %}</td>
|
||||
<td>{% if user.is_authenticated %}{{player.user.last_name}} {{player.user.first_name}}{% else %}---{% endif %}</td>
|
||||
<td class="center">{{player.avg_placement|floatformat:2 }}</td>
|
||||
<td class="right">{{player.avg_score|floatformat:0 }}</td>
|
||||
<td class="right">{{player.hanchan_count}}</td>
|
||||
<td class="right">{{player.good_hanchans}}</td>
|
||||
<td class="right">{{player.won_hanchans}}</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="9">Leider hat es noch niemand in das Ranking geschafft.
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<td class="center">{{result.placement}}.</td>
|
||||
{% for player in result.hanchan.player_set.all %}
|
||||
<td class="center"><a href="{% url 'player-dan-score' player.user.username %}">{{player.user}}</a><br/>
|
||||
{{player.score }}
|
||||
{{player.game_score }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
<td class="center">{{result.dan_points}}</td>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<td><a href="{{ result.hanchan.get_absolute_url }}">{{ result.hanchan.event.name }}</a></td>
|
||||
<td>{{ result.hanchan.start|time:'H:i' }}</td>
|
||||
{% for player in result.hanchan.player_set.all %}
|
||||
<td class="center"><a href="{% url 'player-invalid-score' player.user.username %}">{{player.user}}</a><br/> {{player.score }}</td>
|
||||
<td class="center"><a href="{% url 'player-invalid-score' player.user.username %}">{{player.user}}</a><br/> {{player.input_score }}</td>
|
||||
{% endfor %}
|
||||
<td class="center">{{result.placement}}</td>
|
||||
<td class="center">{{result.kyu_points}}</td>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
{% block title %} {% trans 'Kyu Score for' %} {{membership.username}} {% endblock %}
|
||||
|
||||
{% block teaser %}<h2>{% trans 'Kyu Score for' %}{{membership.username}}</h2>{% endblock %}
|
||||
{% block teaser %}<h2>{% trans 'Kyu Score for' %} {{membership.username}}</h2>{% endblock %}
|
||||
|
||||
{% block score_list %}
|
||||
<div class="grid_12">
|
||||
@@ -34,7 +34,7 @@
|
||||
<td>{{ result.hanchan.start|time:'H:i' }}</td>
|
||||
<td class="center">{{result.placement}}.</td>
|
||||
{% for player in result.hanchan.player_set.select_related %}
|
||||
<td class="center"><a href="{% url 'player-kyu-score' player.user.username %}">{{player.user}}</a><br/> {{player.score }}</td>
|
||||
<td class="center"><a href="{% url 'player-kyu-score' player.user.username %}">{{player.user}}</a><br/> {{player.game_score }}</td>
|
||||
{% endfor %}
|
||||
<td class="center">{{result.kyu_points}}</td>
|
||||
<td>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<td>{{ result.hanchan.start|time:'H:i' }}</td>
|
||||
<td class="center">{{result.placement}}.</td>
|
||||
{% for player in result.hanchan.player_set.select_related %}
|
||||
<td class="center"><a href="{% url 'player-ladder-score' player.user.username %}?season={{season.id}}">{{player.user}}</a><br/> {{player.score}}</td>
|
||||
<td class="center"><a href="{% url 'player-ladder-score' player.user.username %}?season={{season.id}}">{{player.user}}</a><br/> {{player.game_score}}</td>
|
||||
{% endfor %}
|
||||
<td>
|
||||
{% if perms.mahjong_ranking.delete_hanchan %}
|
||||
|
||||
@@ -13,30 +13,19 @@ import views
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url('^$', RedirectView.as_view(pattern_name='mahjong-ladder', permanent=True)),
|
||||
url(r'players/$', views.KyuDanRankingList.as_view(),
|
||||
name="kyudanranking-list"),
|
||||
url(r'players/(?P<order_by>[\+\-\w]+)/$', views.KyuDanRankingList.as_view(),
|
||||
name="kyudanranking-list"),
|
||||
url(r'ranking/$', views.LadderRankingList.as_view(), name="mahjong-ladder"),
|
||||
url(r'ranking/(?P<season>[\d]+)/$', views.LadderRankingList.as_view(),
|
||||
name="mahjong-ladder"),
|
||||
url(r'ranking/event/(?P<event>[\d]+)/$', views.EventHanchanList.as_view(),
|
||||
name="event-hanchan-list"),
|
||||
url(r'ranking/event/(?P<event>[\d]+)/ranking/$',
|
||||
views.EventRankingList.as_view(), name="event-ranking"),
|
||||
url(r'ranking/event/(?P<event>[\d]+)/add-hanchan/$',
|
||||
views.HanchanForm.as_view(), name="add-hanchan-form"),
|
||||
url(r'hanchan/(?P<hanchan>[\d]+)/edit/$', views.HanchanForm.as_view(),
|
||||
name="edit-hanchan"),
|
||||
url(r'hanchan/(?P<hanchan>[\d]+)/delete/$', views.DeleteHanchan.as_view(),
|
||||
name="delete-hanchan"),
|
||||
url(r'player/(?P<username>[\-\.\d\w]+)/dan/$',
|
||||
views.PlayerDanScore.as_view(), name="player-dan-score"),
|
||||
url(r'player/(?P<username>[\-\.\d\w]+)/invalid/$',
|
||||
views.PlayerInvalidScore.as_view(), name="player-invalid-score"),
|
||||
url(r'player/(?P<username>[\-\.\d\w]+)/kyu/$',
|
||||
views.PlayerKyuScore.as_view(), name="player-kyu-score"),
|
||||
url(r'player/(?P<username>[\-\.\d\w]+)/ladder/$',
|
||||
views.PlayerLadderScore.as_view(), name="player-ladder-score"),
|
||||
# url('^$', RedirectView.as_view(pattern_name='mahjong-ladder', permanent=True)),
|
||||
url('^$',views.LadderRankingList.as_view()),
|
||||
url(r'^event/(?P<event>[\d]+)/mahjong/$', views.EventHanchanList.as_view(), name="event-hanchan-list"),
|
||||
url(r'^event/(?P<event>[\d]+)/add-hanchan/$', views.HanchanForm.as_view(), name="add-hanchan-form"),
|
||||
url(r'^event/(?P<event>[\d]+)/mahjong-ranking/$', views.EventRankingList.as_view(), name="event-ranking"),
|
||||
url(r'^hanchan/(?P<hanchan>[\d]+)/edit/$', views.HanchanForm.as_view(), name="edit-hanchan"),
|
||||
url(r'^hanchan/(?P<hanchan>[\d]+)/delete/$', views.DeleteHanchan.as_view(), name="delete-hanchan"),
|
||||
url(r'^mahjong-ladder/$', views.LadderRankingList.as_view(), name="mahjong-ladder"),
|
||||
url(r'^mahjong-ladder/(?P<season>[\d]+)/$', views.LadderRankingList.as_view(), name="mahjong-ladder"),
|
||||
url(r'^player/(?P<username>[\-\.\d\w]+)/dan/$', views.PlayerDanScore.as_view(), name="player-dan-score"),
|
||||
url(r'^player/(?P<username>[\-\.\d\w]+)/invalid/$', views.PlayerInvalidScore.as_view(), name="player-invalid-score"),
|
||||
url(r'^player/(?P<username>[\-\.\d\w]+)/kyu/$', views.PlayerKyuScore.as_view(), name="player-kyu-score"),
|
||||
url(r'^player/(?P<username>[\-\.\d\w]+)/ladder/$', views.PlayerLadderScore.as_view(), name="player-ladder-score"),
|
||||
url(r'^mahjong/$', views.KyuDanRankingList.as_view(), name="kyudanranking-list"),
|
||||
url(r'^mahjong/(?P<order_by>[\+\-\w]+)/$', views.KyuDanRankingList.as_view(), name="kyudanranking-list"),
|
||||
)
|
||||
|
||||
@@ -136,6 +136,7 @@ class EventHanchanList(EventDetailMixin, generic.ListView):
|
||||
Auflistung aller Hanchan die während der Veranstaltung gespielt wurden.
|
||||
"""
|
||||
model = models.Hanchan
|
||||
template_name = 'mahjong_ranking/eventhanchan_list.html'
|
||||
|
||||
def get_queryset(self):
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user