304 lines
9.5 KiB
Python
304 lines
9.5 KiB
Python
from django.shortcuts import render
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
from django.shortcuts import get_object_or_404
|
|
from django.urls import reverse
|
|
from django.contrib import messages
|
|
|
|
import collections
|
|
import pandas as pd
|
|
|
|
# Create your views here.
|
|
from django.views.generic.edit import CreateView
|
|
from boatmovers.models import Athlete, Crew, Race, Result
|
|
import boatmovers.tasks as tasks
|
|
from boatmovers.forms import CsvForm, TimeTeamForm, DatesForm
|
|
from boatmovers.scrapers import *
|
|
#from rowers.rows import handle_uploaded_file
|
|
import django_rq
|
|
queue = django_rq.get_queue('high')
|
|
|
|
class AthleteCreateView(CreateView):
|
|
model = Athlete
|
|
fields = [
|
|
'first_name',
|
|
'last_name',
|
|
'birth_year',
|
|
'gender',
|
|
'club',
|
|
]
|
|
success_url = '/boatmovers/'
|
|
|
|
class CrewCreateView(CreateView):
|
|
model = Crew
|
|
fields = [
|
|
'name',
|
|
'athletes'
|
|
]
|
|
|
|
success_url = '/boatmovers/'
|
|
|
|
class RaceCreateView(CreateView):
|
|
model = Race
|
|
fields = [
|
|
'name',
|
|
'resulturl',
|
|
'date',
|
|
'crew_size',
|
|
'gender',
|
|
#'resultlist',
|
|
]
|
|
|
|
success_url = '/boatmovers/'
|
|
|
|
class ResultCreateView(CreateView):
|
|
model = Result
|
|
fields = [
|
|
'crew',
|
|
'race',
|
|
'order'
|
|
]
|
|
|
|
success_url = '/boatmovers/'
|
|
|
|
def athlete_view(request,id=0):
|
|
athlete = get_object_or_404(Athlete, pk=id)
|
|
crews = athlete.athlete_crews
|
|
resultslist = []
|
|
|
|
for crew in crews.values():
|
|
c = Crew.objects.get(id=crew['id'])
|
|
results = Result.objects.filter(crew=c)
|
|
for result in results:
|
|
resultslist.append(result)
|
|
|
|
return render(request,
|
|
'athlete.html',
|
|
{
|
|
'athlete':athlete,
|
|
'results':resultslist,
|
|
})
|
|
|
|
def boatmovers_view(request):
|
|
athletes = Athlete.objects.filter(trueskill_exposed__gt=0,
|
|
dummy=False).order_by('-trueskill_exposed','-birth_year','last_name','first_name')
|
|
|
|
filter = request.GET.get('filter','all')
|
|
|
|
if filter == 'm':
|
|
athletes = athletes.exclude(gender='f')
|
|
elif filter == 'f':
|
|
athletes = athletes.exclude(gender='m')
|
|
|
|
races = Race.objects.filter(verified=True,processed=True).order_by('-date','-id')
|
|
new_races = Race.objects.filter(processed=False).order_by('date')
|
|
|
|
return render(request,
|
|
'boatmovers.html',
|
|
{'athletes':athletes,
|
|
'races': races,
|
|
'new_races': new_races}
|
|
)
|
|
|
|
def boatmovers_compareview(request):
|
|
form = DatesForm()
|
|
df = pd.DataFrame()
|
|
|
|
if request.method == 'POST':
|
|
form = DatesForm(request.POST)
|
|
if form.is_valid():
|
|
date1 = form.cleaned_data['date1']
|
|
date2 = form.cleaned_data['date2']
|
|
sort_by = form.cleaned_data['sort_by']
|
|
ascending = form.cleaned_data['ascending']
|
|
limit_to_first = form.cleaned_data['limit_to_first']
|
|
gender = form.cleaned_data['gender']
|
|
|
|
file1 = "media/boatmovers_"+date1+".csv"
|
|
df1 = pd.read_csv(file1)
|
|
if gender in ['m','f']:
|
|
df1 = df1[df1.gender==gender]
|
|
df1.index = df1['id']
|
|
df1 = df1.assign(rank=range(len(df1)))
|
|
df1['rank'] = df1['rank']+1
|
|
df1.rename(columns={'full_name':'Name','trueskill_exposed':'Score1','rank':'Rank1'},inplace=True)
|
|
df1 = df1.loc[:, ['Name','club','gender','Score1','Rank1']]
|
|
|
|
file2 = "media/boatmovers_"+date2+".csv"
|
|
df2 = pd.read_csv(file2)
|
|
if gender in ['m','f']:
|
|
df2 = df2[df2.gender==gender]
|
|
df2.index = df2['id']
|
|
df2 = df2.assign(rank=range(len(df2)))
|
|
df2['rank'] = df2['rank']+1
|
|
df2.rename(columns={'trueskill_exposed':'Score2','rank':'Rank2'},inplace=True)
|
|
df2 = df2.loc[:, ['Rank2','Score2']]
|
|
|
|
df = df1.merge(df2,left_on='id',right_on='id')
|
|
df['PositionsClimbed'] = df['Rank1']-df['Rank2']
|
|
df['ScoreIncrease'] = df['Score2']-df['Score1']
|
|
df = df.loc[:, ['Name', 'club', 'gender', 'Rank1', 'Rank2', 'PositionsClimbed',
|
|
'Score1', 'Score2',
|
|
'ScoreIncrease']]
|
|
|
|
df.sort_values(by='Rank2',inplace=True)
|
|
df = df.head(limit_to_first)
|
|
|
|
df.sort_values(by=[sort_by],inplace=True,ascending=ascending)
|
|
|
|
return render(request,
|
|
'boatmovers_compare.html',
|
|
{
|
|
'form':form,
|
|
'df':df,
|
|
})
|
|
|
|
|
|
def race_view(request,id=0):
|
|
race = get_object_or_404(Race, pk=id)
|
|
results = race.results.all().order_by('order')
|
|
|
|
crews = []
|
|
athletes = []
|
|
|
|
for result in results:
|
|
crews.append(result.crew.id)
|
|
for athlete in result.crew.athletes.all():
|
|
athletes.append(athlete.id)
|
|
|
|
# duplicates
|
|
duplicate_athletes = [item for item, count in collections.Counter(athletes).items() if count>1]
|
|
duplicate_crews = [item for item, count in collections.Counter(crews).items() if count>1]
|
|
duplicate_athletes_crews = []
|
|
for athlete_id in duplicate_athletes:
|
|
athlete = Athlete.objects.get(id=athlete_id)
|
|
crews = [crew.id for crew in athlete.athlete_crews.all()]
|
|
for crew in crews:
|
|
duplicate_athletes_crews.append(crew)
|
|
|
|
|
|
return render(request,
|
|
'race.html',
|
|
{
|
|
'race':race,
|
|
'results':results,
|
|
'duplicate_athletes':duplicate_athletes,
|
|
'duplicate_crews':duplicate_crews,
|
|
'duplicate_athletes_crews':duplicate_athletes_crews
|
|
}
|
|
)
|
|
|
|
def race_verify(request, id=0):
|
|
race = get_object_or_404(Race, pk=id)
|
|
outcome = race.validate()
|
|
|
|
return HttpResponseRedirect(reverse('race_view',kwargs={'id':race.id}))
|
|
|
|
def race_handle_timeteam(request,id=0):
|
|
race = get_object_or_404(Race, pk=id)
|
|
if race.verified or race.processed:
|
|
messages.error(request,"Cannot upload CSV file for processed or verified race")
|
|
url = reverse("race_view",kwargs={'id':id})
|
|
return HttpResponseRedirect(url)
|
|
|
|
form = TimeTeamForm(initial={'resulturl':race.resulturl})
|
|
if request.method == 'POST':
|
|
form = TimeTeamForm(request.POST)
|
|
|
|
if form.is_valid():
|
|
startorder = form.cleaned_data['startorder']
|
|
url = form.cleaned_data['resulturl']
|
|
race.resulturl = url
|
|
race.save()
|
|
job = queue.enqueue(
|
|
tasks.handle_timeteam,
|
|
url,race.id,race.gender,startorder)
|
|
|
|
messages.info(request,'URL has been submitted for processing')
|
|
url = reverse('race_view',kwargs={'id':race.id})
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
return render(request,
|
|
'timeteamform.html',
|
|
{
|
|
'race':race,
|
|
'form':form,
|
|
})
|
|
|
|
|
|
def handle_uploaded_file(f):
|
|
with open('media/results.csv', 'wb+') as destination:
|
|
for chunk in f.chunks():
|
|
destination.write(chunk)
|
|
|
|
def race_add_csv(request, id=0):
|
|
race = get_object_or_404(Race, pk=id)
|
|
if race.verified or race.processed:
|
|
messages.error(request,"Cannot upload CSV file for processed or verified race")
|
|
url = reverse("race_view",kwargs={'id':id})
|
|
return HttpResponseRedirect(url)
|
|
|
|
form = CsvForm()
|
|
if request.method == 'POST':
|
|
|
|
form = CsvForm(request.POST, request.FILES)
|
|
|
|
if form.is_valid():
|
|
handle_uploaded_file(request.FILES['file'])
|
|
if race.crew_size == 1:
|
|
bankjes = ['Slag']
|
|
elif race.crew_size == 2:
|
|
bankjes = ['Slag','Boeg']
|
|
elif race.crew_size == 4:
|
|
bankjes = ['Slag','2','3','Boeg']
|
|
elif race.crew_size == 8:
|
|
bankjes = ['Slag','2','3','4','5','6','7','Boeg']
|
|
|
|
csv_reader('media/results.csv',race.id,bankjes=bankjes,gender=race.gender)
|
|
|
|
url = reverse('race_view',kwargs={'id':race.id})
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
return render(request,
|
|
'csvform.html',
|
|
{
|
|
'race':race,
|
|
'form':form,
|
|
})
|
|
|
|
def race_process(request, id=0):
|
|
race = get_object_or_404(Race, pk=id)
|
|
job = queue.enqueue(tasks.race_process,race.id)
|
|
#outcome = race.process()
|
|
messages.info(request,"Your race is being processed. Reload to get the new status.")
|
|
|
|
return HttpResponseRedirect(reverse('race_view',kwargs={'id':race.id}))
|
|
|
|
def race_delete_results(request, id=0):
|
|
race = get_object_or_404(Race, pk=id)
|
|
results = race.results.all()
|
|
|
|
if not race.processed:
|
|
for result in results:
|
|
result.delete()
|
|
messages.info(request,'Results have been removed')
|
|
else:
|
|
messages.error(request,'Cannot remove processed results')
|
|
|
|
url = reverse('race_view',kwargs={'id':race.id})
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
def crew_view(request, id=0):
|
|
crew = get_object_or_404(Crew, pk=id)
|
|
athletes = crew.athletes.all().order_by("-trueskill_exposed")
|
|
|
|
return render(request,
|
|
'crew.html',
|
|
{
|
|
'crew':crew,
|
|
'athletes':athletes
|
|
})
|