diff --git a/.env b/.env index 66aac01..28e29d9 100644 --- a/.env +++ b/.env @@ -13,6 +13,7 @@ DB_HOST=db DB_PORT=5432 PWD_PATH=${PWD} PROJECT_PATH=${PWD_PATH}/pong +DJANGO_LOGS=${PWD_PATH}/logs # ElasticSearch settings STACK_VERSION=8.14.3 diff --git a/config/logstash.conf b/config/logstash.conf index f8a8a2c..329a522 100644 --- a/config/logstash.conf +++ b/config/logstash.conf @@ -1,21 +1,28 @@ input { - udp { - host => "0.0.0.0" - port => 5044 + file { + path => "/usr/share/logstash/logs/django.log" + start_position => "beginning" + sincedb_path => "/dev/null" + codec => "json" } } -filter {} +filter { + json { + source => "message" + target => "json_message" + } +} output { elasticsearch { - index => "logstash-%{+YYYY.MM.dd}" hosts => ["https://es01:9200"] user => "elastic" - password => elastic_pass - ssl_enabled => true + password => "${ELASTIC_PASSWORD}" + ssl_enabled => true ssl_certificate_authorities => "/usr/share/logstash/certs/ca/ca.crt" ssl_verification_mode => "full" + index => "django-logs-%{+YYYY.MM.dd}" + } + stdout { codec => rubydebug } } - #stdout {} -} diff --git a/docker-compose.yml b/docker-compose.yml index 6e96098..33a4a7e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -58,6 +58,60 @@ services: timeout: 5s retries: 120 + backend: + build: + context: . + dockerfile: Dockerfile + image: backend + container_name: backend + restart: always + command: /bin/sh -c "sleep 5 && + venv/bin/python manage.py makemigrations --noinput && + venv/bin/python manage.py migrate --noinput && + venv/bin/python manage.py collectstatic --noinput && + venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" + volumes: + - pong:/transcendence/pong + - pong_django_logs:/transcendence/logs + ports: + - 8080:8080 + networks: + - app-network + environment: + DB_HOST: db + DB_PORT: 5432 + DB_NAME: ${POSTGRES_DB} + DB_USER: ${POSTGRES_USER} + DB_PASSWORD: ${POSTGRES_PASSWORD} + depends_on: + - db + healthcheck: + test: ["CMD-SHELL", "curl", "http://localhost:8080"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + + db: + image: postgres:latest + container_name: postgres + restart: always + volumes: + - pong_pg_data:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - app-network + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + es01: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} container_name: es01 @@ -145,6 +199,7 @@ services: - certs:/usr/share/logstash/certs - pong_logstash_data01:/usr/share/logstash/data - ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro + - pong_django_logs:/usr/share/logstash/logs ports: - "5044:5044/udp" command: logstash -f /usr/share/logstash/pipeline/logstash.conf @@ -154,59 +209,6 @@ services: - ELASTIC_USER=${ELASTIC_USERNAME} - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - xpack.monitoring.enabled=false - - backend: - build: - context: . - dockerfile: Dockerfile - image: backend - container_name: backend - restart: always - command: /bin/sh -c "sleep 5 && - venv/bin/python manage.py makemigrations --noinput && - venv/bin/python manage.py migrate --noinput && - venv/bin/python manage.py collectstatic --noinput && - venv/bin/daphne -b 0.0.0.0 -p 8080 pong.asgi:application" - volumes: - - pong:/transcendence/pong - ports: - - 8080:8080 - networks: - - app-network - environment: - DB_HOST: db - DB_PORT: 5432 - DB_NAME: ${POSTGRES_DB} - DB_USER: ${POSTGRES_USER} - DB_PASSWORD: ${POSTGRES_PASSWORD} - depends_on: - - db - healthcheck: - test: ["CMD-SHELL", "curl", "http://localhost:8080"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 10s - - db: - image: postgres:latest - container_name: postgres - restart: always - volumes: - - pong_pg_data:/var/lib/postgresql/data - ports: - - "5432:5432" - networks: - - app-network - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 10s - timeout: 5s - retries: 5 volumes: pong: @@ -215,6 +217,12 @@ volumes: type: none device: ${PROJECT_PATH} o: bind + pong_django_logs: + driver: local + driver_opts: + type: none + device: ${DJANGO_LOGS} + o: bind pong_pg_data: driver: local pong_es_data_01: diff --git a/logs/django.log b/logs/django.log new file mode 100644 index 0000000..81fe80d --- /dev/null +++ b/logs/django.log @@ -0,0 +1 @@ +{"message": "Not Found: /totofaitduvelo", "taskName": null, "status_code": 404, "request": ""} diff --git a/makefile b/makefile index 35d1deb..0c6d19d 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ CONTAINER=$(c) up: down $(COMPOSE) build - $(COMPOSE) up $(CONTAINER) || true + $(COMPOSE) up -d $(CONTAINER) || true build: $(COMPOSE) build $(CONTAINER) @@ -20,8 +20,8 @@ down: destroy: $(COMPOSE) down -v --rmi all - #sudo lsof -i :5432 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true - #sudo lsof -i :80 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true + sudo lsof -i :5432 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true + sudo lsof -i :80 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true logs: $(COMPOSE) logs -f $(CONTAINER) diff --git a/pong/game/matchmaking.py b/pong/game/matchmaking.py index 5ca454c..989a1dd 100644 --- a/pong/game/matchmaking.py +++ b/pong/game/matchmaking.py @@ -40,7 +40,7 @@ class MatchMaker: await asyncio.sleep(1) self.timer += 1 # Waiting for more than 30s -> BOT game - if self.timer >= 30 and self.waiting_players: + if self.timer >= 15 and self.waiting_players: player1 = self.waiting_players.pop(0) print(f"*** MATCH FOUND: {player1.user.username} vs BOT") self.botgame = True diff --git a/pong/game/templates/pong/match_list.html b/pong/game/templates/pong/match_list.html deleted file mode 100644 index 72c1315..0000000 --- a/pong/game/templates/pong/match_list.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - Matches List - - -

Matches List

- - - - - - - - - - - - - - - - - - - {% for match in matches %} - - - - - - - - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDPlayer 1Player 2Score Player 1Score Player 2WinnerBall Touches Player 1Ball Touches Player 2DurationDateIs TournamentTournament
{{ match.id }}{{ match.player1.name }}{{ match.player2.name }}{{ match.score_player1 }}{{ match.score_player2 }}{{ match.winner.name }}{{ match.nbr_ball_touch_p1 }}{{ match.nbr_ball_touch_p2 }}{{ match.duration }}{{ match.date }}{{ match.is_tournoi }}{{ match.tournoi.name }}
No matches found.
- - diff --git a/pong/game/templates/pong/player_list.html b/pong/game/templates/pong/player_list.html deleted file mode 100644 index b9fbb42..0000000 --- a/pong/game/templates/pong/player_list.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - Players List - - -

Players List

- - - - - - - - - - - - - - - - - - - - {% for player in players %} - - - - - - - - - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDNameTotal MatchesTotal WinsWin PercentageAverage Match ScoreAverage Opponent ScoreBest ScoreAverage Ball TouchesTotal DurationAverage DurationParticipated TournamentsWon Tournaments
{{ player.id }}{{ player.name }}{{ player.total_match }}{{ player.total_win }}{{ player.p_win }}{{ player.m_score_match }}{{ player.m_score_adv_match }}{{ player.best_score }}{{ player.m_nbr_ball_touch }}{{ player.total_duration }}{{ player.m_duration }}{{ player.num_participated_tournaments }}{{ player.num_won_tournaments }}
No players found.
- - diff --git a/pong/game/templates/pong/tournoi_list.html b/pong/game/templates/pong/tournoi_list.html deleted file mode 100644 index e5718f5..0000000 --- a/pong/game/templates/pong/tournoi_list.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - Tournaments List - - -

Tournaments List

- - - - - - - - - - - - {% for tournoi in tournois %} - - - - - - - - {% empty %} - - - - {% endfor %} - -
IDNameNumber of PlayersDateWinner
{{ tournoi.id }}{{ tournoi.name }}{{ tournoi.nbr_player }}{{ tournoi.date }}{{ tournoi.winner.name }}
No tournaments found.
- - diff --git a/pong/game/urls.py b/pong/game/urls.py index 7a2a3ef..df150f0 100644 --- a/pong/game/urls.py +++ b/pong/game/urls.py @@ -2,7 +2,6 @@ from django.urls import path, include from . import views -from .views import player_list, tournoi_list, match_list from rest_framework.routers import DefaultRouter from .views import match_list_json, player_list_json, tournoi_list_json @@ -13,9 +12,6 @@ urlpatterns = [ path('register_user/', views.register_user, name='register_user'), path('authenticate_user/', views.authenticate_user, name='authenticate_user'), path('web3/', views.read_data, name='read_data'), - path('players/', player_list, name='player_list'), - path('matches/', match_list, name='match_list'), - path('tournois/', tournoi_list, name='tournoi_list'), path('api/match_list/', match_list_json, name='match_list_json'), path('api/player_list/', player_list_json, name='player_list_json'), path('api/tournoi_list/', tournoi_list_json, name='tournoi_list_json') diff --git a/pong/game/utils.py b/pong/game/utils.py index 070da36..2b35c5b 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -4,35 +4,17 @@ from django.shortcuts import get_object_or_404 from django.db.models import Max, Sum, F from datetime import timedelta from channels.db import database_sync_to_async +#from asgiref.sync import database_sync_to_async async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: print("here endfortheouche §!!!") + # Vérification de l'existence des joueurs et création si nécessaire + player_1 = await get_or_create_player(p1) + player_2 = await get_or_create_player(p2) + + print("ok") - # Handle Player 1 - exists = await database_sync_to_async(Player.objects.filter(name=p1).exists)() - if exists: - print(f"Player {p1} exists.") - else: - print(f"Player {p1} does not exist.") - - player_1 = await get_name(p1) - print(f"Player 1 retrieval result: {player_1}") - if player_1 is None: - print("############# CREATING PLAYER") - player_1 = await create_player(p1) - else: - print("############# PLAYER FOUND") - - # Handle Player 2 - player_2 = await get_name(p2) - print(f"Player 2 retrieval result: {player_2}") - if player_2 is None: - print("############# CREATING PLAYER") - player_2 = await create_player(p2) - else: - print("############# PLAYER FOUND") - print("############# BEFORE MATCH") await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) print("############# AFTER DONE") @@ -45,13 +27,34 @@ async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_ print(f"Error in endfortheouche: {e}") @database_sync_to_async -def get_name(p): - print(f"in get_name({p})..") - try: - return Player.objects.get(name=p) - except Player.DoesNotExist: - print("get_name() exception") - return None +def get_player_by_name(name): + print(f"Checking if player '{name}' exists") + exists = Player.objects.filter(name=name).exists() + print(f"Player exists: {exists}") + return exists + + +@database_sync_to_async +def get_player(name): + return Player.objects.get(name=name) + + +async def get_or_create_player(name): + print("here !!") + print(f"Checking existence for player: {name}") + player_exists = await get_player_by_name(name) + print(f"END search in database!! (Player exists: {player_exists})") + if not player_exists: + print("Player does not exist, creating player...") + player = await create_player(name) + print(f"Player created: {player}") + return player + else: + print("Player exists, fetching player...") + player = await get_player(name) + print(f"Player fetched: {player}") + return player + @database_sync_to_async def create_player( @@ -69,8 +72,6 @@ def create_player( num_won_tournaments=0 ): print("create player !!!") - """ if database_sync_to_async(Player.objects.filter(name=name).exists)(): - raise ValueError(f"A player with the name '{name}' already exists.") """ player = Player( name=name, @@ -150,9 +151,9 @@ def update_player_statistics(player_name): return won_matches = Match.objects.filter(winner=player) - """ part_tourn_as_p1 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player1=player) - part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player) - won_tourn = Tournoi.objects.filter(winner=player) """ + #part_tourn_as_p1 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player1=player) + #part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player) + #won_tourn = Tournoi.objects.filter(winner=player) total_score = matches_as_player1.aggregate(Sum('score_player1'))['score_player1__sum'] or 0 total_score += matches_as_player2.aggregate(Sum('score_player2'))['score_player2__sum'] or 0 @@ -174,10 +175,10 @@ def update_player_statistics(player_name): total_duration += matches_as_player2.aggregate(Sum('duration'))['duration__sum'] or 0 m_duration = total_duration / total_match - """ total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() - total_win_tourn = won_tourn.count() - p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0 - """ + #total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() + #total_win_tourn = won_tourn.count() + #p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0 + best_score_as_player1 = matches_as_player1.aggregate(Max('score_player1'))['score_player1__max'] or 0 best_score_as_player2 = matches_as_player2.aggregate(Max('score_player2'))['score_player2__max'] or 0 best_score = max(best_score_as_player1, best_score_as_player2) @@ -192,8 +193,8 @@ def update_player_statistics(player_name): player.m_nbr_ball_touch = m_nbr_ball_touch player.total_duration = total_duration player.m_duration = m_duration - """ player.num_participated_tournaments = total_tourn_p - player.num_won_tournaments = total_win_tourn """ + # player.num_participated_tournaments = total_tourn_p + #player.num_won_tournaments = total_win_tourn player.save() print("CHAKU IS THE BEST") @@ -205,4 +206,100 @@ def get_player_p_win(player_name): return player.p_win + + + + + +######## try synchrone version ######## + +""" def endfortheouche_sync(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): + try: + print("here endfortheouche §!!!") + player_1 = get_or_create_player_sync(p1) + player_2 = get_or_create_player_sync(p2) + + print("ok") + + print("############# BEFORE MATCH") + create_match_sync(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) + print("############# AFTER DONE") + + #update_player_statistics_sync(p1) + print("############# END STAT P1") + #update_player_statistics_sync(p2) + except Exception as e: + print(f"Error in endfortheouche: {e}") + +def get_player_sync(name): + print(f"Getting player '{name}'") + return Player.objects.get(name=name) + + +def get_or_create_player_sync(name): + print("here !!") + player_exists = Player.objects.filter(name=name).exists() + print("search in database!!") + if not player_exists: + print(f"Player '{name}' does not exist, creating new player.") + return create_player_sync(name) + else: + print(f"Player '{name}' exists.") + return get_player_sync(name) + +def create_player( + name, + total_match=0, + total_win=0, + p_win= None, + m_score_match= None, + m_score_adv_match= None, + best_score=0, + m_nbr_ball_touch= None, + total_duration= None, + m_duration= None, + num_participated_tournaments=0, + num_won_tournaments=0 +): + print("create player !!!") + player = Player( + name=name, + total_match=total_match, + total_win=total_win, + p_win=p_win, + m_score_match=m_score_match, + m_score_adv_match=m_score_adv_match, + best_score=best_score, + m_nbr_ball_touch=m_nbr_ball_touch, + total_duration=total_duration, + m_duration=m_duration, + num_participated_tournaments=num_participated_tournaments, + num_won_tournaments=num_won_tournaments + ) + player.save() + return player + + +def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi): + match = Match( + player1=player1, + player2=player2, + score_player1=score_player1, + score_player2=score_player2, + nbr_ball_touch_p1=nbr_ball_touch_p1, + nbr_ball_touch_p2=nbr_ball_touch_p2, + duration=duration, + is_tournoi=is_tournoi, + tournoi=tournoi + ) + + if score_player1 > score_player2: + match.winner = match.player1 + elif score_player2 > score_player1: + match.winner = match.player2 + else: + match.winner = None + + match.save() + return match """ diff --git a/pong/game/views.py b/pong/game/views.py index e9b0151..8bd8097 100644 --- a/pong/game/views.py +++ b/pong/game/views.py @@ -72,18 +72,6 @@ def get_or_create_token(user): ####################### THEOUCHE PART ############################ -def player_list(request): - players = Player.objects.all() - return render(request, 'pong/player_list.html', {'players': players}) - -def match_list(request): - matches = Match.objects.select_related('player1', 'player2', 'winner', 'tournoi').all() - return render(request, 'pong/match_list.html', {'matches': matches}) - -def tournoi_list(request): - tournois = Tournoi.objects.select_related('winner').all() - return render(request, 'pong/tournoi_list.html', {'tournois': tournois}) - from django.http import JsonResponse def match_list_json(request): diff --git a/pong/settings.py b/pong/settings.py index 83bd985..1f8d1ce 100644 --- a/pong/settings.py +++ b/pong/settings.py @@ -6,8 +6,9 @@ Django settings for pong project. Generated by 'django-admin startproject' using Django 3.2. """ -from pathlib import Path import os +import logging.config +from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -134,3 +135,38 @@ CHANNEL_LAYERS = { 'BACKEND': 'channels.layers.InMemoryChannelLayer', }, } + +LOGGING = { + 'version': 1, # The version of the logging configuration schema + 'disable_existing_loggers': False, # Allows existing loggers to keep logging + 'formatters': { # Defines how log messages will be formatted + 'json': { + '()': 'pythonjsonlogger.jsonlogger.JsonFormatter', + # Formatter that outputs logs in JSON format, which is ideal for ingestion by Logstash. + }, + 'default': { + 'format': '[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s', + # This is a basic text formatter with timestamp, log level, logger name, line number, and the actual message. + }, + }, + 'handlers': { # Handlers determine where the log messages are sent + 'file': { + 'level': 'INFO', # Minimum log level to be handled (INFO and above) + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, 'logs/django.log'), # The file where logs will be saved + 'formatter': 'json', # Uses the JSON formatter defined above + }, + 'console': { + 'level': 'DEBUG', # Minimum log level to be handled (DEBUG and above) + 'class': 'logging.StreamHandler', + 'formatter': 'default', # Uses the default text formatter + }, + }, + 'loggers': { # Loggers are the actual log streams that get configured + 'django': { # The Django logger catches all messages sent by the Django framework + 'handlers': ['file', 'console'], # Sends logs to both the file and the console + 'level': 'DEBUG', # Minimum log level to be logged + 'propagate': True, # If True, messages will be passed to the parent loggers as well + }, + }, +} diff --git a/pong/static/game.js b/pong/static/game.js index 6eb7096..740056c 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -557,28 +557,31 @@ document.addEventListener('DOMContentLoaded', () => { const matchListBody = document.querySelector('#match-list tbody'); matchListBody.innerHTML = ''; - if (matches.length === 0) { - console.log('No matches to display'); - } - - matches.forEach(match => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${match.id} - ${match.player1__name} - ${match.player2__name} - ${match.score_player1} - ${match.score_player2} - ${match.winner__name} - ${match.nbr_ball_touch_p1} - ${match.nbr_ball_touch_p2} - ${match.duration} - ${match.date} - ${match.is_tournoi} - ${match.tournoi__name} - `; - matchListBody.appendChild(row); - }); + const row = document.createElement('tr'); + if (matches.length != 0) { + matches.forEach(match => { + row.innerHTML = ` + ${match.id} + ${match.player1__name} + ${match.player2__name} + ${match.score_player1} + ${match.score_player2} + ${match.winner__name} + ${match.nbr_ball_touch_p1} + ${match.nbr_ball_touch_p2} + ${match.duration} + ${match.date} + ${match.is_tournoi} + ${match.tournoi__name} + `; + matchListBody.appendChild(row); + }); + } else { + row.innerHTML = ` + No matches found. + `; + matchListBody.appendChild(row); + } } function displayPlayers(players) { @@ -586,51 +589,58 @@ document.addEventListener('DOMContentLoaded', () => { const playersListBody = document.querySelector('#player-list tbody'); playersListBody.innerHTML = ''; - if (players.length === 0) { - console.log('No players to display'); - } + const row = document.createElement('tr'); + if (players.length != 0) { + players.forEach(player => { + row.innerHTML = ` + ${player.id} + ${player.name} + ${player.total_match} + ${player.total_win} + ${player.p_win} + ${player.m_score_match} + ${player.m_score_adv_match} + ${player.best_score} + ${player.m_nbr_ball_touch} + ${player.total_duration} + ${player.m_duration} + ${player.num_participated_tournaments} + ${player.num_won_tournaments} + `; + playersListBody.appendChild(row); + }); + } else { + row.innerHTML = ` + No matches found. + ` + playersListBody.appendChild(row); + } + } - players.forEach(player => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${player.id} - ${player.name} - ${player.total_match} - ${player.total_win} - ${player.p_win} - ${player.m_score_match} - ${player.m_score_adv_match} - ${player.best_score} - ${player.m_nbr_ball_touch} - ${player.total_duration} - ${player.m_duration} - ${player.num_participated_tournaments} - ${player.num_won_tournaments} - `; - playersListBody.appendChild(row); - }); - } + function displayTournois(tournois) { + console.log('Displaying tournois:'); + const tournoisListBody = document.querySelector('#tournoi-list tbody'); + tournoisListBody.innerHTML = ''; - function displayTournois(tournois) { - console.log('Displaying tournois:'); - const tournoisListBody = document.querySelector('#tournoi-list tbody'); - tournoisListBody.innerHTML = ''; - - if (tournois.length === 0) { - console.log('No tournois to display'); - } - - tournois.forEach(tournoi => { - const row = document.createElement('tr'); - row.innerHTML = ` - ${tournoi.id} - ${tournoi.name} - ${tournoi.nbr_player} - ${tournoi.date} - ${tournoi.winner.name} - `; - tournoisListBody.appendChild(row); - }); + const row = document.createElement('tr'); + if (tournois.length != 0) { + tournois.forEach(tournoi => { + row.innerHTML = ` + ${tournoi.id} + ${tournoi.name} + ${tournoi.nbr_player} + ${tournoi.date} + ${tournoi.winner.name} + `; + tournoisListBody.appendChild(row); + }); + } else { + row.innerHTML = ` + No matches found. + ` + tournoisListBody.appendChild(row); + } + } ////////////////////////////// END BURGER BUTTON //////////////////////////////// diff --git a/pong/static/index.html b/pong/static/index.html index 7731712..426cc25 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -146,27 +146,7 @@ - {% for match in matches %} - - {{ match.id }} - {{ match.player1.name }} - {{ match.player2.name }} - {{ match.score_player1 }} - {{ match.score_player2 }} - {{ match.winner.name }} - {{ match.nbr_ball_touch_p1 }} - {{ match.nbr_ball_touch_p2 }} - {{ match.duration }} - {{ match.date }} - {{ match.is_tournoi }} - {{ match.tournoi.name }} - - {% empty %} - - No matches found. - - {% endfor %} - + @@ -191,28 +171,7 @@ - {% for player in players %} - - {{ player.id }} - {{ player.name }} - {{ player.total_match }} - {{ player.total_win }} - {{ player.p_win }} - {{ player.m_score_match }} - {{ player.m_score_adv_match }} - {{ player.best_score }} - {{ player.m_nbr_ball_touch }} - {{ player.total_duration }} - {{ player.m_duration }} - {{ player.num_participated_tournaments }} - {{ player.num_won_tournaments }} - - {% empty %} - - No players found. - - {% endfor %} - + @@ -228,21 +187,8 @@ Winner - - {% for tournoi in tournois %} - - {{ tournoi.id }} - {{ tournoi.name }} - {{ tournoi.nbr_player }} - {{ tournoi.date }} - {{ tournoi.winner.name }} - - {% empty %} - - No tournois found. - - {% endfor %} - + + diff --git a/requirements.txt b/requirements.txt index 54b2e96..15069d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ channels daphne djangorestframework web3 -asyncpg \ No newline at end of file +python-json-logger==2.0.7