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.
421 lines
15 KiB
421 lines
15 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 .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, HttpResponse
|
|
from django.db.models import Q
|
|
import json
|
|
import asyncio
|
|
import csv
|
|
|
|
from api.tokens import account_activation_token
|
|
|
|
from qr_code.qrcode.utils import QRCodeOptions
|
|
from .utils.apns import send_push_notification
|
|
import os
|
|
|
|
from .forms import SimpleForm
|
|
from django.core.mail import EmailMessage
|
|
|
|
|
|
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):
|
|
all_clubs = Club.objects.all().order_by('name')
|
|
clubs = []
|
|
for club in all_clubs:
|
|
if club.events_count() > 0:
|
|
clubs.append(club)
|
|
|
|
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)
|
|
|
|
|
|
bracket_rounds = tournament.round_set.filter(parent=None, group_stage_loser_bracket=False).order_by('-index')
|
|
rounds = list(tournament.round_set.filter(group_stage_loser_bracket=True))
|
|
rounds.extend(bracket_rounds)
|
|
|
|
group_stages = tournament.groupstage_set.order_by('index')
|
|
|
|
print(len(match_groups))
|
|
print(len(rounds))
|
|
print(len(group_stages))
|
|
|
|
if tournament.display_matches() or tournament.display_group_stages():
|
|
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, sheet_name=0, 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, sep=';', index=False, 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_path)
|
|
default_storage.delete(output_path)
|
|
|
|
return response
|
|
else:
|
|
return HttpResponse("No file was uploaded", status=400)
|
|
else:
|
|
return HttpResponse("Only POST requests are allowed", status=405)
|
|
|
|
|
|
def simple_form_view(request):
|
|
|
|
if request.method == 'POST':
|
|
# If this is a POST request, we need to process the form data
|
|
form = SimpleForm(request.POST)
|
|
if form.is_valid():
|
|
# Process the data in form.cleaned_data
|
|
name = form.cleaned_data['name']
|
|
# Do something with the data (e.g., save to the database)
|
|
send_email_to_jap_list()
|
|
# send_email('laurent@staxriver.com', 'Laurent')
|
|
return HttpResponse(f"Hello, {name}!") # Simple response with name
|
|
else:
|
|
form = SimpleForm()
|
|
print(request.method)
|
|
# If this is a GET request, we display an empty form
|
|
|
|
return render(request, 'tournaments/admin/mail_test.html', {'form': form})
|
|
|
|
def send_email_to_jap_list():
|
|
|
|
# Open the CSV file
|
|
with open('tournaments/static/misc/jap-test.csv', 'r') as file:
|
|
# Create a CSV reader object
|
|
csv_reader = csv.reader(file)
|
|
|
|
# Optionally, skip the header row if your CSV has one
|
|
# next(csv_reader)
|
|
|
|
# Iterate over each row in the CSV
|
|
for row in csv_reader:
|
|
# Check if the row has at least 4 elements
|
|
if len(row) >= 4:
|
|
# Get the second and fourth values
|
|
name = row[2]
|
|
mail = row[3]
|
|
|
|
send_email(mail, name)
|
|
|
|
# Print or process these values
|
|
print(f"Name: {name}, mail: {mail}")
|
|
else:
|
|
print(f"Row doesn't have enough elements: {row}")
|
|
|
|
|
|
def send_email(mail, name):
|
|
|
|
subject = "Test mailing list!"
|
|
body = f"Salut {name},\n\nDésolé pour ce mail un peu intrusif. Je suis JAP en région PACA depuis maitenant plus d’un an. Lorsque j'ai démarré le métier je me suis retrouvé un peu sous l’eau, entre les messages d’inscriptions, la convocation des équipes, les imprévus qui cassent la structure du tournoi et bien d’autres…\nJ’ai rêvé d’avoir un outil qui me facilité la vie, et étant développeur de formation et j’ai entrepris la création d’une app pour gagner du temps. Mon app Padel Club est devenue une réalité récemment et j’aimerai évidemment le partager à tous, et aussi améliorer l’expérience joueur grâce à une information mieux partagée. \n\nJe ne te dérange pas plus longtemps, voici le lien de présentation de l’app iOS:\nhttps://padelclub.app/download/\n\nJe serai ravi d’avoir ton retour, si tu penses l’essayer, si tu penses qu’il manque quelque chose ou si quelque chose ne te convient pas. \nN’hésite pas à m’écrire ou m’appeler directement au 06 81 59 81 93."
|
|
|
|
email = EmailMessage(subject, body, to=[mail])
|
|
email.send()
|
|
|