mirror of
https://github.com/AudebertAdrien/ft_transcendence.git
synced 2025-12-18 15:07:49 +01:00
merge with chaku and adrien v1
This commit is contained in:
commit
09f1c9e2a5
1
.env
1
.env
@ -13,6 +13,7 @@ DB_HOST=db
|
|||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
PWD_PATH=${PWD}
|
PWD_PATH=${PWD}
|
||||||
PROJECT_PATH=${PWD_PATH}/pong
|
PROJECT_PATH=${PWD_PATH}/pong
|
||||||
|
DJANGO_LOGS=${PWD_PATH}/logs
|
||||||
|
|
||||||
# ElasticSearch settings
|
# ElasticSearch settings
|
||||||
STACK_VERSION=8.14.3
|
STACK_VERSION=8.14.3
|
||||||
|
|||||||
@ -1,21 +1,28 @@
|
|||||||
input {
|
input {
|
||||||
udp {
|
file {
|
||||||
host => "0.0.0.0"
|
path => "/usr/share/logstash/logs/django.log"
|
||||||
port => 5044
|
start_position => "beginning"
|
||||||
|
sincedb_path => "/dev/null"
|
||||||
|
codec => "json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filter {}
|
filter {
|
||||||
|
json {
|
||||||
|
source => "message"
|
||||||
|
target => "json_message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
output {
|
output {
|
||||||
elasticsearch {
|
elasticsearch {
|
||||||
index => "logstash-%{+YYYY.MM.dd}"
|
|
||||||
hosts => ["https://es01:9200"]
|
hosts => ["https://es01:9200"]
|
||||||
user => "elastic"
|
user => "elastic"
|
||||||
password => elastic_pass
|
password => "${ELASTIC_PASSWORD}"
|
||||||
ssl_enabled => true
|
ssl_enabled => true
|
||||||
ssl_certificate_authorities => "/usr/share/logstash/certs/ca/ca.crt"
|
ssl_certificate_authorities => "/usr/share/logstash/certs/ca/ca.crt"
|
||||||
ssl_verification_mode => "full"
|
ssl_verification_mode => "full"
|
||||||
|
index => "django-logs-%{+YYYY.MM.dd}"
|
||||||
}
|
}
|
||||||
#stdout {}
|
stdout { codec => rubydebug }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,60 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 120
|
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:
|
es01:
|
||||||
image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
|
image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
|
||||||
container_name: es01
|
container_name: es01
|
||||||
@ -145,6 +199,7 @@ services:
|
|||||||
- certs:/usr/share/logstash/certs
|
- certs:/usr/share/logstash/certs
|
||||||
- pong_logstash_data01:/usr/share/logstash/data
|
- pong_logstash_data01:/usr/share/logstash/data
|
||||||
- ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro
|
- ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro
|
||||||
|
- pong_django_logs:/usr/share/logstash/logs
|
||||||
ports:
|
ports:
|
||||||
- "5044:5044/udp"
|
- "5044:5044/udp"
|
||||||
command: logstash -f /usr/share/logstash/pipeline/logstash.conf
|
command: logstash -f /usr/share/logstash/pipeline/logstash.conf
|
||||||
@ -155,59 +210,6 @@ services:
|
|||||||
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
|
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
|
||||||
- xpack.monitoring.enabled=false
|
- 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:
|
volumes:
|
||||||
pong:
|
pong:
|
||||||
driver: local
|
driver: local
|
||||||
@ -215,6 +217,12 @@ volumes:
|
|||||||
type: none
|
type: none
|
||||||
device: ${PROJECT_PATH}
|
device: ${PROJECT_PATH}
|
||||||
o: bind
|
o: bind
|
||||||
|
pong_django_logs:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
device: ${DJANGO_LOGS}
|
||||||
|
o: bind
|
||||||
pong_pg_data:
|
pong_pg_data:
|
||||||
driver: local
|
driver: local
|
||||||
pong_es_data_01:
|
pong_es_data_01:
|
||||||
|
|||||||
1
logs/django.log
Normal file
1
logs/django.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"message": "Not Found: /totofaitduvelo", "taskName": null, "status_code": 404, "request": "<ASGIRequest: GET '/totofaitduvelo'>"}
|
||||||
6
makefile
6
makefile
@ -4,7 +4,7 @@ CONTAINER=$(c)
|
|||||||
|
|
||||||
up: down
|
up: down
|
||||||
$(COMPOSE) build
|
$(COMPOSE) build
|
||||||
$(COMPOSE) up $(CONTAINER) || true
|
$(COMPOSE) up -d $(CONTAINER) || true
|
||||||
|
|
||||||
build:
|
build:
|
||||||
$(COMPOSE) build $(CONTAINER)
|
$(COMPOSE) build $(CONTAINER)
|
||||||
@ -20,8 +20,8 @@ down:
|
|||||||
|
|
||||||
destroy:
|
destroy:
|
||||||
$(COMPOSE) down -v --rmi all
|
$(COMPOSE) down -v --rmi all
|
||||||
#sudo lsof -i :5432 | 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
|
sudo lsof -i :80 | awk 'NR>1 {print $$2}' | xargs sudo kill -9 || true
|
||||||
|
|
||||||
logs:
|
logs:
|
||||||
$(COMPOSE) logs -f $(CONTAINER)
|
$(COMPOSE) logs -f $(CONTAINER)
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class MatchMaker:
|
|||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
self.timer += 1
|
self.timer += 1
|
||||||
# Waiting for more than 30s -> BOT game
|
# 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)
|
player1 = self.waiting_players.pop(0)
|
||||||
print(f"*** MATCH FOUND: {player1.user.username} vs BOT")
|
print(f"*** MATCH FOUND: {player1.user.username} vs BOT")
|
||||||
self.botgame = True
|
self.botgame = True
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Matches List</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Matches List</h1>
|
|
||||||
<table border="1">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>ID</th>
|
|
||||||
<th>Player 1</th>
|
|
||||||
<th>Player 2</th>
|
|
||||||
<th>Score Player 1</th>
|
|
||||||
<th>Score Player 2</th>
|
|
||||||
<th>Winner</th>
|
|
||||||
<th>Ball Touches Player 1</th>
|
|
||||||
<th>Ball Touches Player 2</th>
|
|
||||||
<th>Duration</th>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Is Tournament</th>
|
|
||||||
<th>Tournament</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for match in matches %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ match.id }}</td>
|
|
||||||
<td>{{ match.player1.name }}</td>
|
|
||||||
<td>{{ match.player2.name }}</td>
|
|
||||||
<td>{{ match.score_player1 }}</td>
|
|
||||||
<td>{{ match.score_player2 }}</td>
|
|
||||||
<td>{{ match.winner.name }}</td>
|
|
||||||
<td>{{ match.nbr_ball_touch_p1 }}</td>
|
|
||||||
<td>{{ match.nbr_ball_touch_p2 }}</td>
|
|
||||||
<td>{{ match.duration }}</td>
|
|
||||||
<td>{{ match.date }}</td>
|
|
||||||
<td>{{ match.is_tournoi }}</td>
|
|
||||||
<td>{{ match.tournoi.name }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="12">No matches found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Players List</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Players List</h1>
|
|
||||||
<table border="1">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>ID</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Total Matches</th>
|
|
||||||
<th>Total Wins</th>
|
|
||||||
<th>Win Percentage</th>
|
|
||||||
<th>Average Match Score</th>
|
|
||||||
<th>Average Opponent Score</th>
|
|
||||||
<th>Best Score</th>
|
|
||||||
<th>Average Ball Touches</th>
|
|
||||||
<th>Total Duration</th>
|
|
||||||
<th>Average Duration</th>
|
|
||||||
<th>Participated Tournaments</th>
|
|
||||||
<th>Won Tournaments</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for player in players %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ player.id }}</td>
|
|
||||||
<td>{{ player.name }}</td>
|
|
||||||
<td>{{ player.total_match }}</td>
|
|
||||||
<td>{{ player.total_win }}</td>
|
|
||||||
<td>{{ player.p_win }}</td>
|
|
||||||
<td>{{ player.m_score_match }}</td>
|
|
||||||
<td>{{ player.m_score_adv_match }}</td>
|
|
||||||
<td>{{ player.best_score }}</td>
|
|
||||||
<td>{{ player.m_nbr_ball_touch }}</td>
|
|
||||||
<td>{{ player.total_duration }}</td>
|
|
||||||
<td>{{ player.m_duration }}</td>
|
|
||||||
<td>{{ player.num_participated_tournaments }}</td>
|
|
||||||
<td>{{ player.num_won_tournaments }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="13">No players found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Tournaments List</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Tournaments List</h1>
|
|
||||||
<table border="1">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>ID</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Number of Players</th>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Winner</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for tournoi in tournois %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ tournoi.id }}</td>
|
|
||||||
<td>{{ tournoi.name }}</td>
|
|
||||||
<td>{{ tournoi.nbr_player }}</td>
|
|
||||||
<td>{{ tournoi.date }}</td>
|
|
||||||
<td>{{ tournoi.winner.name }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="5">No tournaments found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from . import views
|
from . import views
|
||||||
from .views import player_list, tournoi_list, match_list
|
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from .views import match_list_json, player_list_json, tournoi_list_json
|
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('register_user/', views.register_user, name='register_user'),
|
||||||
path('authenticate_user/', views.authenticate_user, name='authenticate_user'),
|
path('authenticate_user/', views.authenticate_user, name='authenticate_user'),
|
||||||
path('web3/', views.read_data, name='read_data'),
|
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/match_list/', match_list_json, name='match_list_json'),
|
||||||
path('api/player_list/', player_list_json, name='player_list_json'),
|
path('api/player_list/', player_list_json, name='player_list_json'),
|
||||||
path('api/tournoi_list/', tournoi_list_json, name='tournoi_list_json')
|
path('api/tournoi_list/', tournoi_list_json, name='tournoi_list_json')
|
||||||
|
|||||||
@ -4,34 +4,16 @@ from django.shortcuts import get_object_or_404
|
|||||||
from django.db.models import Max, Sum, F
|
from django.db.models import Max, Sum, F
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from channels.db import database_sync_to_async
|
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):
|
async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament):
|
||||||
try:
|
try:
|
||||||
print("here endfortheouche §!!!")
|
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)
|
||||||
|
|
||||||
# Handle Player 1
|
print("ok")
|
||||||
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")
|
print("############# BEFORE MATCH")
|
||||||
await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament)
|
await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament)
|
||||||
@ -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}")
|
print(f"Error in endfortheouche: {e}")
|
||||||
|
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
def get_name(p):
|
def get_player_by_name(name):
|
||||||
print(f"in get_name({p})..")
|
print(f"Checking if player '{name}' exists")
|
||||||
try:
|
exists = Player.objects.filter(name=name).exists()
|
||||||
return Player.objects.get(name=p)
|
print(f"Player exists: {exists}")
|
||||||
except Player.DoesNotExist:
|
return exists
|
||||||
print("get_name() exception")
|
|
||||||
return None
|
|
||||||
|
@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
|
@database_sync_to_async
|
||||||
def create_player(
|
def create_player(
|
||||||
@ -69,8 +72,6 @@ def create_player(
|
|||||||
num_won_tournaments=0
|
num_won_tournaments=0
|
||||||
):
|
):
|
||||||
print("create player !!!")
|
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(
|
player = Player(
|
||||||
name=name,
|
name=name,
|
||||||
@ -150,9 +151,9 @@ def update_player_statistics(player_name):
|
|||||||
return
|
return
|
||||||
|
|
||||||
won_matches = Match.objects.filter(winner=player)
|
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_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)
|
#part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player)
|
||||||
won_tourn = Tournoi.objects.filter(winner=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_player1.aggregate(Sum('score_player1'))['score_player1__sum'] or 0
|
||||||
total_score += matches_as_player2.aggregate(Sum('score_player2'))['score_player2__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
|
total_duration += matches_as_player2.aggregate(Sum('duration'))['duration__sum'] or 0
|
||||||
m_duration = total_duration / total_match
|
m_duration = total_duration / total_match
|
||||||
|
|
||||||
""" total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count()
|
#total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count()
|
||||||
total_win_tourn = won_tourn.count()
|
#total_win_tourn = won_tourn.count()
|
||||||
p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0
|
#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_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_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)
|
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.m_nbr_ball_touch = m_nbr_ball_touch
|
||||||
player.total_duration = total_duration
|
player.total_duration = total_duration
|
||||||
player.m_duration = m_duration
|
player.m_duration = m_duration
|
||||||
""" player.num_participated_tournaments = total_tourn_p
|
# player.num_participated_tournaments = total_tourn_p
|
||||||
player.num_won_tournaments = total_win_tourn """
|
#player.num_won_tournaments = total_win_tourn
|
||||||
|
|
||||||
player.save()
|
player.save()
|
||||||
print("CHAKU IS THE BEST")
|
print("CHAKU IS THE BEST")
|
||||||
@ -206,3 +207,99 @@ def get_player_p_win(player_name):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
######## 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 """
|
||||||
|
|||||||
@ -72,18 +72,6 @@ def get_or_create_token(user):
|
|||||||
|
|
||||||
####################### THEOUCHE PART ############################
|
####################### 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
|
from django.http import JsonResponse
|
||||||
|
|
||||||
def match_list_json(request):
|
def match_list_json(request):
|
||||||
|
|||||||
@ -6,8 +6,9 @@ Django settings for pong project.
|
|||||||
Generated by 'django-admin startproject' using Django 3.2.
|
Generated by 'django-admin startproject' using Django 3.2.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
import os
|
import os
|
||||||
|
import logging.config
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
@ -134,3 +135,38 @@ CHANNEL_LAYERS = {
|
|||||||
'BACKEND': 'channels.layers.InMemoryChannelLayer',
|
'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
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
@ -557,12 +557,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const matchListBody = document.querySelector('#match-list tbody');
|
const matchListBody = document.querySelector('#match-list tbody');
|
||||||
matchListBody.innerHTML = '';
|
matchListBody.innerHTML = '';
|
||||||
|
|
||||||
if (matches.length === 0) {
|
|
||||||
console.log('No matches to display');
|
|
||||||
}
|
|
||||||
|
|
||||||
matches.forEach(match => {
|
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
|
if (matches.length != 0) {
|
||||||
|
matches.forEach(match => {
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${match.id}</td>
|
<td>${match.id}</td>
|
||||||
<td>${match.player1__name}</td>
|
<td>${match.player1__name}</td>
|
||||||
@ -579,6 +576,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
`;
|
`;
|
||||||
matchListBody.appendChild(row);
|
matchListBody.appendChild(row);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
row.innerHTML = `
|
||||||
|
<td colspan="12">No matches found.</td>
|
||||||
|
`;
|
||||||
|
matchListBody.appendChild(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayPlayers(players) {
|
function displayPlayers(players) {
|
||||||
@ -586,12 +589,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const playersListBody = document.querySelector('#player-list tbody');
|
const playersListBody = document.querySelector('#player-list tbody');
|
||||||
playersListBody.innerHTML = '';
|
playersListBody.innerHTML = '';
|
||||||
|
|
||||||
if (players.length === 0) {
|
|
||||||
console.log('No players to display');
|
|
||||||
}
|
|
||||||
|
|
||||||
players.forEach(player => {
|
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
|
if (players.length != 0) {
|
||||||
|
players.forEach(player => {
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${player.id}</td>
|
<td>${player.id}</td>
|
||||||
<td>${player.name}</td>
|
<td>${player.name}</td>
|
||||||
@ -609,6 +609,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
`;
|
`;
|
||||||
playersListBody.appendChild(row);
|
playersListBody.appendChild(row);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
row.innerHTML = `
|
||||||
|
<td colspan="12">No matches found.</td>
|
||||||
|
`
|
||||||
|
playersListBody.appendChild(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayTournois(tournois) {
|
function displayTournois(tournois) {
|
||||||
@ -616,12 +622,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const tournoisListBody = document.querySelector('#tournoi-list tbody');
|
const tournoisListBody = document.querySelector('#tournoi-list tbody');
|
||||||
tournoisListBody.innerHTML = '';
|
tournoisListBody.innerHTML = '';
|
||||||
|
|
||||||
if (tournois.length === 0) {
|
|
||||||
console.log('No tournois to display');
|
|
||||||
}
|
|
||||||
|
|
||||||
tournois.forEach(tournoi => {
|
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
|
if (tournois.length != 0) {
|
||||||
|
tournois.forEach(tournoi => {
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${tournoi.id}</td>
|
<td>${tournoi.id}</td>
|
||||||
<td>${tournoi.name}</td>
|
<td>${tournoi.name}</td>
|
||||||
@ -631,6 +634,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
`;
|
`;
|
||||||
tournoisListBody.appendChild(row);
|
tournoisListBody.appendChild(row);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
row.innerHTML = `
|
||||||
|
<td colspan="12">No matches found.</td>
|
||||||
|
`
|
||||||
|
tournoisListBody.appendChild(row);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////// END BURGER BUTTON ////////////////////////////////
|
////////////////////////////// END BURGER BUTTON ////////////////////////////////
|
||||||
|
|||||||
@ -146,26 +146,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for match in matches %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ match.id }}</td>
|
|
||||||
<td>{{ match.player1.name }}</td>
|
|
||||||
<td>{{ match.player2.name }}</td>
|
|
||||||
<td>{{ match.score_player1 }}</td>
|
|
||||||
<td>{{ match.score_player2 }}</td>
|
|
||||||
<td>{{ match.winner.name }}</td>
|
|
||||||
<td>{{ match.nbr_ball_touch_p1 }}</td>
|
|
||||||
<td>{{ match.nbr_ball_touch_p2 }}</td>
|
|
||||||
<td>{{ match.duration }}</td>
|
|
||||||
<td>{{ match.date }}</td>
|
|
||||||
<td>{{ match.is_tournoi }}</td>
|
|
||||||
<td>{{ match.tournoi.name }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="12">No matches found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -191,27 +171,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for player in players %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ player.id }}</td>
|
|
||||||
<td>{{ player.name }}</td>
|
|
||||||
<td>{{ player.total_match }}</td>
|
|
||||||
<td>{{ player.total_win }}</td>
|
|
||||||
<td>{{ player.p_win }}</td>
|
|
||||||
<td>{{ player.m_score_match }}</td>
|
|
||||||
<td>{{ player.m_score_adv_match }}</td>
|
|
||||||
<td>{{ player.best_score }}</td>
|
|
||||||
<td>{{ player.m_nbr_ball_touch }}</td>
|
|
||||||
<td>{{ player.total_duration }}</td>
|
|
||||||
<td>{{ player.m_duration }}</td>
|
|
||||||
<td>{{ player.num_participated_tournaments }}</td>
|
|
||||||
<td>{{ player.num_won_tournaments }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="13">No players found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -229,19 +188,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for tournoi in tournois %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ tournoi.id }}</td>
|
|
||||||
<td>{{ tournoi.name }}</td>
|
|
||||||
<td>{{ tournoi.nbr_player }}</td>
|
|
||||||
<td>{{ tournoi.date }}</td>
|
|
||||||
<td>{{ tournoi.winner.name }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="14">No tournois found.</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -5,4 +5,4 @@ channels
|
|||||||
daphne
|
daphne
|
||||||
djangorestframework
|
djangorestframework
|
||||||
web3
|
web3
|
||||||
asyncpg
|
python-json-logger==2.0.7
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user