644 lines
20 KiB
Python
644 lines
20 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Copyright (c) 2015-2016 by Martin Bley (martin@mb-oss.de)
|
|
|
|
This file is part of TipPy.
|
|
|
|
TipPy is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
TipPy is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with TipPy. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
from django.http import HttpResponse
|
|
from django.shortcuts import render_to_response, redirect, render, \
|
|
get_object_or_404
|
|
from django.contrib.auth import authenticate, login
|
|
from django.contrib.auth.models import User
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib.auth.views import password_reset, \
|
|
password_reset_confirm
|
|
from django.core.context_processors import csrf
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
from django.core.urlresolvers import reverse
|
|
from django.core.paginator import Paginator, InvalidPage, EmptyPage, \
|
|
PageNotAnInteger
|
|
from django.utils import timezone
|
|
from django.utils.text import slugify
|
|
from django.db.models import Sum, Max
|
|
from django.conf import settings
|
|
from os.path import join as pjoin
|
|
from tipp.models import *
|
|
from tipp.forms import *
|
|
from openliga import *
|
|
from datetime import datetime
|
|
from PIL import Image as PImage
|
|
import urllib2, pytz, os, sys
|
|
|
|
# setting utf-8 as default encoding to avoid errors in file
|
|
# uploads and form data
|
|
reload(sys)
|
|
sys.setdefaultencoding('utf8')
|
|
|
|
timezoneLocal = pytz.timezone('Europe/Berlin')
|
|
|
|
@login_required
|
|
def home(request):
|
|
ls = get_current_ls()
|
|
season = get_current_season()
|
|
md = get_current_md(ls)
|
|
|
|
return redirect("matchday",
|
|
ls = ls,
|
|
season = season,
|
|
matchday=str(md).zfill(2)
|
|
)
|
|
|
|
@login_required
|
|
def profile(request, pk):
|
|
user = User.objects.get(id=pk)
|
|
profile, created = UserProfile.objects.get_or_create(user=user)
|
|
|
|
if profile.avatar:
|
|
img = profile.avatar.name
|
|
else:
|
|
img = None
|
|
|
|
debug = []
|
|
debug.append('avatar: ' + str(img))
|
|
|
|
# If it's a HTTP POST, we're interested in processing form data.
|
|
if request.method == 'POST':
|
|
user_form = UserForm(data=request.POST, instance=user)
|
|
profile_form = UserProfileForm(
|
|
data=request.POST, instance=profile
|
|
)
|
|
|
|
if user_form.is_valid() and profile_form.is_valid():
|
|
|
|
user = user_form.save()
|
|
|
|
profile = profile_form.save(commit=False)
|
|
profile.user = user
|
|
|
|
# Did the user provide a profile picture?
|
|
if 'avatar' in request.FILES:
|
|
profile.avatar = request.FILES['avatar']
|
|
# Now we save the UserProfile model instance.
|
|
profile.save()
|
|
|
|
# create thumbnail
|
|
imfn = pjoin(settings.MEDIA_ROOT, profile.avatar.name)
|
|
im = PImage.open(imfn)
|
|
im.thumbnail((50,50), PImage.ANTIALIAS)
|
|
im.save(settings.MEDIA_ROOT + profile.avatar.name)
|
|
if 'avatar-clear' in request.POST:
|
|
if 'on' in request.POST['avatar-clear']:
|
|
image = pjoin(settings.MEDIA_ROOT, img)
|
|
debug.append('Is the image ' + str(image)
|
|
+ ' a regular file? '
|
|
+ str(os.path.isfile(image))
|
|
)
|
|
if os.path.isfile(image):
|
|
os.remove(image)
|
|
profile.save()
|
|
|
|
for item in request.POST:
|
|
debug.append(str(item) + " -> "
|
|
+ str(request.POST[item])
|
|
)
|
|
|
|
# Invalid form or forms - mistakes or something else?
|
|
# Print problems to the terminal.
|
|
# They'll also be shown to the user.
|
|
else:
|
|
print user_form.errors, profile_form.errors
|
|
|
|
return redirect( '/accounts/profile/' + str(user.id) )
|
|
|
|
# Not a HTTP POST, so we render our form using two ModelForm
|
|
# instances. These forms will be blank, ready for user input.
|
|
else:
|
|
user_form = UserForm(
|
|
initial={ 'last_name': user.last_name,
|
|
'first_name': user.first_name,
|
|
'email': user.email },
|
|
instance=user
|
|
)
|
|
profile_form = UserProfileForm(instance=profile)
|
|
|
|
return render(request, 'registration/profile.html', {
|
|
'user_form': user_form,
|
|
'profile_form': profile_form,
|
|
'debug': debug,
|
|
'img': img}
|
|
)
|
|
|
|
|
|
@login_required
|
|
def getSeason(request, ls, season):
|
|
ol = OpenLiga()
|
|
teams = ol.getTeams(str(season), ls)
|
|
season = ol.getSeason(str(season), ls)
|
|
md = get_current_md(ls)
|
|
|
|
return_vals = []
|
|
for team in teams[0]:
|
|
t = Team(
|
|
teamID=team['teamID'],
|
|
name=team['teamName'],
|
|
iconURL = team['teamIconURL']
|
|
)
|
|
|
|
"""
|
|
check if object exits and do insert if not
|
|
"""
|
|
try:
|
|
to = Team.objects.get(teamID=int(t.teamID))
|
|
except Team.DoesNotExist:
|
|
t.save()
|
|
|
|
if to.iconURL is None:
|
|
t.save(update_fields=['iconURL'])
|
|
|
|
|
|
for match in season[0]:
|
|
m = Match(matchID=unicode(match['matchID']),
|
|
matchDateTime=datetime.strptime(
|
|
unicode(match['matchDateTime']), '%Y-%m-%d %H:%M:%S'),
|
|
group=int(match['groupID']),
|
|
matchday=int(match['groupOrderID']),
|
|
matchday_name=unicode(match['groupName']),
|
|
idTeam1=Team.objects.get(teamID=int(match['idTeam1'])),
|
|
idTeam2=Team.objects.get(teamID=int(match['idTeam2'])),
|
|
pointsTeam1=match['pointsTeam1'],
|
|
pointsTeam2=match['pointsTeam2'],
|
|
finished=bool(match['matchIsFinished']),
|
|
season=match['leagueSaison'],
|
|
leagueShortcut=match['leagueShortcut']
|
|
)
|
|
m.save()
|
|
|
|
return redirect("matchday",
|
|
ls=ls,
|
|
season=get_current_season(),
|
|
matchday=str(get_current_md(ls)).zfill(2)
|
|
)
|
|
|
|
@login_required
|
|
def update(request, ls, season, cur_md):
|
|
"""
|
|
To do:
|
|
- update table tipp_competition
|
|
"""
|
|
|
|
ol = OpenLiga()
|
|
md_matches = ol.getMatchday(str(season), int(cur_md) ,ls)
|
|
|
|
# Achtung: DateTimeField prüfen
|
|
for match in md_matches[0]:
|
|
# Endergebnis holen
|
|
matchResults = match['matchResults']
|
|
try:
|
|
for result in matchResults[0]:
|
|
if result['resultName'] == "Halbzeit":
|
|
pointsTeam1=int(result['pointsTeam1'])
|
|
pointsTeam2=int(result['pointsTeam2'])
|
|
elif result['resultName'] == "Endergebnis":
|
|
pointsTeam1=int(result['pointsTeam1'])
|
|
pointsTeam2=int(result['pointsTeam2'])
|
|
elif str(result['resultName']) == u"nach Verlängerung":
|
|
pointsTeam1=int(result['pointsTeam1'])
|
|
pointsTeam2=int(result['pointsTeam2'])
|
|
except:
|
|
pointsTeam1=-1
|
|
pointsTeam2=-1
|
|
|
|
|
|
m = Match(matchID=unicode(match['matchID']),
|
|
pointsTeam1=pointsTeam1,
|
|
pointsTeam2=pointsTeam2,
|
|
finished=bool(match['matchIsFinished']),
|
|
)
|
|
m.save(update_fields=['pointsTeam1', 'pointsTeam2', 'finished'])
|
|
pointsTeam1=-1
|
|
pointsTeam2=-1
|
|
|
|
# evaluate scores
|
|
scores = Score.objects.get(client=Mandant.objects.get(name='huse'))
|
|
finished_matches=Match.objects.filter(
|
|
finished=True,
|
|
leagueShortcut=ls,
|
|
season=season,
|
|
matchday = cur_md
|
|
)
|
|
for match in finished_matches:
|
|
tipps = Tipp.objects.filter(matchID=match.matchID)
|
|
for tipp in tipps:
|
|
score = 0
|
|
goals_total = match.pointsTeam1 + match.pointsTeam2
|
|
|
|
# Tipp is acurate
|
|
if (tipp.pointsTeam1 == match.pointsTeam1
|
|
and tipp.pointsTeam2 == match.pointsTeam2):
|
|
if goals_total >= 5:
|
|
score = scores.exact_high
|
|
else:
|
|
score = scores.exact
|
|
|
|
tipp.score = score
|
|
tipp.save()
|
|
continue
|
|
|
|
# who won?
|
|
winnerReal = None
|
|
if match.pointsTeam1 > match.pointsTeam2:
|
|
winnerReal = 1
|
|
elif (match.pointsTeam2 > match.pointsTeam1):
|
|
winnerReal = 2
|
|
elif (match.pointsTeam1 == match.pointsTeam2):
|
|
winnerReal = 0
|
|
|
|
winnerTipp = None
|
|
if tipp.pointsTeam1 > tipp.pointsTeam2:
|
|
winnerTipp = 1
|
|
elif (tipp.pointsTeam2 > tipp.pointsTeam1):
|
|
winnerTipp = 2
|
|
elif (tipp.pointsTeam1 == tipp.pointsTeam2):
|
|
winnerTipp = 0
|
|
|
|
diffReal = match.pointsTeam1 - match.pointsTeam2
|
|
diffTipp = tipp.pointsTeam1 - tipp.pointsTeam2
|
|
|
|
if ( winnerTipp == winnerReal ):
|
|
if ( diffTipp == diffReal ):
|
|
score = scores.diff
|
|
else:
|
|
score = scores.tendency
|
|
|
|
tipp.score = score
|
|
tipp.save()
|
|
continue
|
|
|
|
tipp.score = score
|
|
tipp.save()
|
|
continue
|
|
|
|
return redirect("matchday",
|
|
ls=ls,
|
|
season=season,
|
|
matchday=str(get_current_md(ls)).zfill(2)
|
|
)
|
|
|
|
@login_required
|
|
def matchday(request, ls, season, matchday, template_name='md.html'):
|
|
debug = ''
|
|
debug += "Debugging: "
|
|
has_refresh = True
|
|
|
|
""" get matches of the matchday """
|
|
md_matches = Match.objects.filter(leagueShortcut=ls, season=season,
|
|
matchday=int(matchday)).order_by('matchDateTime')
|
|
|
|
""" get the current user """
|
|
user = User.objects.get(username=request.user.username)
|
|
|
|
""" get mandants current user is related """
|
|
mandants = RelUserMandant.objects.filter(user=request.user). \
|
|
values_list('mandant', flat=True)
|
|
|
|
""" get mates """
|
|
mandant_dict = {}
|
|
for m in mandants:
|
|
mandant = Mandant.objects.get(id=m)
|
|
mandant_dict[mandant.name] = []
|
|
rs = RelUserMandant.objects.filter(mandant=m)
|
|
|
|
for r in rs:
|
|
mandant_dict[mandant.name].append({
|
|
'mate': r.user,
|
|
'tipps': [],
|
|
'sum_score': 0
|
|
})
|
|
|
|
matches = []
|
|
for match in md_matches:
|
|
"""
|
|
create a form for each tipp
|
|
"""
|
|
form = TippForm(request.POST or None, prefix=str(match.matchID))
|
|
|
|
"""
|
|
check if Tipp already exists
|
|
"""
|
|
try:
|
|
tipp = Tipp.objects.get(tipperID=user.id,
|
|
matchID=match.matchID)
|
|
except ObjectDoesNotExist:
|
|
tipp = None
|
|
|
|
"""
|
|
if request is a POST, process form data, else just show form
|
|
"""
|
|
if form.is_valid():
|
|
data = form.cleaned_data
|
|
|
|
if tipp is not None:
|
|
""" Tipp exists an needs an UPDATE"""
|
|
tipp = Tipp(id=tipp.pk,
|
|
matchID=match,
|
|
tipperID=user,
|
|
pointsTeam1=data['tippTeam1'],
|
|
pointsTeam2=data['tippTeam2']
|
|
)
|
|
tipp.save()
|
|
|
|
else:
|
|
""" do INSERT """
|
|
tipp = Tipp( matchID=match,
|
|
tipperID=user,
|
|
pointsTeam1=data['tippTeam1'],
|
|
pointsTeam2=data['tippTeam2'])
|
|
tipp.save()
|
|
|
|
match_started = timezone.now() >= match.matchDateTime
|
|
|
|
if tipp is not None:
|
|
f = TippForm(prefix=str(match.matchID),
|
|
initial={'tippTeam1': tipp.pointsTeam1,
|
|
'tippTeam2': tipp.pointsTeam2}
|
|
)
|
|
else:
|
|
f = TippForm(prefix=str(match.matchID))
|
|
|
|
item = {}
|
|
item['matchDateTime'] = (match.matchDateTime. \
|
|
astimezone(timezoneLocal).strftime('%a %d.%m, %H:%M'))
|
|
|
|
item['iconTeam1']= str(match.idTeam1.icon)
|
|
item['iconURLTeam1'] = str(match.idTeam1.iconURL)
|
|
item['nameTeam1']= str(match.idTeam1)
|
|
item['abbrTeam1']= str(match.idTeam1.abbr)
|
|
item['iconTeam2'] = str(match.idTeam2.icon)
|
|
item['iconURLTeam2'] = str(match.idTeam2.iconURL)
|
|
item['nameTeam2'] = str(match.idTeam2)
|
|
item['abbrTeam2']= str(match.idTeam2.abbr)
|
|
item['started'] = match_started
|
|
item['finished'] = match.finished
|
|
item['md_name'] = match.matchday_name
|
|
|
|
if (match.pointsTeam1 == -1 or match.pointsTeam2 == -1):
|
|
item['matchResult'] = "-:-"
|
|
else:
|
|
item['matchResult'] = str(match.pointsTeam1) + ":" \
|
|
+ str(match.pointsTeam2)
|
|
|
|
item['tippFormTeam1'] = f['tippTeam1']
|
|
item['tippFormTeam2'] = f['tippTeam2']
|
|
|
|
if match_started is True:
|
|
f.fields['tippTeam1'].widget.attrs['disabled'] = True
|
|
f.fields['tippTeam2'].widget.attrs['disabled'] = True
|
|
|
|
""" get tipps from mates """
|
|
for mandant in mandant_dict:
|
|
for mate in mandant_dict[mandant]:
|
|
try:
|
|
matetipp = Tipp.objects.get(tipperID=mate['mate'],
|
|
matchID=match.matchID)
|
|
if match_started is True:
|
|
if matetipp.score is None:
|
|
score = u'\u231B'
|
|
else:
|
|
score = matetipp.score
|
|
|
|
mate['tipps'].append(str(matetipp.pointsTeam1)
|
|
+ ":" + str(matetipp.pointsTeam2)
|
|
+ "(" + str(score) + ")")
|
|
if match.finished is True:
|
|
mate['sum_score'] += matetipp.score
|
|
else:
|
|
mate['tipps'].append(u'\u2714')
|
|
except Exception as e:
|
|
mate['tipps'].append(u'\u2717')
|
|
|
|
matches.append(item)
|
|
|
|
# get the newest blogposts
|
|
pm = RelPostMandant.objects.filter(mandant__in=mandants). \
|
|
values_list('post', flat=True)
|
|
posts = []
|
|
for post in Post.objects.filter(id__in=pm, published=True)[:1]:
|
|
try:
|
|
avatar = UserProfile.objects.get(user_id=post.author_id). \
|
|
avatar.name
|
|
except:
|
|
avatar = None
|
|
posts.append( (post, avatar) )
|
|
|
|
try:
|
|
cur_group = matches[0]['md_name']
|
|
except:
|
|
cur_group = "N/A"
|
|
|
|
return render(request, 'md.html', {
|
|
#'debug': debug,
|
|
#'mds_season': mds_in_season,
|
|
'cur_md': matchday,
|
|
'md_name': cur_group,
|
|
'matches': matches,
|
|
'ls': ls,
|
|
'season': season,
|
|
'username': user,
|
|
'mandant_dict': mandant_dict,
|
|
#'tipp_mates': sorted(tipp_mates, key=lambda k: k['sum_score'],
|
|
#reverse=True),
|
|
'posts': posts,
|
|
'has_refresh': has_refresh
|
|
})
|
|
|
|
@login_required
|
|
def charts(request, ls, season, pos='default',
|
|
template_name='charts.html'):
|
|
|
|
debug = ''
|
|
|
|
if pos == 'default':
|
|
if get_current_md(ls) < 18:
|
|
pos = 'hin'
|
|
matches = Match.objects.filter(leagueShortcut=ls,
|
|
season=season, matchday__lte=17)
|
|
else:
|
|
pos = 'rueck'
|
|
matches = Match.objects.filter(leagueShortcut=ls,
|
|
season=season, matchday__gte=18)
|
|
elif pos == 'hin':
|
|
matches = Match.objects.filter(leagueShortcut=ls,
|
|
season=season, matchday__lte=17)
|
|
elif pos == 'rueck':
|
|
matches = Match.objects.filter(leagueShortcut=ls,
|
|
season=season, matchday__gte=18)
|
|
else:
|
|
matches = Match.objects.filter(leagueShortcut=ls, season=season)
|
|
|
|
# get mandants of current user
|
|
mandants = RelUserMandant.objects.filter(user=request.user). \
|
|
values_list('mandant', flat=True)
|
|
|
|
# main loop
|
|
mandant_dict = {}
|
|
for m in mandants:
|
|
mandant = Mandant.objects.get(id=m)
|
|
|
|
# get users
|
|
users = RelUserMandant.objects.filter(mandant=m). \
|
|
values_list('user', flat=True)
|
|
|
|
user_dict = {}
|
|
for userid in users:
|
|
# get user object, then fetch matches for user
|
|
user = User.objects.get(id=userid)
|
|
score = Tipp.objects.filter(matchID__in=matches, \
|
|
tipperID=user).aggregate(Sum('score'))
|
|
|
|
if score['score__sum'] is None:
|
|
user_dict[user.first_name] = 0
|
|
else:
|
|
user_dict[user.first_name] = score['score__sum']
|
|
|
|
mandant_dict[mandant.name] = sorted(user_dict.items(),
|
|
key=lambda x: x[1], reverse=True)
|
|
|
|
return render(request, template_name, {
|
|
#'debug': debug,
|
|
'mandant_dict': mandant_dict,
|
|
'season': season,
|
|
'ls': ls,
|
|
'pos': pos
|
|
})
|
|
|
|
@login_required
|
|
def blogindex(request, page):
|
|
# get the blog posts that are published
|
|
# and related to mandant
|
|
mandants = RelUserMandant.objects.filter(user=request.user). \
|
|
values_list('mandant', flat=True)
|
|
posts = RelPostMandant.objects.filter(mandant__in=mandants). \
|
|
values_list('post', flat=True)
|
|
|
|
post_list = []
|
|
for post in Post.objects.filter(published=True, id__in=posts):
|
|
try:
|
|
avatar = UserProfile.objects.get(user_id=post.author_id). \
|
|
avatar.name
|
|
except:
|
|
avatar = None
|
|
post_list.append( (post, avatar) )
|
|
|
|
p = Paginator(post_list, 5)
|
|
|
|
try:
|
|
posts = p.page(page)
|
|
except PageNotAnInteger:
|
|
posts = p.page(1)
|
|
except EmptyPage:
|
|
posts = p.page(p.num_pages)
|
|
|
|
return render(request, 'blogindex.html', {
|
|
'posts': posts,
|
|
'ls': get_current_ls(),
|
|
'season': get_current_season(),
|
|
'page': page
|
|
})
|
|
|
|
@login_required
|
|
def newBlogpost(request):
|
|
debug = ''
|
|
|
|
has_mandant = False
|
|
mandants = RelUserMandant.objects.filter(user=request.user). \
|
|
values_list('mandant', flat=True)
|
|
choices = []
|
|
if mandants.count > 1:
|
|
has_mandant = True
|
|
for m in Mandant.objects.filter(id__in=mandants):
|
|
choices.append( (m.name, m.description) )
|
|
|
|
if request.method == 'POST':
|
|
form_bp = BlogpostForm(request.POST)
|
|
if has_mandant is True:
|
|
form_mandant = MandantsForm(request.POST)
|
|
form_mandant.fields["mandants"].choices = choices
|
|
|
|
if form_bp.is_valid():
|
|
data = form_bp.cleaned_data
|
|
p = Post(author_id=request.user.id, content=data['content'])
|
|
p.save()
|
|
|
|
if has_mandant is True and form_mandant.is_valid():
|
|
data = form_mandant.cleaned_data
|
|
for m in data['mandants']:
|
|
debug += str(m) + " "
|
|
m = RelPostMandant(post=p,
|
|
mandant=Mandant.objects.get(name=m))
|
|
m.save()
|
|
else:
|
|
m = RelPostMandant(post=p,
|
|
mandant=Mandant.objects.get(id=mandants[0]))
|
|
m.save()
|
|
|
|
return redirect( '/blog/1')
|
|
|
|
blogpostForm = BlogpostForm()
|
|
form_mandant = MandantsForm()
|
|
form_mandant.fields["mandants"].choices = choices
|
|
cnt_mandants = len(choices)
|
|
|
|
return render(request, 'newblogpost.html', {
|
|
'debug': debug,
|
|
'form_bp': blogpostForm,
|
|
'form_mandants': form_mandant,
|
|
'cnt_mandants' : cnt_mandants,
|
|
'ls': get_current_ls(),
|
|
'season': get_current_season()
|
|
})
|
|
|
|
def logout(request):
|
|
"""
|
|
Log users out and re-direct them to the main page.
|
|
"""
|
|
logout(request)
|
|
return HttpResponseRedirect('/')
|
|
|
|
def get_current_md(ls):
|
|
"""
|
|
get current matchday()
|
|
returns dict with keys
|
|
['groupName']
|
|
['groupOrderID']
|
|
['groupID']
|
|
"""
|
|
|
|
try:
|
|
ol = OpenLiga()
|
|
cur_md = ol.getCurrentGroup(ls)
|
|
except:
|
|
cur_md = {'groupName': u"1. Spieltag", 'groupOrderID': 1}
|
|
|
|
return(cur_md['groupOrderID'])
|
|
|
|
def get_current_ls():
|
|
return("bl1")
|
|
|
|
def get_current_season():
|
|
return("2016")
|
|
|