You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
354 lines
12 KiB
354 lines
12 KiB
from django.shortcuts import render, get_object_or_404
|
|
from django.http import HttpResponse
|
|
from django.utils.encoding import force_str
|
|
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
|
from django.urls import reverse
|
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.core.files.storage import default_storage
|
|
from django.core.files.base import ContentFile
|
|
|
|
from tournaments.models.device_token import DeviceToken
|
|
|
|
# from tournaments.models import group_stage
|
|
from .models import Court, DateInterval, Club, Tournament, CustomUser, Event, Round, GroupStage, Match, TeamScore, TeamRegistration, PlayerRegistration, Purchase, FailedApiCall
|
|
from .models import TeamSummon
|
|
from datetime import datetime, timedelta
|
|
|
|
from django.template import loader
|
|
from datetime import date
|
|
from django.http import JsonResponse
|
|
from django.db.models import Q
|
|
import json
|
|
import asyncio
|
|
|
|
from api.tokens import account_activation_token
|
|
|
|
from qr_code.qrcode.utils import QRCodeOptions
|
|
from .utils.apns import send_push_notification
|
|
import os
|
|
|
|
def index(request):
|
|
|
|
club_id = request.GET.get('club')
|
|
future = future_tournaments(club_id)
|
|
live = live_tournaments(club_id)
|
|
finished = finished_tournaments(club_id)
|
|
|
|
club = None
|
|
if club_id:
|
|
club = get_object_or_404(Club, pk=club_id)
|
|
|
|
return render(
|
|
request,
|
|
"tournaments/tournaments.html",
|
|
{
|
|
'future': future[:10],
|
|
'live': live[:10],
|
|
'ended': finished[:10],
|
|
'club': club,
|
|
}
|
|
)
|
|
|
|
def tournaments_query(query, club_id, ascending):
|
|
queries = [query, Q(is_private=False, is_deleted=False, event__club__isnull=False)]
|
|
|
|
club = None
|
|
if club_id:
|
|
club = get_object_or_404(Club, pk=club_id)
|
|
q_club = Q(event__club=club)
|
|
queries.append(q_club)
|
|
|
|
sortkey = 'start_date'
|
|
if not ascending:
|
|
sortkey = '-start_date'
|
|
return Tournament.objects.filter(*queries).order_by(sortkey)
|
|
|
|
def finished_tournaments(club_id):
|
|
ended_tournaments = tournaments_query(Q(end_date__isnull=False), club_id, False)
|
|
return [t for t in ended_tournaments if t.display_tournament()]
|
|
|
|
def live_tournaments(club_id):
|
|
tournaments = tournaments_query(Q(end_date__isnull=True), club_id, True)
|
|
return [t for t in tournaments if t.display_tournament() and t.supposedly_in_progress()]
|
|
|
|
def future_tournaments(club_id):
|
|
tomorrow = date.today() + timedelta(days=1)
|
|
tournaments = tournaments_query(Q(end_date__isnull=True, start_date__gt=tomorrow), club_id, True)
|
|
return [t for t in tournaments if t.display_tournament()]
|
|
|
|
def tournament_info(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
return render(request, 'tournaments/tournament_info.html', {
|
|
'tournament': tournament,
|
|
})
|
|
|
|
def tournaments(request):
|
|
|
|
filter = int(request.GET.get('filter'))
|
|
club_id = request.GET.get('club')
|
|
|
|
title = ''
|
|
tournaments = []
|
|
if filter==0:
|
|
title = 'À venir'
|
|
tournaments = future_tournaments(club_id)
|
|
elif filter==1:
|
|
title = 'En cours'
|
|
tournaments = live_tournaments(club_id)
|
|
elif filter==2:
|
|
title = 'Terminés'
|
|
tournaments = finished_tournaments(club_id)
|
|
|
|
return render(
|
|
request,
|
|
"tournaments/tournaments_list.html",
|
|
{
|
|
'tournaments': tournaments,
|
|
'title': title,
|
|
'club': club_id,
|
|
}
|
|
)
|
|
|
|
def clubs(request):
|
|
clubs = Club.objects.all().order_by('name')
|
|
return render(request, 'tournaments/clubs.html', {
|
|
'clubs': clubs,
|
|
})
|
|
|
|
def club(request, club_id):
|
|
club = get_object_or_404(Club, pk=club_id)
|
|
return render(request, 'tournaments/summons.html', {
|
|
'tournament': tournament,
|
|
'team_summons': team_summons,
|
|
})
|
|
|
|
def tournament(request, tournament_id):
|
|
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
|
|
round_id = request.GET.get('round')
|
|
group_stage_id = request.GET.get('group_stage')
|
|
match_groups = tournament.match_groups(False, group_stage_id, round_id)
|
|
|
|
rounds = tournament.round_set.filter(parent=None).order_by('-index')
|
|
group_stages = tournament.groupstage_set.order_by('index')
|
|
|
|
print(len(match_groups))
|
|
print(len(rounds))
|
|
print(len(group_stages))
|
|
|
|
if tournament.display_matches():
|
|
return render(request, 'tournaments/matches.html', {
|
|
'tournament': tournament,
|
|
'rounds': rounds,
|
|
'group_stages': group_stages,
|
|
'match_groups': match_groups,
|
|
})
|
|
else:
|
|
return tournament_info(request, tournament_id)
|
|
|
|
def tournament_teams(request, tournament_id):
|
|
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
teams = tournament.teams()
|
|
|
|
return render(request, 'tournaments/teams.html', {
|
|
'tournament': tournament,
|
|
'teams': teams,
|
|
})
|
|
|
|
def tournament_summons(request, tournament_id):
|
|
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
team_summons = tournament.team_summons()
|
|
|
|
return render(request, 'tournaments/summons.html', {
|
|
'tournament': tournament,
|
|
'team_summons': team_summons,
|
|
})
|
|
|
|
def tournament_broadcasted_summons(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
return render(request, 'tournaments/broadcast/broadcasted_summons.html', {
|
|
'tournament': tournament,
|
|
'qr_code_url': qr_code_url(request, tournament_id),
|
|
'qr_code_options': qr_code_options(),
|
|
})
|
|
|
|
def tournament_summons_json(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
team_summons = [summon.to_dict() for summon in tournament.team_summons()]
|
|
data = json.dumps(team_summons)
|
|
return HttpResponse(data, content_type='application/json')
|
|
|
|
def tournament_broadcast_home(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
return render(request, 'tournaments/broadcast/broadcast.html', {
|
|
'tournament': tournament,
|
|
'qr_code_url': qr_code_url(request, tournament_id),
|
|
'qr_code_options': qr_code_options(),
|
|
})
|
|
|
|
def automatic_broadcast(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
return render(request, 'tournaments/broadcast/broadcasted_auto.html', {
|
|
'tournament': tournament,
|
|
'qr_code_url': qr_code_url(request, tournament_id),
|
|
'qr_code_options': qr_code_options(),
|
|
})
|
|
|
|
def qr_code_url(request, tournament_id):
|
|
qr_code_url = reverse('tournament', args=[tournament_id])
|
|
return request.build_absolute_uri(qr_code_url)
|
|
|
|
def qr_code_options():
|
|
return QRCodeOptions(size=10, border=4, error_correction='L')
|
|
|
|
def tournament_matches(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
return render(request, 'tournaments/broadcast/broadcasted_matches.html', {
|
|
'tournament': tournament,
|
|
'qr_code_url': qr_code_url(request, tournament_id),
|
|
'qr_code_options': qr_code_options(),
|
|
})
|
|
|
|
def broadcast_json(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
broadcast = tournament.broadcast_content()
|
|
data = json.dumps(broadcast)
|
|
return HttpResponse(data, content_type='application/json')
|
|
|
|
def tournament_matches_json(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
matches, group_stages = tournament.broadcasted_matches_and_group_stages()
|
|
live_matches = [match.live_match() for match in matches]
|
|
|
|
data = json.dumps(live_matches, default=vars)
|
|
return HttpResponse(data, content_type='application/json')
|
|
|
|
def tournament_group_stages(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
live_group_stages = list(tournament.live_group_stages())
|
|
return render(request, 'tournaments/group_stages.html', {
|
|
'tournament': tournament,
|
|
'group_stages': live_group_stages,
|
|
})
|
|
|
|
def tournament_broadcasted_group_stages(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
return render(request, 'tournaments/broadcast/broadcasted_group_stages.html', {
|
|
'tournament': tournament,
|
|
'qr_code_url': qr_code_url(request, tournament_id),
|
|
'qr_code_options': qr_code_options(),
|
|
})
|
|
|
|
def tournament_live_group_stage_json(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
|
|
gs_dicts = [gs.to_dict() for gs in tournament.live_group_stages()]
|
|
# group_stages = tournament.live_group_stages()
|
|
data = json.dumps(gs_dicts)
|
|
return HttpResponse(data, content_type='application/json')
|
|
|
|
def tournament_rankings(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
rankings = tournament.rankings()
|
|
|
|
return render(request, 'tournaments/rankings.html', {
|
|
'tournament': tournament,
|
|
'rankings': rankings,
|
|
})
|
|
|
|
def tournament_rankings_json(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
rankings = tournament.rankings()
|
|
|
|
data = json.dumps(rankings, default=vars)
|
|
return HttpResponse(data, content_type='application/json')
|
|
|
|
def tournament_broadcast_rankings(request, tournament_id):
|
|
tournament = get_object_or_404(Tournament, pk=tournament_id)
|
|
return render(request, 'tournaments/broadcast/broadcasted_rankings.html', {
|
|
'tournament': tournament,
|
|
'qr_code_url': qr_code_url(request, tournament_id),
|
|
'qr_code_options': qr_code_options(),
|
|
})
|
|
|
|
def players(request):
|
|
return render(request, 'tournaments/test.html')
|
|
|
|
def activate(request, uidb64, token):
|
|
try:
|
|
uid = force_str(urlsafe_base64_decode(uidb64))
|
|
user = CustomUser.objects.get(pk=uid)
|
|
except(TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
|
|
user = None
|
|
if user is not None and account_activation_token.check_token(user, token):
|
|
user.is_active = True
|
|
user.save()
|
|
return HttpResponse('Votre email est confirmé. Vous pouvez maintenant vous connecter.')
|
|
else:
|
|
return HttpResponse('Le lien est invalide.')
|
|
|
|
def club_broadcast(request, broadcast_code):
|
|
club = get_object_or_404(Club, broadcast_code=broadcast_code)
|
|
q_not_deleted = Q(is_deleted=False, event__club=club)
|
|
tournaments = Tournament.objects.filter(q_not_deleted).order_by('-start_date')
|
|
|
|
return render(request, 'tournaments/broadcast/broadcast_club.html', {
|
|
'club': club,
|
|
'tournaments': tournaments,
|
|
})
|
|
|
|
def download(request):
|
|
return render(request, 'tournaments/download.html')
|
|
|
|
def test_apns(request):
|
|
token = DeviceToken.objects.first()
|
|
|
|
asyncio.run(send_push_notification(token.value, 'hello!'))
|
|
|
|
return HttpResponse('OK!')
|
|
|
|
def test_websocket(request):
|
|
return render(request, 'tournaments/test_websocket.html')
|
|
|
|
def terms_of_use(request):
|
|
return render(request, 'terms_of_use.html')
|
|
|
|
import pandas as pd
|
|
from .utils.extensions import create_random_filename
|
|
|
|
@csrf_exempt
|
|
def xls_to_csv(request):
|
|
if request.method == 'POST':
|
|
# Check if the request has a file
|
|
if 'file' in request.FILES:
|
|
uploaded_file = request.FILES['file']
|
|
|
|
# Save the uploaded file
|
|
directory = 'tmp/csv/'
|
|
file_path = os.path.join(directory, uploaded_file.name)
|
|
file_name = default_storage.save(file_path, ContentFile(uploaded_file.read()))
|
|
|
|
# convert to csv and save
|
|
data_xls = pd.read_excel(file_name, 'Joueurs', index_col=None)
|
|
csv_file_name = create_random_filename('players', 'csv')
|
|
output_path = os.path.join(directory, csv_file_name)
|
|
data_xls.to_csv(output_path, encoding='utf-8')
|
|
|
|
# Send the processed file back
|
|
with default_storage.open(output_path, 'rb') as file:
|
|
response = HttpResponse(file.read(), content_type='application/octet-stream')
|
|
response['Content-Disposition'] = f'attachment; filename="players.csv"'
|
|
|
|
# Clean up: delete both files
|
|
default_storage.delete(file_name)
|
|
default_storage.delete(csv_file_name)
|
|
|
|
return response
|
|
else:
|
|
return HttpResponse("No file was uploaded", status=400)
|
|
else:
|
|
return HttpResponse("Only POST requests are allowed", status=405)
|
|
|