optimiert werden. jQuery wurde entfernt. Übersetzungen wurden korrigiert. Neue sync.sh Datei, welche änderungen mit rsync auf den Server spielt und das neuladen erzwingt.
364 lines
13 KiB
Python
364 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 events.views import EventDetailMixin
|
|
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(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.
|
|
"""
|
|
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(EventDetailMixin, 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(EventDetailMixin, 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'))
|
|
|
|
|
|
class EventRankingList(EventDetailMixin, 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'))
|
|
|
|
|
|
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_list'] = models.LadderSeason.objects.all()
|
|
context['latest_hanchan_list'] = models.Hanchan.objects.filter(
|
|
valid=True)[:3]
|
|
context['latest_event_list'] = Event.objects.archive()[:3]
|
|
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(user=self.user)
|
|
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)
|