Milestone 08-14
* Mahjong Ranking wurde stark vereinfacht um Fehler besser vorzubeugen. * Online WYSIWYG Editor auf CKEditor umgeändert, damit online bearbeiten für unbedarfte besser funktioniert. * Viele kleine Optimierungen am CSS für bessere Performance. * CSS wird jetzt aus LESS Code generiert * Für dise Arbeit wird jetzt grunt und node package management lokal verwendet.
This commit is contained in:
@@ -1,22 +1,19 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
from datetime import date
|
||||
|
||||
import urllib
|
||||
|
||||
from django.contrib import auth, messages
|
||||
from django.contrib import auth
|
||||
from django.core.urlresolvers import reverse
|
||||
import django.forms
|
||||
import django.http
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
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'),
|
||||
@@ -46,49 +43,32 @@ class DeleteHanchan(EventDetailMixin, PermissionRequiredMixin, generic.DeleteVie
|
||||
kwargs={'event': self.object.event.pk})
|
||||
|
||||
|
||||
class HanchanForm(EventDetailMixin, PermissionRequiredMixin, generic.UpdateView):
|
||||
class HanchanForm(SuccessMessageMixin, EventDetailMixin, PermissionRequiredMixin, generic.UpdateView):
|
||||
"""
|
||||
Ein Formular um eine neue Hanchan anzulegen, bzw. eine bestehende zu
|
||||
Ein Formular um neue Hanchans 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_context_data(self, **kwargs):
|
||||
context = generic.UpdateView.get_context_data(self, **kwargs)
|
||||
context['event'] = self.event
|
||||
return context
|
||||
|
||||
def get_form_class(self):
|
||||
"""
|
||||
Returns the form class to use in this view
|
||||
Users with edit Persmission will see the AdminForm to confirm
|
||||
unconfirmed Hanchans.
|
||||
"""
|
||||
if self.request.user.has_perm('mahjong_ranking.delete_hanchan'):
|
||||
if self.request.user.has_perm('mahjong_ranking.change_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'):
|
||||
if self.kwargs.get('hanchan') and self.request.user.has_perm('mahjong_ranking.change_hanchan'):
|
||||
hanchan = models.Hanchan.objects.get(id=self.kwargs['hanchan'])
|
||||
self.event = hanchan.event
|
||||
elif self.kwargs.get('event'):
|
||||
@@ -97,38 +77,23 @@ class HanchanForm(EventDetailMixin, PermissionRequiredMixin, generic.UpdateView)
|
||||
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):
|
||||
def get_success_url(self):
|
||||
"""
|
||||
|
||||
:param request:
|
||||
Adding a new Hanchan redirect to create_hanchan form.
|
||||
Editing an exiting one: redierect to the Hanchanevent.
|
||||
"""
|
||||
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)
|
||||
if self.kwargs.get('hanchan'):
|
||||
return self.object.get_absolute_url()
|
||||
else:
|
||||
return self.form_invalid(form, formset)
|
||||
return reverse('add-hanchan-form', kwargs={'event': self.event.pk})
|
||||
|
||||
def get_success_message(self, cleaned_data):
|
||||
if self.kwargs.get('hanchan'):
|
||||
return _('%s has been updated successfully.') % self.object
|
||||
else:
|
||||
return _('%s has been added successfully. You can now add a new one.') % self.object
|
||||
|
||||
|
||||
class EventHanchanList(EventDetailMixin, generic.ListView):
|
||||
@@ -142,7 +107,6 @@ class EventHanchanList(EventDetailMixin, generic.ListView):
|
||||
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:
|
||||
@@ -160,8 +124,7 @@ class EventRankingList(EventDetailMixin, generic.ListView):
|
||||
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
|
||||
return queryset.prefetch_related()
|
||||
except models.Event.DoesNotExist:
|
||||
raise django.http.Http404(_('Event does not exist'))
|
||||
|
||||
@@ -176,130 +139,47 @@ class KyuDanRankingList(generic.ListView):
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.order_by = kyu_dan_order[
|
||||
kwargs.get('order_by', self.default_order)] # @IgnorePep8
|
||||
kwargs.get('order_by', self.default_order)
|
||||
]
|
||||
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
|
||||
queryset = models.KyuDanRanking.objects.all().order_by(*self.order_by)
|
||||
return queryset.select_related('user__membership')
|
||||
|
||||
|
||||
class LadderRankingList(generic.ListView):
|
||||
model = models.LadderRanking
|
||||
class SeasonRankingList(generic.ListView):
|
||||
model = models.SeasonRanking
|
||||
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
|
||||
self.season = int(self.kwargs.get('season', date.today().year))
|
||||
queryset = self.model.objects.filter(season=self.season,
|
||||
placement__isnull=False)
|
||||
return queryset.select_related()
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = generic.ListView.get_context_data(self, **kwargs)
|
||||
context['is_archive'] = self.is_archive
|
||||
context = super(SeasonRankingList, self).get_context_data(**kwargs)
|
||||
context['season'] = self.season
|
||||
context['season_list'] = models.LadderSeason.objects.all()
|
||||
context['latest_hanchan_list'] = models.Hanchan.objects.filter(
|
||||
valid=True)[:3]
|
||||
context['season_start'] = date(year=self.season, month=1, day=1)
|
||||
context['season_end'] = date(year=self.season, month=12, day=31)
|
||||
context['season_list'] = models.SeasonRanking.objects.season_list
|
||||
context['latest_hanchan_list'] = models.Hanchan.objects.confirmed_hanchans()[: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):
|
||||
user_model = auth.get_user_model()
|
||||
try:
|
||||
user_model = auth.get_user_model()
|
||||
self.user = user_model.objects.get(username=self.kwargs.get('username'))
|
||||
except 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)
|
||||
raise django.http.Http404(_("No user found matching the name {}").format(self.kwargs.get('username')))
|
||||
return super(PlayerScore, self).get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = generic.ListView.get_context_data(self, **kwargs)
|
||||
@@ -310,11 +190,11 @@ class PlayerScore(LoginRequiredMixin, generic.ListView):
|
||||
except models.KyuDanRanking.DoesNotExist:
|
||||
context['ranking'] = None
|
||||
try:
|
||||
context['ladder_ranking'] = models.LadderRanking.objects.get(
|
||||
context['ladder_ranking'] = models.SeasonRanking.objects.get(
|
||||
user=self.user,
|
||||
season=models.LadderSeason.objects.current())
|
||||
except models.LadderRanking.DoesNotExist:
|
||||
context['ladder_ranking'] = models.LadderRanking(user=self.user)
|
||||
season=date.today().year)
|
||||
except models.SeasonRanking.DoesNotExist:
|
||||
context['ladder_ranking'] = models.SeasonRanking(user=self.user)
|
||||
return context
|
||||
|
||||
|
||||
@@ -322,42 +202,39 @@ class PlayerDanScore(PlayerScore):
|
||||
template_name = 'mahjong_ranking/player_dan_score.html'
|
||||
|
||||
def get_queryset(self):
|
||||
return models.Player.objects.dan_hanchans(self.user)
|
||||
return models.Hanchan.objects.dan_hanchans(user=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)
|
||||
return models.Hanchan.objects.unconfirmed_hanchans(user=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)
|
||||
return models.Hanchan.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 = super(PlayerLadderScore, self).get_context_data(**kwargs)
|
||||
context['season'] = self.season
|
||||
context['seasons_select_form'] = forms.SeasonSelectForm(user=self.user)
|
||||
context['seasons_select_field'] = django.forms.ChoiceField(
|
||||
choices=season_list)
|
||||
context['season_start'] = date(year=self.season, month=1, day=1)
|
||||
context['season_end'] = date(year=self.season, month=12, day=31)
|
||||
context['season_list'] = models.SeasonRanking.objects.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)
|
||||
try:
|
||||
self.season = int(self.request.GET.get('season'))
|
||||
except:
|
||||
self.season = date.today().year
|
||||
hanchan_list = models.Hanchan.objects.season_hanchans(user=self.user, season=self.season)
|
||||
print hanchan_list
|
||||
return hanchan_list
|
||||
|
||||
Reference in New Issue
Block a user