Adds tournament cleaner tool

online_registration
Laurent 11 months ago
parent 18aa95f672
commit 6679c8e811
  1. 16
      tournaments/templates/tournaments/admin/tournament_cleaner.html
  2. 1
      tournaments/urls.py
  3. 93
      tournaments/views.py

@ -0,0 +1,16 @@
<!-- templates/admin_import.html -->
<!DOCTYPE html>
<html>
<head>
<title>Tournament Import</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="upload-zone">
<input type="file" name="tournament_zip" accept=".zip">
</div>
<button type="submit">Process Import</button>
</form>
</body>
</html>

@ -38,4 +38,5 @@ urlpatterns = [
path('terms-of-use/', views.terms_of_use, name='terms-of-use'),
path('utils/xls-to-csv/', views.xls_to_csv, name='xls-to-csv'),
path('mail-test/', views.simple_form_view, name='mail-test'),
path('admin/tournament-import/', views.tournament_import_view, name='tournament_import'),
]

@ -5,6 +5,7 @@ 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.contrib.admin.views.decorators import staff_member_required
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
@ -22,6 +23,7 @@ from django.db.models import Q
import json
import asyncio
import csv
import zipfile
from api.tokens import account_activation_token
@ -483,3 +485,94 @@ def send_email(mail, name):
email = EmailMessage(subject, body, to=[mail])
email.send()
from api.serializers import GroupStageSerializer, MatchSerializer, PlayerRegistrationSerializer, RoundSerializer, TeamRegistrationSerializer, TeamScoreSerializer
@staff_member_required
def tournament_import_view(request):
if request.method == 'POST':
zip_file = request.FILES.get('tournament_zip')
if zip_file:
try:
tournament_id = os.path.splitext(zip_file.name)[0]
tournament = Tournament.objects.get(id=tournament_id)
# Delete existing relationships
tournament.round_set.all().delete()
tournament.groupstage_set.all().delete()
tournament.teamregistration_set.all().delete()
with zipfile.ZipFile(zip_file) as z:
# First, process rounds
rounds_data = get_file_data(z, f"{tournament_id}/rounds.json")
if rounds_data:
# First pass: Create rounds without parent relationships
rounds_without_parent = []
for item in rounds_data:
item['tournament'] = tournament.id
# Temporarily remove parent field
parent = item.pop('parent', None)
rounds_without_parent.append({'data': item, 'parent': parent})
serializer = RoundSerializer(data=[item['data'] for item in rounds_without_parent], many=True)
serializer.is_valid(raise_exception=True)
created_rounds = serializer.save()
# Create a mapping of round IDs
round_mapping = {round_obj.id: round_obj for round_obj in created_rounds}
# Second pass: Update parent relationships
for round_obj, original_data in zip(created_rounds, rounds_without_parent):
if original_data['parent']:
round_obj.parent = round_mapping.get(original_data['parent'])
round_obj.save()
# Then process all other files
serializer_mapping = {
'group-stages.json': GroupStageSerializer,
'team-registrations.json': TeamRegistrationSerializer,
'matches.json': MatchSerializer,
'player-registrations.json': PlayerRegistrationSerializer,
'team-scores.json': TeamScoreSerializer
}
# Process each remaining file
for filename, serializer_class in serializer_mapping.items():
process_file(z, filename, tournament_id, tournament, serializer_class)
return JsonResponse({'status': 'success'})
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)})
else:
return render(request, 'tournaments/admin/tournament_cleaner.html')
def process_file(zip_file, filename, tournament_id, tournament, serializer_class):
"""Helper function to process individual files"""
try:
file_path = f"{tournament_id}/{filename}"
json_data = get_file_data(zip_file, file_path)
if json_data:
# Add tournament to each item
for item in json_data:
item['tournament'] = tournament.id
serializer = serializer_class(data=json_data, many=True)
serializer.is_valid(raise_exception=True)
serializer.save()
except Exception as e:
print(f"Error processing {filename}: {str(e)}")
def get_file_data(zip_file, file_path):
"""Helper function to read and parse JSON data from zip file"""
try:
file_content = zip_file.read(file_path)
return json.loads(file_content)
except KeyError:
print(f"File not found: {file_path}")
return None
except json.JSONDecodeError as e:
print(f"JSON Error for {file_path}: {str(e)}")
raise Exception(f"Invalid JSON in file {file_path}")

Loading…
Cancel
Save