Das Layout der einzelnen Seiten ist jetzt einheitlich: - jumbotron - Naviation der Unterseiten (wenn Vorhanden) - Hauptinhalt - Pager (bei mehrseiteigen Ergebnissen) - Kommentare (wenn Kommentare möglich) - Buttonleiste zum bearbeiten (wen erlaubt) * Viele kleine HTML5 Fehler wurden bereinigt * CSS Dateien wurden angepasst * Nicht mehr benötigte Dateien in STATIC gelöscht * externe Pakete aus utlis/ entfernt, als Vobreitung für virtenv Nutzung.
355 lines
13 KiB
Python
355 lines
13 KiB
Python
# -*- encoding: utf-8 -*-
|
|
|
|
import urllib
|
|
|
|
from django.contrib import auth, messages
|
|
from django.core.urlresolvers import reverse
|
|
import django.forms
|
|
import django.http
|
|
from django.utils.translation import gettext as _
|
|
from django.views import generic
|
|
import xlwt
|
|
|
|
from events.models import Event
|
|
from . import forms, models
|
|
from membership.models import Membership
|
|
from utils.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
|
|
|
|
|
kyu_dan_order = {
|
|
'+full_name': ('user__last_name', 'user__first_name'),
|
|
'-full_name': ('-user__last_name', '-user__first_name'),
|
|
'+hanchan_count': ('hanchan_count',),
|
|
'-hanchan_count': ('-hanchan_count',),
|
|
'+rank': ('-kyu', 'dan'),
|
|
'-rank': ('-dan', 'kyu'),
|
|
'+score': ('dan_points', 'kyu_points'),
|
|
'-score': ('-dan_points', '-kyu_points'),
|
|
'+username': ('user__username',),
|
|
'-username': ('-user__username',)
|
|
}
|
|
|
|
|
|
class DeleteHanchan(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.
|
|
"""
|
|
form_class = forms.HanchanForm
|
|
model = models.Hanchan
|
|
permission_required = 'mahjong_ranking.delete_hanchan'
|
|
pk_url_kwarg = 'hanchan'
|
|
|
|
def get_success_url(self):
|
|
return reverse('event-hanchan-list',
|
|
kwargs={'event': self.object.event.pk})
|
|
|
|
|
|
class HanchanForm(PermissionRequiredMixin, generic.UpdateView):
|
|
"""
|
|
Ein Formular um eine neue Hanchan anzulegen, bzw. eine bestehende zu
|
|
bearbeitsen
|
|
"""
|
|
form_class = forms.HanchanForm
|
|
model = models.Hanchan
|
|
permission_required = 'mahjong_ranking.add_hanchan'
|
|
|
|
def form_valid(self, form, formset):
|
|
if not self.object.pk:
|
|
self.object = form.save()
|
|
formset.save()
|
|
self.object.save()
|
|
else:
|
|
formset.save()
|
|
self.object = form.save()
|
|
return django.http.HttpResponseRedirect(self.get_success_url())
|
|
|
|
def form_invalid(self, form, formset):
|
|
return self.render_to_response(self.get_context_data(
|
|
form=form,
|
|
formset=formset,
|
|
object=self.object,
|
|
))
|
|
|
|
def get_form_class(self):
|
|
"""
|
|
Returns the form class to use in this view
|
|
"""
|
|
if self.request.user.has_perm('mahjong_ranking.delete_hanchan'):
|
|
return forms.HanchanAdminForm
|
|
else:
|
|
return forms.HanchanForm
|
|
|
|
def get_formset(self):
|
|
return forms.PlayerFormSet(
|
|
data=self.request.POST or None,
|
|
instance=self.object
|
|
)
|
|
|
|
def get_object(self, queryset=None):
|
|
if self.kwargs.get('hanchan'):
|
|
hanchan = models.Hanchan.objects.get(id=self.kwargs['hanchan'])
|
|
self.event = hanchan.event
|
|
elif self.kwargs.get('event'):
|
|
self.event = models.Event.objects.get(id=self.kwargs['event'])
|
|
hanchan = models.Hanchan(
|
|
event=self.event,
|
|
start=self.event.start
|
|
)
|
|
else:
|
|
hanchan = self.model()
|
|
if hanchan.id and not hanchan.valid:
|
|
messages.warning(self.request, hanchan.check_validity())
|
|
return hanchan
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = generic.UpdateView.get_context_data(self, **kwargs)
|
|
context['event'] = self.event
|
|
return context
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
"""
|
|
|
|
:param request:
|
|
"""
|
|
self.object = self.get_object()
|
|
form = self.get_form(self.get_form_class())
|
|
formset = self.get_formset()
|
|
return self.render_to_response(
|
|
self.get_context_data(form=form, formset=formset)
|
|
)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
self.object = self.get_object()
|
|
form_class = self.get_form_class()
|
|
form = self.get_form(form_class)
|
|
formset = self.get_formset()
|
|
if form.is_valid() and formset.is_valid():
|
|
return self.form_valid(form, formset)
|
|
else:
|
|
return self.form_invalid(form, formset)
|
|
|
|
|
|
class EventHanchanList(generic.ListView):
|
|
"""
|
|
Auflistung aller Hanchan die während der Veranstaltung gespielt wurden.
|
|
"""
|
|
model = models.Hanchan
|
|
|
|
def get_queryset(self):
|
|
try:
|
|
self.event = models.Event.objects.get(pk=self.kwargs['event'])
|
|
queryset = models.Hanchan.objects.filter(event=self.event)
|
|
queryset = queryset.prefetch_related('player_set__user')
|
|
queryset = queryset.order_by('start')
|
|
return queryset
|
|
except models.Event.DoesNotExist:
|
|
raise django.http.Http404(_('Event does not exist'))
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = generic.ListView.get_context_data(self, **kwargs)
|
|
context['event'] = self.event
|
|
return context
|
|
|
|
|
|
class EventRankingList(generic.ListView):
|
|
"""
|
|
Anzeige des Eventrankings, daß erstellt wurde falls der Termin als internes
|
|
Turnier markiert wurde.
|
|
"""
|
|
model = models.EventRanking
|
|
|
|
def get_queryset(self):
|
|
try:
|
|
self.event = models.Event.objects.get(pk=self.kwargs['event'])
|
|
queryset = models.EventRanking.objects.filter(event=self.event)
|
|
queryset = queryset.prefetch_related()
|
|
return queryset
|
|
except models.Event.DoesNotExist:
|
|
raise django.http.Http404(_('Event does not exist'))
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = generic.ListView.get_context_data(self, **kwargs)
|
|
context['event'] = self.event
|
|
return context
|
|
|
|
|
|
class KyuDanRankingList(generic.ListView):
|
|
"""
|
|
Anzeige aller Spiele mit ihrem Kyu bzw Dan Grad.
|
|
"""
|
|
default_order = '-score'
|
|
order_by = ''
|
|
paginate_by = 25
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
self.order_by = kyu_dan_order[kwargs.get('order_by', self.default_order)] # @IgnorePep8
|
|
return generic.ListView.dispatch(self, request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
queryset = models.KyuDanRanking.objects.all()
|
|
queryset = queryset.select_related('user__membership')
|
|
queryset = queryset.order_by(*self.order_by)
|
|
return queryset
|
|
|
|
|
|
class LadderRankingList(generic.ListView):
|
|
model = models.LadderRanking
|
|
paginate_by = 25
|
|
season = None
|
|
is_archive = False
|
|
|
|
def get_queryset(self):
|
|
try:
|
|
if self.kwargs.get('season'):
|
|
self.season = models.LadderSeason.objects.get(pk=self.kwargs['season'])
|
|
self.is_archive = True
|
|
elif self.kwargs.get('is_archive'):
|
|
self.season = models.LadderSeason.objects.order_by('-pk')[1]
|
|
self.is_archive = True
|
|
else:
|
|
self.season = models.LadderSeason.objects.current()
|
|
except models.LadderSeason.DoesNotExist:
|
|
raise django.http.Http404(_('Season does not exist'))
|
|
queryset = models.LadderRanking.objects.filter(season=self.season, placement__isnull=False).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_archive'] = models.LadderSeason.objects.all()
|
|
context['latest_hanchan_list'] = models.Hanchan.objects.filter(valid=True)[:5]
|
|
context['latest_event_list'] = Event.objects.archive()[:5]
|
|
return context
|
|
|
|
|
|
class LadderRankingExcel(generic.View):
|
|
center = xlwt.easyxf('align: horiz centre')
|
|
# Format für Datumswerte
|
|
date = xlwt.easyxf('align: horiz right', num_format_str='d.MM.YYYY')
|
|
# Format für Überschriften
|
|
header = xlwt.easyxf('font: bold on; align: wrap on, vert centre, \
|
|
horiz center; pattern: back_color grey25;')
|
|
filename = u"ladderranking.xls"
|
|
|
|
def get(self, request, **kwargs):
|
|
self.queryset = self.team.members.all()
|
|
response = django.http.HttpResponse(mimetype=u'application/msexcel')
|
|
|
|
filename = urllib.quote(self.filename.encode('utf-8'))
|
|
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % filename
|
|
|
|
field_names = [u"Login", u"Name", u"E-Mail", u"Telefon", u"Handy", u"Geburtstag",
|
|
u"T-Shirt", u"Teams", u"Gr.", u"Kg", u"Notfall Adresse",
|
|
u"Notfall Nummer", u"Notizen", ]
|
|
|
|
|
|
# Erstelle ein Workbook (Das ist eine Excel Datei)
|
|
workbook = xlwt.Workbook(encoding='utf-8')
|
|
|
|
# Das Sheet ist eine Tabelle in der Excel Datei.
|
|
# Dort wird die erste Spalte fixiert und mit den Zeilenüberschriften befüllt.
|
|
sheet = workbook.add_sheet('Mitglieder', cell_overwrite_ok=False)
|
|
sheet.set_panes_frozen(True)
|
|
sheet.set_horz_split_pos(1) # in general, freeze after last heading row
|
|
sheet.set_remove_splits(True) # if user does unfreeze, don't leave a split there
|
|
for column in range(0, len(field_names)):
|
|
sheet.write(0, column, field_names[column], style=header)
|
|
|
|
# Dann fangen wir an ab der 2. Zeile die einzelnen Datensätze einzuspielen.
|
|
current_row = 2
|
|
for user in self.queryset:
|
|
self.set_col(sheet, current_row, 0, user.username)
|
|
self.set_col(sheet, current_row, 1, user.get_full_name())
|
|
self.set_col(sheet, current_row, 2, user.email)
|
|
try:
|
|
profile = user.get_profile()
|
|
self.set_col(sheet, current_row, 3, profile.telephone or None)
|
|
self.set_col(sheet, current_row, 4, profile.mobilephone or None)
|
|
self.set_col(sheet, current_row, 5, profile.birthday or None, style=self.date)
|
|
self.set_col(sheet, current_row, 6, profile.shirt_size or None, style=self.center)
|
|
self.set_col(sheet, current_row, 7, self.get_other_teams(user))
|
|
self.set_col(sheet, current_row, 8, profile.height or None)
|
|
self.set_col(sheet, current_row, 9, profile.weight or None)
|
|
self.set_col(sheet, current_row, 10, profile.emergency_contact or None)
|
|
self.set_col(sheet, current_row, 11, profile.emergency_phone or None)
|
|
except Membership.DoesNotExist:
|
|
pass
|
|
current_row += 1
|
|
|
|
for column in range(0, 13):
|
|
sheet.col(column).width = (self.max_colwidth[column] + 1) * 256
|
|
|
|
workbook.save(response)
|
|
return response
|
|
|
|
|
|
class PlayerScore(LoginRequiredMixin, generic.ListView):
|
|
paginate_by = 25
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
try:
|
|
self.user = auth.get_user_model().objects.get(username=self.kwargs.get('username'))
|
|
self.membership = Membership.objects.get_or_create(user=self.user)[0]
|
|
except auth.get_user_model().DoesNotExist:
|
|
raise django.http.Http404(_("No user found matching the name %s") % self.kwargs.get('username'))
|
|
return generic.ListView.get(self, request, *args, **kwargs)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = generic.ListView.get_context_data(self, **kwargs)
|
|
context['membership'] = self.membership
|
|
try:
|
|
context['kyu_dan_ranking'] = models.KyuDanRanking.objects.get(user=self.user)
|
|
except models.KyuDanRanking.DoesNotExist:
|
|
context['ranking'] = None
|
|
try:
|
|
context['ladder_ranking'] = models.LadderRanking.objects.get(
|
|
user=self.user,
|
|
season=models.LadderSeason.objects.current())
|
|
except models.LadderRanking.DoesNotExist:
|
|
context['ladder_ranking'] = models.LadderRanking(user=self.user)
|
|
return context
|
|
|
|
|
|
|
|
class PlayerDanScore(PlayerScore):
|
|
template_name = 'mahjong_ranking/player_dan_score.html'
|
|
|
|
def get_queryset(self):
|
|
return models.Player.objects.dan_hanchans(self.user)
|
|
|
|
|
|
class PlayerInvalidScore(PlayerScore):
|
|
template_name = 'mahjong_ranking/player_invalid_score.html'
|
|
|
|
def get_queryset(self):
|
|
return models.Player.objects.non_counting_hanchans(self.user)
|
|
|
|
|
|
class PlayerKyuScore(PlayerScore):
|
|
template_name = 'mahjong_ranking/player_kyu_score.html'
|
|
|
|
def get_queryset(self):
|
|
return models.Player.objects.kyu_hanchans(self.user)
|
|
|
|
|
|
class PlayerLadderScore(PlayerScore):
|
|
template_name = 'mahjong_ranking/player_ladder_score.html'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = PlayerScore.get_context_data(self, **kwargs)
|
|
season_list = models.LadderRanking.objects.filter(user=self.user).select_related('user')
|
|
season_list = season_list.values_list('id', 'season__name')
|
|
context['season'] = self.season
|
|
context['seasons_select_form'] = forms.SeasonSelectForm(user=self.user)
|
|
context['seasons_select_field'] = django.forms.ChoiceField(choices=season_list)
|
|
return context
|
|
|
|
def get_queryset(self, **kwargs):
|
|
if self.request.GET.get('season'):
|
|
self.season = models.LadderSeason.objects.get(pk=self.request.GET['season'])
|
|
else:
|
|
self.season = models.LadderSeason.objects.current()
|
|
return models.Player.objects.ladder_hanchans(user=self.user, season=self.season)
|