Files
TipPy/tipp/views.py

565 lines
18 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['groupOrderID']).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)
for team in teams[0]:
t = Team(
teamID=team['teamID'],
name=team['teamName'],
iconURL = team['teamIconURL']
)
t.save()
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=season, matchday=md['groupOrderID'])
@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'] == "Endergebnis":
pointsTeam1=int(result['pointsTeam1'])
pointsTeam2=int(result['pointsTeam2'])
elif result['resultName'] == "Halbzeit":
pointsTeam1=int(result['pointsTeam1'])
pointsTeam2=int(result['pointsTeam2'])
else:
pointsTeam1=-1
pointsTeam2=-1
except:
pointsTeam1=-1
pointsTeam2=-1
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 = match['groupName'],
idTeam1=Team.objects.get(teamID=int(match['idTeam1'])),
idTeam2=Team.objects.get(teamID=int(match['idTeam2'])),
pointsTeam1=pointsTeam1,
pointsTeam2=pointsTeam2,
finished=bool(match['matchIsFinished']),
season=match['leagueSaison'],
leagueShortcut=match['leagueShortcut']
)
m.save()
pointsTeam1=-1
pointsTeam2=-1
""" evaluate scores """
scores = Score.objects.get(client=Mandant.objects.get(name='huse'))
finished_matches=Match.objects.filter(finished=True)
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=cur_md)
@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 """
tipp_mates = []
for m in mandants:
rs = RelUserMandant.objects.filter(mandant=m)
for r in rs:
"""filter duplicates """
d = False
for item in tipp_mates:
if r.user == item['mate']:
d = True
if d is False:
tipp_mates.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
for mate in tipp_mates:
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
posts = []
for post in Post.objects.filter(published=True)[:1]:
try:
avatar = UserProfile.objects.get(user_id=post.author_id).avatar.name
except:
avatar = None
posts.append( (post, avatar) )
cur_group = matches[0]['md_name']
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,
'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, season) < 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
post_list = []
for post in Post.objects.filter(published=True):
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:
# If page is not an integer, deliver first page.
posts = p.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
posts = p.page(p.num_pages)
# now return the rendered template
return render(request, 'blogindex.html', {
'posts': posts,
'ls': get_current_ls(),
'season': get_current_season(),
'page': page
})
@login_required
def newBlogpost(request):
"""
if this is a POST request we need to process the form data
"""
if request.method == 'POST':
# create form instance and populate it with data from the request
form = BlogpostForm(request.POST)
# check whether it's valid:
if form.is_valid():
data = form.cleaned_data
p = Post(author_id=request.user.id, content=data['content'])
p.save()
# ...
# redirect to a new URL:
return redirect( '/blog/1')
# if a GET (or any other method) we'll create a blank form
else:
blogpostForm = BlogpostForm()
return render(request, 'newblogpost.html', {
'form': blogpostForm,
'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)
def get_current_ls():
return("em2016")
def get_current_season():
return("2016")