diff --git a/api/serializers.py b/api/serializers.py index d5b44f3..0057fdf 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -12,6 +12,7 @@ from django.contrib.sites.shortcuts import get_current_site from api.tokens import account_activation_token from shared.cryptography import encryption_util +from tournaments.models.draw_log import DrawLog class EncryptedUserField(serializers.Field): def to_representation(self, value): @@ -230,3 +231,8 @@ class DeviceTokenSerializer(serializers.ModelSerializer): model = DeviceToken fields = '__all__' read_only_fields = ['user'] + +class DrawLogSerializer(serializers.ModelSerializer): + class Meta: + model = DrawLog + fields = '__all__' diff --git a/api/urls.py b/api/urls.py index ff61351..b221163 100644 --- a/api/urls.py +++ b/api/urls.py @@ -18,6 +18,7 @@ router.register(r'player-registrations', views.PlayerRegistrationViewSet) router.register(r'purchases', views.PurchaseViewSet) router.register(r'courts', views.CourtViewSet) router.register(r'date-intervals', views.DateIntervalViewSet) +router.register(r'draw-logs', views.DrawLogViewSet) router.register(r'failed-api-calls', views.FailedApiCallViewSet) router.register(r'logs', views.LogViewSet) router.register(r'device-token', views.DeviceTokenViewSet) diff --git a/api/views.py b/api/views.py index a8d84b5..f004f5d 100644 --- a/api/views.py +++ b/api/views.py @@ -1,5 +1,6 @@ from pandas.io.feather_format import pd -from .serializers import ClubSerializer, CourtSerializer, DateIntervalSerializer, TournamentSerializer, UserSerializer, ChangePasswordSerializer, EventSerializer, RoundSerializer, GroupStageSerializer, MatchSerializer, TeamScoreSerializer, TeamRegistrationSerializer, PlayerRegistrationSerializer, LiveMatchSerializer, PurchaseSerializer, UserUpdateSerializer, FailedApiCallSerializer, LogSerializer, DeviceTokenSerializer +from tournaments.models.draw_log import DrawLog +from .serializers import ClubSerializer, CourtSerializer, DateIntervalSerializer, DrawLogSerializer, TournamentSerializer, UserSerializer, ChangePasswordSerializer, EventSerializer, RoundSerializer, GroupStageSerializer, MatchSerializer, TeamScoreSerializer, TeamRegistrationSerializer, PlayerRegistrationSerializer, LiveMatchSerializer, PurchaseSerializer, UserUpdateSerializer, FailedApiCallSerializer, LogSerializer, DeviceTokenSerializer from tournaments.models import Club, Tournament, CustomUser, Event, Round, GroupStage, Match, TeamScore, TeamRegistration, PlayerRegistration, Court, DateInterval, Purchase, FailedApiCall, Log, DeviceToken from rest_framework import viewsets, permissions @@ -288,3 +289,15 @@ class DeviceTokenViewSet(viewsets.ModelViewSet): def perform_create(self, serializer): serializer.save(user=self.request.user) + +class DrawLogViewSet(viewsets.ModelViewSet): + queryset = DrawLog.objects.all() + serializer_class = DrawLogSerializer + + def get_queryset(self): + tournament_id = self.request.query_params.get('tournament') + if tournament_id: + return self.queryset.filter(tournament=tournament_id) + if self.request.user: + return self.queryset.filter(tournament__event__creator=self.request.user) + return [] diff --git a/tournaments/admin.py b/tournaments/admin.py index ff0fc5d..41c923f 100644 --- a/tournaments/admin.py +++ b/tournaments/admin.py @@ -2,6 +2,7 @@ from django.contrib import admin from tournaments.models import team_registration from tournaments.models.device_token import DeviceToken +from tournaments.models.draw_log import DrawLog from .models import Club, TeamScore, Tournament, CustomUser, Event, Round, GroupStage, Match, TeamRegistration, PlayerRegistration, Purchase, Court, DateInterval, FailedApiCall, Log from django.contrib.auth.admin import UserAdmin @@ -105,6 +106,11 @@ class LogAdmin(admin.ModelAdmin): class DeviceTokenAdmin(admin.ModelAdmin): list_display = ['user', 'value'] +class DrawLogAdmin(admin.ModelAdmin): + list_display = ['tournament', 'draw_date', 'draw_seed', 'draw_match_index', 'draw_team_position'] + list_filter = [SimpleTournamentListFilter] + ordering = ['draw_date'] + admin.site.register(CustomUser, CustomUserAdmin) admin.site.register(Club, ClubAdmin) admin.site.register(Event, EventAdmin) @@ -121,3 +127,4 @@ admin.site.register(DateInterval, DateIntervalAdmin) admin.site.register(FailedApiCall, FailedApiCallAdmin) admin.site.register(Log, LogAdmin) admin.site.register(DeviceToken, DeviceTokenAdmin) +admin.site.register(DrawLog, DrawLogAdmin) diff --git a/tournaments/migrations/0091_drawlog.py b/tournaments/migrations/0091_drawlog.py new file mode 100644 index 0000000..285b871 --- /dev/null +++ b/tournaments/migrations/0091_drawlog.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.11 on 2024-10-24 06:55 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('tournaments', '0090_tournament_initial_seed_count_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='DrawLog', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('draw_date', models.DateTimeField()), + ('draw_seed', models.IntegerField()), + ('draw_match_index', models.IntegerField()), + ('draw_team_position', models.IntegerField()), + ('tournament', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.tournament')), + ], + ), + ] diff --git a/tournaments/migrations/0092_club_timezone.py b/tournaments/migrations/0092_club_timezone.py new file mode 100644 index 0000000..7fb0045 --- /dev/null +++ b/tournaments/migrations/0092_club_timezone.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1 on 2024-10-24 12:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tournaments', '0091_drawlog'), + ] + + operations = [ + migrations.AddField( + model_name='club', + name='timezone', + field=models.CharField(blank=True, choices=[('Africa/Abidjan', 'Africa/Abidjan'), ('Africa/Accra', 'Africa/Accra'), ('Africa/Addis_Ababa', 'Africa/Addis_Ababa'), ('Africa/Algiers', 'Africa/Algiers'), ('Africa/Asmara', 'Africa/Asmara'), ('Africa/Asmera', 'Africa/Asmera'), ('Africa/Bamako', 'Africa/Bamako'), ('Africa/Bangui', 'Africa/Bangui'), ('Africa/Banjul', 'Africa/Banjul'), ('Africa/Bissau', 'Africa/Bissau'), ('Africa/Blantyre', 'Africa/Blantyre'), ('Africa/Brazzaville', 'Africa/Brazzaville'), ('Africa/Bujumbura', 'Africa/Bujumbura'), ('Africa/Cairo', 'Africa/Cairo'), ('Africa/Casablanca', 'Africa/Casablanca'), ('Africa/Ceuta', 'Africa/Ceuta'), ('Africa/Conakry', 'Africa/Conakry'), ('Africa/Dakar', 'Africa/Dakar'), ('Africa/Dar_es_Salaam', 'Africa/Dar_es_Salaam'), ('Africa/Djibouti', 'Africa/Djibouti'), ('Africa/Douala', 'Africa/Douala'), ('Africa/El_Aaiun', 'Africa/El_Aaiun'), ('Africa/Freetown', 'Africa/Freetown'), ('Africa/Gaborone', 'Africa/Gaborone'), ('Africa/Harare', 'Africa/Harare'), ('Africa/Johannesburg', 'Africa/Johannesburg'), ('Africa/Juba', 'Africa/Juba'), ('Africa/Kampala', 'Africa/Kampala'), ('Africa/Khartoum', 'Africa/Khartoum'), ('Africa/Kigali', 'Africa/Kigali'), ('Africa/Kinshasa', 'Africa/Kinshasa'), ('Africa/Lagos', 'Africa/Lagos'), ('Africa/Libreville', 'Africa/Libreville'), ('Africa/Lome', 'Africa/Lome'), ('Africa/Luanda', 'Africa/Luanda'), ('Africa/Lubumbashi', 'Africa/Lubumbashi'), ('Africa/Lusaka', 'Africa/Lusaka'), ('Africa/Malabo', 'Africa/Malabo'), ('Africa/Maputo', 'Africa/Maputo'), ('Africa/Maseru', 'Africa/Maseru'), ('Africa/Mbabane', 'Africa/Mbabane'), ('Africa/Mogadishu', 'Africa/Mogadishu'), ('Africa/Monrovia', 'Africa/Monrovia'), ('Africa/Nairobi', 'Africa/Nairobi'), ('Africa/Ndjamena', 'Africa/Ndjamena'), ('Africa/Niamey', 'Africa/Niamey'), ('Africa/Nouakchott', 'Africa/Nouakchott'), ('Africa/Ouagadougou', 'Africa/Ouagadougou'), ('Africa/Porto-Novo', 'Africa/Porto-Novo'), ('Africa/Sao_Tome', 'Africa/Sao_Tome'), ('Africa/Timbuktu', 'Africa/Timbuktu'), ('Africa/Tripoli', 'Africa/Tripoli'), ('Africa/Tunis', 'Africa/Tunis'), ('Africa/Windhoek', 'Africa/Windhoek'), ('America/Adak', 'America/Adak'), ('America/Anchorage', 'America/Anchorage'), ('America/Anguilla', 'America/Anguilla'), ('America/Antigua', 'America/Antigua'), ('America/Araguaina', 'America/Araguaina'), ('America/Argentina/Buenos_Aires', 'America/Argentina/Buenos_Aires'), ('America/Argentina/Catamarca', 'America/Argentina/Catamarca'), ('America/Argentina/ComodRivadavia', 'America/Argentina/ComodRivadavia'), ('America/Argentina/Cordoba', 'America/Argentina/Cordoba'), ('America/Argentina/Jujuy', 'America/Argentina/Jujuy'), ('America/Argentina/La_Rioja', 'America/Argentina/La_Rioja'), ('America/Argentina/Mendoza', 'America/Argentina/Mendoza'), ('America/Argentina/Rio_Gallegos', 'America/Argentina/Rio_Gallegos'), ('America/Argentina/Salta', 'America/Argentina/Salta'), ('America/Argentina/San_Juan', 'America/Argentina/San_Juan'), ('America/Argentina/San_Luis', 'America/Argentina/San_Luis'), ('America/Argentina/Tucuman', 'America/Argentina/Tucuman'), ('America/Argentina/Ushuaia', 'America/Argentina/Ushuaia'), ('America/Aruba', 'America/Aruba'), ('America/Asuncion', 'America/Asuncion'), ('America/Atikokan', 'America/Atikokan'), ('America/Atka', 'America/Atka'), ('America/Bahia', 'America/Bahia'), ('America/Bahia_Banderas', 'America/Bahia_Banderas'), ('America/Barbados', 'America/Barbados'), ('America/Belem', 'America/Belem'), ('America/Belize', 'America/Belize'), ('America/Blanc-Sablon', 'America/Blanc-Sablon'), ('America/Boa_Vista', 'America/Boa_Vista'), ('America/Bogota', 'America/Bogota'), ('America/Boise', 'America/Boise'), ('America/Buenos_Aires', 'America/Buenos_Aires'), ('America/Cambridge_Bay', 'America/Cambridge_Bay'), ('America/Campo_Grande', 'America/Campo_Grande'), ('America/Cancun', 'America/Cancun'), ('America/Caracas', 'America/Caracas'), ('America/Catamarca', 'America/Catamarca'), ('America/Cayenne', 'America/Cayenne'), ('America/Cayman', 'America/Cayman'), ('America/Chicago', 'America/Chicago'), ('America/Chihuahua', 'America/Chihuahua'), ('America/Ciudad_Juarez', 'America/Ciudad_Juarez'), ('America/Coral_Harbour', 'America/Coral_Harbour'), ('America/Cordoba', 'America/Cordoba'), ('America/Costa_Rica', 'America/Costa_Rica'), ('America/Creston', 'America/Creston'), ('America/Cuiaba', 'America/Cuiaba'), ('America/Curacao', 'America/Curacao'), ('America/Danmarkshavn', 'America/Danmarkshavn'), ('America/Dawson', 'America/Dawson'), ('America/Dawson_Creek', 'America/Dawson_Creek'), ('America/Denver', 'America/Denver'), ('America/Detroit', 'America/Detroit'), ('America/Dominica', 'America/Dominica'), ('America/Edmonton', 'America/Edmonton'), ('America/Eirunepe', 'America/Eirunepe'), ('America/El_Salvador', 'America/El_Salvador'), ('America/Ensenada', 'America/Ensenada'), ('America/Fort_Nelson', 'America/Fort_Nelson'), ('America/Fort_Wayne', 'America/Fort_Wayne'), ('America/Fortaleza', 'America/Fortaleza'), ('America/Glace_Bay', 'America/Glace_Bay'), ('America/Godthab', 'America/Godthab'), ('America/Goose_Bay', 'America/Goose_Bay'), ('America/Grand_Turk', 'America/Grand_Turk'), ('America/Grenada', 'America/Grenada'), ('America/Guadeloupe', 'America/Guadeloupe'), ('America/Guatemala', 'America/Guatemala'), ('America/Guayaquil', 'America/Guayaquil'), ('America/Guyana', 'America/Guyana'), ('America/Halifax', 'America/Halifax'), ('America/Havana', 'America/Havana'), ('America/Hermosillo', 'America/Hermosillo'), ('America/Indiana/Indianapolis', 'America/Indiana/Indianapolis'), ('America/Indiana/Knox', 'America/Indiana/Knox'), ('America/Indiana/Marengo', 'America/Indiana/Marengo'), ('America/Indiana/Petersburg', 'America/Indiana/Petersburg'), ('America/Indiana/Tell_City', 'America/Indiana/Tell_City'), ('America/Indiana/Vevay', 'America/Indiana/Vevay'), ('America/Indiana/Vincennes', 'America/Indiana/Vincennes'), ('America/Indiana/Winamac', 'America/Indiana/Winamac'), ('America/Indianapolis', 'America/Indianapolis'), ('America/Inuvik', 'America/Inuvik'), ('America/Iqaluit', 'America/Iqaluit'), ('America/Jamaica', 'America/Jamaica'), ('America/Jujuy', 'America/Jujuy'), ('America/Juneau', 'America/Juneau'), ('America/Kentucky/Louisville', 'America/Kentucky/Louisville'), ('America/Kentucky/Monticello', 'America/Kentucky/Monticello'), ('America/Knox_IN', 'America/Knox_IN'), ('America/Kralendijk', 'America/Kralendijk'), ('America/La_Paz', 'America/La_Paz'), ('America/Lima', 'America/Lima'), ('America/Los_Angeles', 'America/Los_Angeles'), ('America/Louisville', 'America/Louisville'), ('America/Lower_Princes', 'America/Lower_Princes'), ('America/Maceio', 'America/Maceio'), ('America/Managua', 'America/Managua'), ('America/Manaus', 'America/Manaus'), ('America/Marigot', 'America/Marigot'), ('America/Martinique', 'America/Martinique'), ('America/Matamoros', 'America/Matamoros'), ('America/Mazatlan', 'America/Mazatlan'), ('America/Mendoza', 'America/Mendoza'), ('America/Menominee', 'America/Menominee'), ('America/Merida', 'America/Merida'), ('America/Metlakatla', 'America/Metlakatla'), ('America/Mexico_City', 'America/Mexico_City'), ('America/Miquelon', 'America/Miquelon'), ('America/Moncton', 'America/Moncton'), ('America/Monterrey', 'America/Monterrey'), ('America/Montevideo', 'America/Montevideo'), ('America/Montreal', 'America/Montreal'), ('America/Montserrat', 'America/Montserrat'), ('America/Nassau', 'America/Nassau'), ('America/New_York', 'America/New_York'), ('America/Nipigon', 'America/Nipigon'), ('America/Nome', 'America/Nome'), ('America/Noronha', 'America/Noronha'), ('America/North_Dakota/Beulah', 'America/North_Dakota/Beulah'), ('America/North_Dakota/Center', 'America/North_Dakota/Center'), ('America/North_Dakota/New_Salem', 'America/North_Dakota/New_Salem'), ('America/Nuuk', 'America/Nuuk'), ('America/Ojinaga', 'America/Ojinaga'), ('America/Panama', 'America/Panama'), ('America/Pangnirtung', 'America/Pangnirtung'), ('America/Paramaribo', 'America/Paramaribo'), ('America/Phoenix', 'America/Phoenix'), ('America/Port-au-Prince', 'America/Port-au-Prince'), ('America/Port_of_Spain', 'America/Port_of_Spain'), ('America/Porto_Acre', 'America/Porto_Acre'), ('America/Porto_Velho', 'America/Porto_Velho'), ('America/Puerto_Rico', 'America/Puerto_Rico'), ('America/Punta_Arenas', 'America/Punta_Arenas'), ('America/Rainy_River', 'America/Rainy_River'), ('America/Rankin_Inlet', 'America/Rankin_Inlet'), ('America/Recife', 'America/Recife'), ('America/Regina', 'America/Regina'), ('America/Resolute', 'America/Resolute'), ('America/Rio_Branco', 'America/Rio_Branco'), ('America/Rosario', 'America/Rosario'), ('America/Santa_Isabel', 'America/Santa_Isabel'), ('America/Santarem', 'America/Santarem'), ('America/Santiago', 'America/Santiago'), ('America/Santo_Domingo', 'America/Santo_Domingo'), ('America/Sao_Paulo', 'America/Sao_Paulo'), ('America/Scoresbysund', 'America/Scoresbysund'), ('America/Shiprock', 'America/Shiprock'), ('America/Sitka', 'America/Sitka'), ('America/St_Barthelemy', 'America/St_Barthelemy'), ('America/St_Johns', 'America/St_Johns'), ('America/St_Kitts', 'America/St_Kitts'), ('America/St_Lucia', 'America/St_Lucia'), ('America/St_Thomas', 'America/St_Thomas'), ('America/St_Vincent', 'America/St_Vincent'), ('America/Swift_Current', 'America/Swift_Current'), ('America/Tegucigalpa', 'America/Tegucigalpa'), ('America/Thule', 'America/Thule'), ('America/Thunder_Bay', 'America/Thunder_Bay'), ('America/Tijuana', 'America/Tijuana'), ('America/Toronto', 'America/Toronto'), ('America/Tortola', 'America/Tortola'), ('America/Vancouver', 'America/Vancouver'), ('America/Virgin', 'America/Virgin'), ('America/Whitehorse', 'America/Whitehorse'), ('America/Winnipeg', 'America/Winnipeg'), ('America/Yakutat', 'America/Yakutat'), ('America/Yellowknife', 'America/Yellowknife'), ('Antarctica/Casey', 'Antarctica/Casey'), ('Antarctica/Davis', 'Antarctica/Davis'), ('Antarctica/DumontDUrville', 'Antarctica/DumontDUrville'), ('Antarctica/Macquarie', 'Antarctica/Macquarie'), ('Antarctica/Mawson', 'Antarctica/Mawson'), ('Antarctica/McMurdo', 'Antarctica/McMurdo'), ('Antarctica/Palmer', 'Antarctica/Palmer'), ('Antarctica/Rothera', 'Antarctica/Rothera'), ('Antarctica/South_Pole', 'Antarctica/South_Pole'), ('Antarctica/Syowa', 'Antarctica/Syowa'), ('Antarctica/Troll', 'Antarctica/Troll'), ('Antarctica/Vostok', 'Antarctica/Vostok'), ('Arctic/Longyearbyen', 'Arctic/Longyearbyen'), ('Asia/Aden', 'Asia/Aden'), ('Asia/Almaty', 'Asia/Almaty'), ('Asia/Amman', 'Asia/Amman'), ('Asia/Anadyr', 'Asia/Anadyr'), ('Asia/Aqtau', 'Asia/Aqtau'), ('Asia/Aqtobe', 'Asia/Aqtobe'), ('Asia/Ashgabat', 'Asia/Ashgabat'), ('Asia/Ashkhabad', 'Asia/Ashkhabad'), ('Asia/Atyrau', 'Asia/Atyrau'), ('Asia/Baghdad', 'Asia/Baghdad'), ('Asia/Bahrain', 'Asia/Bahrain'), ('Asia/Baku', 'Asia/Baku'), ('Asia/Bangkok', 'Asia/Bangkok'), ('Asia/Barnaul', 'Asia/Barnaul'), ('Asia/Beirut', 'Asia/Beirut'), ('Asia/Bishkek', 'Asia/Bishkek'), ('Asia/Brunei', 'Asia/Brunei'), ('Asia/Calcutta', 'Asia/Calcutta'), ('Asia/Chita', 'Asia/Chita'), ('Asia/Choibalsan', 'Asia/Choibalsan'), ('Asia/Chongqing', 'Asia/Chongqing'), ('Asia/Chungking', 'Asia/Chungking'), ('Asia/Colombo', 'Asia/Colombo'), ('Asia/Dacca', 'Asia/Dacca'), ('Asia/Damascus', 'Asia/Damascus'), ('Asia/Dhaka', 'Asia/Dhaka'), ('Asia/Dili', 'Asia/Dili'), ('Asia/Dubai', 'Asia/Dubai'), ('Asia/Dushanbe', 'Asia/Dushanbe'), ('Asia/Famagusta', 'Asia/Famagusta'), ('Asia/Gaza', 'Asia/Gaza'), ('Asia/Harbin', 'Asia/Harbin'), ('Asia/Hebron', 'Asia/Hebron'), ('Asia/Ho_Chi_Minh', 'Asia/Ho_Chi_Minh'), ('Asia/Hong_Kong', 'Asia/Hong_Kong'), ('Asia/Hovd', 'Asia/Hovd'), ('Asia/Irkutsk', 'Asia/Irkutsk'), ('Asia/Istanbul', 'Asia/Istanbul'), ('Asia/Jakarta', 'Asia/Jakarta'), ('Asia/Jayapura', 'Asia/Jayapura'), ('Asia/Jerusalem', 'Asia/Jerusalem'), ('Asia/Kabul', 'Asia/Kabul'), ('Asia/Kamchatka', 'Asia/Kamchatka'), ('Asia/Karachi', 'Asia/Karachi'), ('Asia/Kashgar', 'Asia/Kashgar'), ('Asia/Kathmandu', 'Asia/Kathmandu'), ('Asia/Katmandu', 'Asia/Katmandu'), ('Asia/Khandyga', 'Asia/Khandyga'), ('Asia/Kolkata', 'Asia/Kolkata'), ('Asia/Krasnoyarsk', 'Asia/Krasnoyarsk'), ('Asia/Kuala_Lumpur', 'Asia/Kuala_Lumpur'), ('Asia/Kuching', 'Asia/Kuching'), ('Asia/Kuwait', 'Asia/Kuwait'), ('Asia/Macao', 'Asia/Macao'), ('Asia/Macau', 'Asia/Macau'), ('Asia/Magadan', 'Asia/Magadan'), ('Asia/Makassar', 'Asia/Makassar'), ('Asia/Manila', 'Asia/Manila'), ('Asia/Muscat', 'Asia/Muscat'), ('Asia/Nicosia', 'Asia/Nicosia'), ('Asia/Novokuznetsk', 'Asia/Novokuznetsk'), ('Asia/Novosibirsk', 'Asia/Novosibirsk'), ('Asia/Omsk', 'Asia/Omsk'), ('Asia/Oral', 'Asia/Oral'), ('Asia/Phnom_Penh', 'Asia/Phnom_Penh'), ('Asia/Pontianak', 'Asia/Pontianak'), ('Asia/Pyongyang', 'Asia/Pyongyang'), ('Asia/Qatar', 'Asia/Qatar'), ('Asia/Qostanay', 'Asia/Qostanay'), ('Asia/Qyzylorda', 'Asia/Qyzylorda'), ('Asia/Rangoon', 'Asia/Rangoon'), ('Asia/Riyadh', 'Asia/Riyadh'), ('Asia/Saigon', 'Asia/Saigon'), ('Asia/Sakhalin', 'Asia/Sakhalin'), ('Asia/Samarkand', 'Asia/Samarkand'), ('Asia/Seoul', 'Asia/Seoul'), ('Asia/Shanghai', 'Asia/Shanghai'), ('Asia/Singapore', 'Asia/Singapore'), ('Asia/Srednekolymsk', 'Asia/Srednekolymsk'), ('Asia/Taipei', 'Asia/Taipei'), ('Asia/Tashkent', 'Asia/Tashkent'), ('Asia/Tbilisi', 'Asia/Tbilisi'), ('Asia/Tehran', 'Asia/Tehran'), ('Asia/Tel_Aviv', 'Asia/Tel_Aviv'), ('Asia/Thimbu', 'Asia/Thimbu'), ('Asia/Thimphu', 'Asia/Thimphu'), ('Asia/Tokyo', 'Asia/Tokyo'), ('Asia/Tomsk', 'Asia/Tomsk'), ('Asia/Ujung_Pandang', 'Asia/Ujung_Pandang'), ('Asia/Ulaanbaatar', 'Asia/Ulaanbaatar'), ('Asia/Ulan_Bator', 'Asia/Ulan_Bator'), ('Asia/Urumqi', 'Asia/Urumqi'), ('Asia/Ust-Nera', 'Asia/Ust-Nera'), ('Asia/Vientiane', 'Asia/Vientiane'), ('Asia/Vladivostok', 'Asia/Vladivostok'), ('Asia/Yakutsk', 'Asia/Yakutsk'), ('Asia/Yangon', 'Asia/Yangon'), ('Asia/Yekaterinburg', 'Asia/Yekaterinburg'), ('Asia/Yerevan', 'Asia/Yerevan'), ('Atlantic/Azores', 'Atlantic/Azores'), ('Atlantic/Bermuda', 'Atlantic/Bermuda'), ('Atlantic/Canary', 'Atlantic/Canary'), ('Atlantic/Cape_Verde', 'Atlantic/Cape_Verde'), ('Atlantic/Faeroe', 'Atlantic/Faeroe'), ('Atlantic/Faroe', 'Atlantic/Faroe'), ('Atlantic/Jan_Mayen', 'Atlantic/Jan_Mayen'), ('Atlantic/Madeira', 'Atlantic/Madeira'), ('Atlantic/Reykjavik', 'Atlantic/Reykjavik'), ('Atlantic/South_Georgia', 'Atlantic/South_Georgia'), ('Atlantic/St_Helena', 'Atlantic/St_Helena'), ('Atlantic/Stanley', 'Atlantic/Stanley'), ('Australia/ACT', 'Australia/ACT'), ('Australia/Adelaide', 'Australia/Adelaide'), ('Australia/Brisbane', 'Australia/Brisbane'), ('Australia/Broken_Hill', 'Australia/Broken_Hill'), ('Australia/Canberra', 'Australia/Canberra'), ('Australia/Currie', 'Australia/Currie'), ('Australia/Darwin', 'Australia/Darwin'), ('Australia/Eucla', 'Australia/Eucla'), ('Australia/Hobart', 'Australia/Hobart'), ('Australia/LHI', 'Australia/LHI'), ('Australia/Lindeman', 'Australia/Lindeman'), ('Australia/Lord_Howe', 'Australia/Lord_Howe'), ('Australia/Melbourne', 'Australia/Melbourne'), ('Australia/NSW', 'Australia/NSW'), ('Australia/North', 'Australia/North'), ('Australia/Perth', 'Australia/Perth'), ('Australia/Queensland', 'Australia/Queensland'), ('Australia/South', 'Australia/South'), ('Australia/Sydney', 'Australia/Sydney'), ('Australia/Tasmania', 'Australia/Tasmania'), ('Australia/Victoria', 'Australia/Victoria'), ('Australia/West', 'Australia/West'), ('Australia/Yancowinna', 'Australia/Yancowinna'), ('Brazil/Acre', 'Brazil/Acre'), ('Brazil/DeNoronha', 'Brazil/DeNoronha'), ('Brazil/East', 'Brazil/East'), ('Brazil/West', 'Brazil/West'), ('CET', 'CET'), ('CST6CDT', 'CST6CDT'), ('Canada/Atlantic', 'Canada/Atlantic'), ('Canada/Central', 'Canada/Central'), ('Canada/Eastern', 'Canada/Eastern'), ('Canada/Mountain', 'Canada/Mountain'), ('Canada/Newfoundland', 'Canada/Newfoundland'), ('Canada/Pacific', 'Canada/Pacific'), ('Canada/Saskatchewan', 'Canada/Saskatchewan'), ('Canada/Yukon', 'Canada/Yukon'), ('Chile/Continental', 'Chile/Continental'), ('Chile/EasterIsland', 'Chile/EasterIsland'), ('Cuba', 'Cuba'), ('EET', 'EET'), ('EST', 'EST'), ('EST5EDT', 'EST5EDT'), ('Egypt', 'Egypt'), ('Eire', 'Eire'), ('Etc/GMT', 'Etc/GMT'), ('Etc/GMT+0', 'Etc/GMT+0'), ('Etc/GMT+1', 'Etc/GMT+1'), ('Etc/GMT+10', 'Etc/GMT+10'), ('Etc/GMT+11', 'Etc/GMT+11'), ('Etc/GMT+12', 'Etc/GMT+12'), ('Etc/GMT+2', 'Etc/GMT+2'), ('Etc/GMT+3', 'Etc/GMT+3'), ('Etc/GMT+4', 'Etc/GMT+4'), ('Etc/GMT+5', 'Etc/GMT+5'), ('Etc/GMT+6', 'Etc/GMT+6'), ('Etc/GMT+7', 'Etc/GMT+7'), ('Etc/GMT+8', 'Etc/GMT+8'), ('Etc/GMT+9', 'Etc/GMT+9'), ('Etc/GMT-0', 'Etc/GMT-0'), ('Etc/GMT-1', 'Etc/GMT-1'), ('Etc/GMT-10', 'Etc/GMT-10'), ('Etc/GMT-11', 'Etc/GMT-11'), ('Etc/GMT-12', 'Etc/GMT-12'), ('Etc/GMT-13', 'Etc/GMT-13'), ('Etc/GMT-14', 'Etc/GMT-14'), ('Etc/GMT-2', 'Etc/GMT-2'), ('Etc/GMT-3', 'Etc/GMT-3'), ('Etc/GMT-4', 'Etc/GMT-4'), ('Etc/GMT-5', 'Etc/GMT-5'), ('Etc/GMT-6', 'Etc/GMT-6'), ('Etc/GMT-7', 'Etc/GMT-7'), ('Etc/GMT-8', 'Etc/GMT-8'), ('Etc/GMT-9', 'Etc/GMT-9'), ('Etc/GMT0', 'Etc/GMT0'), ('Etc/Greenwich', 'Etc/Greenwich'), ('Etc/UCT', 'Etc/UCT'), ('Etc/UTC', 'Etc/UTC'), ('Etc/Universal', 'Etc/Universal'), ('Etc/Zulu', 'Etc/Zulu'), ('Europe/Amsterdam', 'Europe/Amsterdam'), ('Europe/Andorra', 'Europe/Andorra'), ('Europe/Astrakhan', 'Europe/Astrakhan'), ('Europe/Athens', 'Europe/Athens'), ('Europe/Belfast', 'Europe/Belfast'), ('Europe/Belgrade', 'Europe/Belgrade'), ('Europe/Berlin', 'Europe/Berlin'), ('Europe/Bratislava', 'Europe/Bratislava'), ('Europe/Brussels', 'Europe/Brussels'), ('Europe/Bucharest', 'Europe/Bucharest'), ('Europe/Budapest', 'Europe/Budapest'), ('Europe/Busingen', 'Europe/Busingen'), ('Europe/Chisinau', 'Europe/Chisinau'), ('Europe/Copenhagen', 'Europe/Copenhagen'), ('Europe/Dublin', 'Europe/Dublin'), ('Europe/Gibraltar', 'Europe/Gibraltar'), ('Europe/Guernsey', 'Europe/Guernsey'), ('Europe/Helsinki', 'Europe/Helsinki'), ('Europe/Isle_of_Man', 'Europe/Isle_of_Man'), ('Europe/Istanbul', 'Europe/Istanbul'), ('Europe/Jersey', 'Europe/Jersey'), ('Europe/Kaliningrad', 'Europe/Kaliningrad'), ('Europe/Kiev', 'Europe/Kiev'), ('Europe/Kirov', 'Europe/Kirov'), ('Europe/Kyiv', 'Europe/Kyiv'), ('Europe/Lisbon', 'Europe/Lisbon'), ('Europe/Ljubljana', 'Europe/Ljubljana'), ('Europe/London', 'Europe/London'), ('Europe/Luxembourg', 'Europe/Luxembourg'), ('Europe/Madrid', 'Europe/Madrid'), ('Europe/Malta', 'Europe/Malta'), ('Europe/Mariehamn', 'Europe/Mariehamn'), ('Europe/Minsk', 'Europe/Minsk'), ('Europe/Monaco', 'Europe/Monaco'), ('Europe/Moscow', 'Europe/Moscow'), ('Europe/Nicosia', 'Europe/Nicosia'), ('Europe/Oslo', 'Europe/Oslo'), ('Europe/Paris', 'Europe/Paris'), ('Europe/Podgorica', 'Europe/Podgorica'), ('Europe/Prague', 'Europe/Prague'), ('Europe/Riga', 'Europe/Riga'), ('Europe/Rome', 'Europe/Rome'), ('Europe/Samara', 'Europe/Samara'), ('Europe/San_Marino', 'Europe/San_Marino'), ('Europe/Sarajevo', 'Europe/Sarajevo'), ('Europe/Saratov', 'Europe/Saratov'), ('Europe/Simferopol', 'Europe/Simferopol'), ('Europe/Skopje', 'Europe/Skopje'), ('Europe/Sofia', 'Europe/Sofia'), ('Europe/Stockholm', 'Europe/Stockholm'), ('Europe/Tallinn', 'Europe/Tallinn'), ('Europe/Tirane', 'Europe/Tirane'), ('Europe/Tiraspol', 'Europe/Tiraspol'), ('Europe/Ulyanovsk', 'Europe/Ulyanovsk'), ('Europe/Uzhgorod', 'Europe/Uzhgorod'), ('Europe/Vaduz', 'Europe/Vaduz'), ('Europe/Vatican', 'Europe/Vatican'), ('Europe/Vienna', 'Europe/Vienna'), ('Europe/Vilnius', 'Europe/Vilnius'), ('Europe/Volgograd', 'Europe/Volgograd'), ('Europe/Warsaw', 'Europe/Warsaw'), ('Europe/Zagreb', 'Europe/Zagreb'), ('Europe/Zaporozhye', 'Europe/Zaporozhye'), ('Europe/Zurich', 'Europe/Zurich'), ('Factory', 'Factory'), ('GB', 'GB'), ('GB-Eire', 'GB-Eire'), ('GMT', 'GMT'), ('GMT+0', 'GMT+0'), ('GMT-0', 'GMT-0'), ('GMT0', 'GMT0'), ('Greenwich', 'Greenwich'), ('HST', 'HST'), ('Hongkong', 'Hongkong'), ('Iceland', 'Iceland'), ('Indian/Antananarivo', 'Indian/Antananarivo'), ('Indian/Chagos', 'Indian/Chagos'), ('Indian/Christmas', 'Indian/Christmas'), ('Indian/Cocos', 'Indian/Cocos'), ('Indian/Comoro', 'Indian/Comoro'), ('Indian/Kerguelen', 'Indian/Kerguelen'), ('Indian/Mahe', 'Indian/Mahe'), ('Indian/Maldives', 'Indian/Maldives'), ('Indian/Mauritius', 'Indian/Mauritius'), ('Indian/Mayotte', 'Indian/Mayotte'), ('Indian/Reunion', 'Indian/Reunion'), ('Iran', 'Iran'), ('Israel', 'Israel'), ('Jamaica', 'Jamaica'), ('Japan', 'Japan'), ('Kwajalein', 'Kwajalein'), ('Libya', 'Libya'), ('MET', 'MET'), ('MST', 'MST'), ('MST7MDT', 'MST7MDT'), ('Mexico/BajaNorte', 'Mexico/BajaNorte'), ('Mexico/BajaSur', 'Mexico/BajaSur'), ('Mexico/General', 'Mexico/General'), ('NZ', 'NZ'), ('NZ-CHAT', 'NZ-CHAT'), ('Navajo', 'Navajo'), ('PRC', 'PRC'), ('PST8PDT', 'PST8PDT'), ('Pacific/Apia', 'Pacific/Apia'), ('Pacific/Auckland', 'Pacific/Auckland'), ('Pacific/Bougainville', 'Pacific/Bougainville'), ('Pacific/Chatham', 'Pacific/Chatham'), ('Pacific/Chuuk', 'Pacific/Chuuk'), ('Pacific/Easter', 'Pacific/Easter'), ('Pacific/Efate', 'Pacific/Efate'), ('Pacific/Enderbury', 'Pacific/Enderbury'), ('Pacific/Fakaofo', 'Pacific/Fakaofo'), ('Pacific/Fiji', 'Pacific/Fiji'), ('Pacific/Funafuti', 'Pacific/Funafuti'), ('Pacific/Galapagos', 'Pacific/Galapagos'), ('Pacific/Gambier', 'Pacific/Gambier'), ('Pacific/Guadalcanal', 'Pacific/Guadalcanal'), ('Pacific/Guam', 'Pacific/Guam'), ('Pacific/Honolulu', 'Pacific/Honolulu'), ('Pacific/Johnston', 'Pacific/Johnston'), ('Pacific/Kanton', 'Pacific/Kanton'), ('Pacific/Kiritimati', 'Pacific/Kiritimati'), ('Pacific/Kosrae', 'Pacific/Kosrae'), ('Pacific/Kwajalein', 'Pacific/Kwajalein'), ('Pacific/Majuro', 'Pacific/Majuro'), ('Pacific/Marquesas', 'Pacific/Marquesas'), ('Pacific/Midway', 'Pacific/Midway'), ('Pacific/Nauru', 'Pacific/Nauru'), ('Pacific/Niue', 'Pacific/Niue'), ('Pacific/Norfolk', 'Pacific/Norfolk'), ('Pacific/Noumea', 'Pacific/Noumea'), ('Pacific/Pago_Pago', 'Pacific/Pago_Pago'), ('Pacific/Palau', 'Pacific/Palau'), ('Pacific/Pitcairn', 'Pacific/Pitcairn'), ('Pacific/Pohnpei', 'Pacific/Pohnpei'), ('Pacific/Ponape', 'Pacific/Ponape'), ('Pacific/Port_Moresby', 'Pacific/Port_Moresby'), ('Pacific/Rarotonga', 'Pacific/Rarotonga'), ('Pacific/Saipan', 'Pacific/Saipan'), ('Pacific/Samoa', 'Pacific/Samoa'), ('Pacific/Tahiti', 'Pacific/Tahiti'), ('Pacific/Tarawa', 'Pacific/Tarawa'), ('Pacific/Tongatapu', 'Pacific/Tongatapu'), ('Pacific/Truk', 'Pacific/Truk'), ('Pacific/Wake', 'Pacific/Wake'), ('Pacific/Wallis', 'Pacific/Wallis'), ('Pacific/Yap', 'Pacific/Yap'), ('Poland', 'Poland'), ('Portugal', 'Portugal'), ('ROC', 'ROC'), ('ROK', 'ROK'), ('Singapore', 'Singapore'), ('Turkey', 'Turkey'), ('UCT', 'UCT'), ('US/Alaska', 'US/Alaska'), ('US/Aleutian', 'US/Aleutian'), ('US/Arizona', 'US/Arizona'), ('US/Central', 'US/Central'), ('US/East-Indiana', 'US/East-Indiana'), ('US/Eastern', 'US/Eastern'), ('US/Hawaii', 'US/Hawaii'), ('US/Indiana-Starke', 'US/Indiana-Starke'), ('US/Michigan', 'US/Michigan'), ('US/Mountain', 'US/Mountain'), ('US/Pacific', 'US/Pacific'), ('US/Samoa', 'US/Samoa'), ('UTC', 'UTC'), ('Universal', 'Universal'), ('W-SU', 'W-SU'), ('WET', 'WET'), ('Zulu', 'Zulu')], default='CET', max_length=50, null=True), + ), + ] diff --git a/tournaments/models/club.py b/tournaments/models/club.py index d2b2f29..0d62c18 100644 --- a/tournaments/models/club.py +++ b/tournaments/models/club.py @@ -1,4 +1,5 @@ from django.db import models +from zoneinfo import available_timezones import uuid class Club(models.Model): @@ -15,7 +16,11 @@ class Club(models.Model): zip_code = models.CharField(max_length=10, null=True, blank=True) latitude = models.FloatField(null=True, blank=True) longitude = models.FloatField(null=True, blank=True) - + timezone = models.CharField( + max_length=50, null=True, blank=True, + choices=[(tz, tz) for tz in sorted(available_timezones())], + default='CET' + ) court_count = models.IntegerField(default=2) broadcast_code = models.CharField(max_length=10, null=True, blank=True, unique=True) diff --git a/tournaments/models/draw_log.py b/tournaments/models/draw_log.py new file mode 100644 index 0000000..c09e099 --- /dev/null +++ b/tournaments/models/draw_log.py @@ -0,0 +1,10 @@ +from django.db import models +import uuid + +class DrawLog(models.Model): + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) + tournament = models.ForeignKey('Tournament', on_delete=models.CASCADE) + draw_date = models.DateTimeField() + draw_seed = models.IntegerField() + draw_match_index = models.IntegerField() + draw_team_position = models.IntegerField() diff --git a/tournaments/models/match.py b/tournaments/models/match.py index 4e4695d..7aa7d71 100644 --- a/tournaments/models/match.py +++ b/tournaments/models/match.py @@ -2,7 +2,8 @@ from django.db import models from tournaments.models import group_stage from . import Round, GroupStage, FederalMatchCategory from django.utils import timezone, formats -from datetime import timedelta +from datetime import datetime, timedelta + import uuid from ..utils.extensions import format_seconds @@ -41,6 +42,8 @@ class Match(models.Model): if self.tournament().event: club = self.tournament().event.club + if self.confirmed is False: + return "" if club: return club.court_name(index) elif index is not None: @@ -78,14 +81,16 @@ class Match(models.Model): def player_names(self): return map(lambda ts: ts.player_names(), self.team_scores.all()) + def local_start_date(self): + timezone = self.tournament().timezone() + return self.start_date.astimezone(timezone) + def formatted_start_date(self): if self.start_date: - timezoned_datetime = timezone.localtime(self.start_date) - return formats.date_format(timezoned_datetime, format='H:i') - # return formats.date_format(self.start_date, format='H:i') + local_start = self.local_start_date() + return formats.date_format(local_start, format='H:i') else: return '' - # return str(self.start_date) #.strftime("%H:%M") def time_indication(self): if self.end_date: @@ -95,10 +100,18 @@ class Match(models.Model): return '' elif self.start_date: if self.started(): - return self.formatted_duration() + if self.confirmed: + return self.formatted_duration() + else: + return 'À suivre' else: - timezoned_datetime = timezone.localtime(self.start_date) - return formats.date_format(timezoned_datetime, format='l H:i') + # timezoned_datetime = timezone.localtime(self.start_date) + timezone = self.tournament().timezone() + local_start = self.start_date.astimezone(timezone) + if self.confirmed: + return formats.date_format(local_start, format='l H:i') + else: + return f"Estimée : {formats.date_format(local_start, format='l H:i')}" else: return 'À venir...' @@ -185,14 +198,14 @@ class Match(models.Model): def live_match(self): title = self.name if self.name else self.backup_name() date = self.formatted_start_date() - duration = self.time_indication() + time_indication = self.time_indication() court = self.court_name(self.court_index) group_stage_name = None if self.group_stage: group_stage_name = self.group_stage.display_name() ended = self.end_date is not None - livematch = LiveMatch(title, date, duration, court, self.started(), ended, group_stage_name) + livematch = LiveMatch(title, date, time_indication, court, self.started(), ended, group_stage_name) for team_score in self.sorted_team_scores(): if team_score.team_registration: @@ -254,11 +267,11 @@ class Team: } class LiveMatch: - def __init__(self, title, date, duration, court, started, ended, group_stage_name): + def __init__(self, title, date, time_indication, court, started, ended, group_stage_name): self.title = title self.date = date self.teams = [] - self.duration = duration + self.time_indication = time_indication self.court = court self.started = started self.ended = ended @@ -275,7 +288,7 @@ class LiveMatch: "title": self.title, "date": self.date, "teams": [team.to_dict() for team in self.teams], - "duration": self.duration, + "time_indication": self.time_indication, "court": self.court, "started": self.started, "ended": self.ended, @@ -283,7 +296,7 @@ class LiveMatch: "group_stage_name": self.group_stage_name, } - def show_duration(self): + def show_time_indication(self): for team in self.teams: if team.walk_out and len(team.scores) == 0: return False diff --git a/tournaments/models/tournament.py b/tournaments/models/tournament.py index bb1c6e3..1acea4e 100644 --- a/tournaments/models/tournament.py +++ b/tournaments/models/tournament.py @@ -1,3 +1,4 @@ +from zoneinfo import ZoneInfo from django.db import models from typing import TYPE_CHECKING if TYPE_CHECKING: @@ -7,6 +8,8 @@ from . import Event, TournamentPayment, FederalMatchCategory, FederalCategory, F import uuid from django.utils import timezone, formats from datetime import datetime, timedelta +from zoneinfo import ZoneInfo + from shared.cryptography import encryption_util from ..utils.extensions import plural_format @@ -129,6 +132,19 @@ class Tournament(models.Model): components.append(self.name) return (' ').join(components) + def timezone(self): + tz = 'CET' + if self.event and self.event.club: + tz = self.event.club.timezone + return ZoneInfo(tz) + + def local_start_date(self): + timezone = self.timezone() + return self.start_date.astimezone(timezone) + + def local_start_date_formatted(self): + return formats.date_format(self.local_start_date(), format='j F Y H:i') + def level(self): if self.federal_level_category == 0: return "Anim." @@ -216,6 +232,7 @@ class Tournament(models.Model): def team_summons(self): summons = [] + print('>>> team_summons') if self.supposedly_in_progress() and self.end_date is None: for team in self.teams(False): names = team.names @@ -231,7 +248,7 @@ class Tournament(models.Model): names = team_registration.team_names() stage = next_match.summon_stage_name() weight = team_registration.weight - summon = TeamSummon(names, next_match.start_date, weight, stage, next_match.court_name(next_match.court_index), team_registration.logo) + summon = TeamSummon(names, next_match.local_start_date(), weight, stage, next_match.court_name(next_match.court_index), team_registration.logo) summons.append(summon) summons.sort(key=lambda s: (s.date is None, s.date or datetime.min)) @@ -259,7 +276,7 @@ class Tournament(models.Model): return rankings def teams(self, includeWaitingList): - print("Starting teams method") + # print("Starting teams method") bracket_teams = [] group_stage_teams = [] waiting_teams = [] @@ -268,10 +285,10 @@ class Tournament(models.Model): wildcard_group_stage = [] complete_teams = [] closed_registration_date = self.closed_registration_date - print(f"Closed registration date: {closed_registration_date}") + # print(f"Closed registration date: {closed_registration_date}") for team_registration in self.teamregistration_set.all(): - print(f"Processing team registration: {team_registration}") + # print(f"Processing team registration: {team_registration}") is_valid = False if closed_registration_date is not None and team_registration.registration_date is not None and team_registration.registration_date <= closed_registration_date: is_valid = True @@ -279,7 +296,7 @@ class Tournament(models.Model): is_valid = True if team_registration.registration_date is None: is_valid = True - print(f"Is valid: {is_valid}") + # print(f"Is valid: {is_valid}") if team_registration.walk_out is False: names = team_registration.team_names() @@ -287,14 +304,14 @@ class Tournament(models.Model): initial_weight = team_registration.initial_weight() date = team_registration.call_date team = TeamList(names, weight, date, initial_weight, team_registration.wild_card_bracket, team_registration.wild_card_group_stage, team_registration.logo) - print(f"Created team: {team}") + # print(f"Created team: {team}") if team_registration.group_stage_position is not None: team.set_stage("Poule") elif team_registration.bracket_position is not None: team.set_stage("Tableau") else: team.set_stage("Attente") - print(f"Team stage: {team.stage}") + # print(f"Team stage: {team.stage}") teams.append(team) if team_registration.wild_card_bracket: @@ -306,11 +323,11 @@ class Tournament(models.Model): else: waiting_teams.append(team) - print(f"Total teams: {len(teams)}") - print(f"Wildcard bracket: {len(wildcard_bracket)}") - print(f"Wildcard group stage: {len(wildcard_group_stage)}") - print(f"Complete teams: {len(complete_teams)}") - print(f"Waiting teams: {len(waiting_teams)}") + # print(f"Total teams: {len(teams)}") + # print(f"Wildcard bracket: {len(wildcard_bracket)}") + # print(f"Wildcard group stage: {len(wildcard_group_stage)}") + # print(f"Complete teams: {len(complete_teams)}") + # print(f"Waiting teams: {len(waiting_teams)}") if len(teams) < self.team_count: teams.sort(key=lambda s: (s.initial_weight, s.date)) @@ -323,8 +340,8 @@ class Tournament(models.Model): group_stage_members_count = 0 if seeds_count < 0: seeds_count = 0 - print(f"Seeds count: {seeds_count}") - print(f"Group stage members count: {group_stage_members_count}") + # print(f"Seeds count: {seeds_count}") + # print(f"Group stage members count: {group_stage_members_count}") if self.team_sorting == TeamSortingType.INSCRIPTION_DATE: complete_teams.sort(key=lambda s: (s.date is None, s.date or datetime.min, s.initial_weight)) @@ -333,25 +350,25 @@ class Tournament(models.Model): selected_teams = complete_teams[:self.team_count] selected_teams.sort(key=lambda s: s.initial_weight) - print(f"Selected teams: {len(selected_teams)}") + # print(f"Selected teams: {len(selected_teams)}") if seeds_count > 0: bracket_teams = selected_teams[:seeds_count] + wildcard_bracket else: bracket_teams = [] - print(f"Bracket teams: {len(bracket_teams)}") + # print(f"Bracket teams: {len(bracket_teams)}") if group_stage_members_count: group_stage_end = seeds_count + group_stage_members_count group_stage_teams = selected_teams[seeds_count:group_stage_end] + wildcard_group_stage else: group_stage_teams = [] - print(f"Group stage teams: {len(group_stage_teams)}") + # print(f"Group stage teams: {len(group_stage_teams)}") waiting_list_count = len(teams) - self.team_count if waiting_list_count < 0: waiting_list_count = 0 - print(f"Waiting list count: {waiting_list_count}") + # print(f"Waiting list count: {waiting_list_count}") if waiting_list_count > 0 or len(waiting_teams) > 0: if waiting_list_count > 0: @@ -362,7 +379,7 @@ class Tournament(models.Model): waiting_teams.sort(key=lambda s: (s.initial_weight, s.date)) else: waiting_teams = [] - print(f"Final waiting teams: {len(waiting_teams)}") + # print(f"Final waiting teams: {len(waiting_teams)}") bracket_teams.sort(key=lambda s: s.weight) group_stage_teams.sort(key=lambda s: s.weight) @@ -380,10 +397,10 @@ class Tournament(models.Model): if includeWaitingList is True: final_teams = bracket_teams + group_stage_teams + waiting_teams - print(f"Final teams with waiting list: {len(final_teams)}") + # print(f"Final teams with waiting list: {len(final_teams)}") else: final_teams = bracket_teams + group_stage_teams - print(f"Final teams without waiting list: {len(final_teams)}") + # print(f"Final teams without waiting list: {len(final_teams)}") return final_teams @@ -791,8 +808,23 @@ class Tournament(models.Model): return date.replace(hour=8, minute=0, second=0, microsecond=0, tzinfo=date.tzinfo) def supposedly_in_progress(self): - end = self.start_date + timedelta(days=self.day_duration + 1) - return self.start_date.replace(hour=0, minute=0) <= timezone.now() <= end + # end = self.start_date + timedelta(days=self.day_duration + 1) + # return self.start_date.replace(hour=0, minute=0) <= timezone.now() <= end + + timezoned_datetime = timezone.localtime(self.start_date) + end = timezoned_datetime + timedelta(days=self.day_duration + 1) + now = timezone.now() + + start = timezoned_datetime.replace(hour=0, minute=0) + + print(f"timezoned_datetime: {timezoned_datetime}") + print(f"tournament end date: {end}") + print(f"current time: {now}") + print(f"tournament start: {start}") + print(f"start <= now <= end: {start <= now <= end}") + + return start <= now <= end + def display_points_earned(self): return self.federal_level_category != FederalLevelCategory.UNLISTED and self.hide_points_earned is False @@ -840,10 +872,9 @@ class TeamSummon: def formatted_date(self): if self.date: - timezoned_datetime = timezone.localtime(self.date) - return formats.date_format(timezoned_datetime, format='l H:i') + return formats.date_format(self.date, format='l H:i') else: - return None + return '' def to_dict(self): return { diff --git a/tournaments/static/misc/jap-test.csv b/tournaments/static/misc/jap-test.csv index 04d8fde..f32ae23 100644 --- a/tournaments/static/misc/jap-test.csv +++ b/tournaments/static/misc/jap-test.csv @@ -1,3 +1 @@ CAN PADEL,POPOVITCH,Laurent,laurent@padelclub.app,0629445485 -CAN PADEL,POPOVITCH,Razmig,razmig@padelclub.app,0629445485 -CAN PADEL,POPOVITCH,Xavier,xavier@padelclub.app,0629445485 diff --git a/tournaments/templates/tournaments/broadcast/broadcasted_match.html b/tournaments/templates/tournaments/broadcast/broadcasted_match.html index 66758cc..295b181 100644 --- a/tournaments/templates/tournaments/broadcast/broadcasted_match.html +++ b/tournaments/templates/tournaments/broadcast/broadcasted_match.html @@ -51,7 +51,7 @@
- +
diff --git a/tournaments/templates/tournaments/match_cell.html b/tournaments/templates/tournaments/match_cell.html index aea7beb..984bd81 100644 --- a/tournaments/templates/tournaments/match_cell.html +++ b/tournaments/templates/tournaments/match_cell.html @@ -42,8 +42,8 @@
-
{{ summon.date|date:'l H:i' }}
+
{{ summon.formatted_date }}
{{ summon.court }}
{{ summon.stage }}
diff --git a/tournaments/templates/tournaments/tournament_info.html b/tournaments/templates/tournaments/tournament_info.html index 319dbda..8ab6c16 100644 --- a/tournaments/templates/tournaments/tournament_info.html +++ b/tournaments/templates/tournaments/tournament_info.html @@ -7,6 +7,7 @@ {% block content %} {% load static %} +{% load tz %} {% include 'tournaments/navigation_tournament.html' %} @@ -17,7 +18,7 @@

-

{{ tournament.start_date }}
+
{{ tournament.local_start_date_formatted }}
{{ tournament.day_duration_formatted }}
{{ tournament.court_count }} terrains

diff --git a/tournaments/views.py b/tournaments/views.py index 3904f9d..e30e420 100644 --- a/tournaments/views.py +++ b/tournaments/views.py @@ -79,8 +79,8 @@ def live_tournaments(club_id): 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) + tomorrow = datetime.now().date() + timedelta(days=1) + tournaments = tournaments_query(Q(end_date__isnull=True, start_date__gte=tomorrow), club_id, True) return [t for t in tournaments if t.display_tournament()] def tournament_info(request, tournament_id): @@ -147,13 +147,8 @@ def tournament(request, tournament_id): rounds = list(tournament.round_set.filter(group_stage_loser_bracket=True)) rounds.extend(bracket_rounds) - #group_stages = tournament.groupstage_set.order_by('index') group_stages = sorted(tournament.get_computed_group_stage(), key=lambda s: (s.step, s.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, @@ -430,7 +425,7 @@ def simple_form_view(request): return HttpResponse(f"Hello, {name}!") # Simple response with name else: form = SimpleForm() - print(request.method) + # print(request.method) # If this is a GET request, we display an empty form return render(request, 'tournaments/admin/mail_test.html', {'form': form}) @@ -484,7 +479,7 @@ def send_email(mail, name): name = "" subject = "Tes tournois en toute simplicité avec Padel Club" - body = f"Salut {name} !\n\nJe me permets de t'écrire car je suis JAP2 en région PACA et développeur, et je viens de lancer Padel Club, une app iOS qui facilite enfin l'organisation des tournois. Avec elle, tu peux convoquer rapidement, simuler et programmer tes structures, diffuser tous les résultats à tous les joueurs, et ce depuis un iPhone.\n\nTu peux l'essayer gratuitement pour découvrir tout son potentiel ! Télécharge l'app ici et teste la dès ton prochain tournoi: https://padelclub.app/download/\n\nJe suis disponible pour échanger avec toi par mail ou téléphone au 06 81 59 81 93 et voir ce que tu en penses.\nÀ bientôt j'espère !\n\nRazmig" + body = f"Salut {name} !\n\nJe me permets de t'écrire car je suis JAP2 en région PACA et développeur, et je viens de lancer Padel Club, une app iOS qui facilite enfin l'organisation des tournois.\n\nAvec elle, tu peux convoquer rapidement, simuler et programmer tes structures, diffuser tous les résultats à tous les joueurs, et ce depuis un iPhone.\n\nTu peux l'essayer gratuitement pour découvrir tout son potentiel ! Télécharge l'app ici et teste la dès ton prochain tournoi: https://padelclub.app/download/\n\nJe suis disponible pour échanger avec toi par mail ou téléphone au 06 81 59 81 93 et voir ce que tu en penses.\nÀ bientôt j'espère !\n\nRazmig" email = EmailMessage(subject, body, to=[mail]) email.send()