mirror of
https://github.com/AudebertAdrien/ft_transcendence.git
synced 2025-12-16 05:57:48 +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
|
||||
PWD_PATH=${PWD}
|
||||
PROJECT_PATH=${PWD_PATH}/pong
|
||||
DJANGO_LOGS=${PWD_PATH}/logs
|
||||
|
||||
# ElasticSearch settings
|
||||
STACK_VERSION=8.14.3
|
||||
|
||||
@ -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 {}
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
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
|
||||
$(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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 . 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')
|
||||
|
||||
@ -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 """
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -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 = `
|
||||
<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>
|
||||
`;
|
||||
matchListBody.appendChild(row);
|
||||
});
|
||||
const row = document.createElement('tr');
|
||||
if (matches.length != 0) {
|
||||
matches.forEach(match => {
|
||||
row.innerHTML = `
|
||||
<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>
|
||||
`;
|
||||
matchListBody.appendChild(row);
|
||||
});
|
||||
} else {
|
||||
row.innerHTML = `
|
||||
<td colspan="12">No matches found.</td>
|
||||
`;
|
||||
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 = `
|
||||
<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>
|
||||
`;
|
||||
playersListBody.appendChild(row);
|
||||
});
|
||||
} else {
|
||||
row.innerHTML = `
|
||||
<td colspan="12">No matches found.</td>
|
||||
`
|
||||
playersListBody.appendChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
players.forEach(player => {
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<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>
|
||||
`;
|
||||
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 = `
|
||||
<td>${tournoi.id}</td>
|
||||
<td>${tournoi.name}</td>
|
||||
<td>${tournoi.nbr_player}</td>
|
||||
<td>${tournoi.date}</td>
|
||||
<td>${tournoi.winner.name}</td>
|
||||
`;
|
||||
tournoisListBody.appendChild(row);
|
||||
});
|
||||
const row = document.createElement('tr');
|
||||
if (tournois.length != 0) {
|
||||
tournois.forEach(tournoi => {
|
||||
row.innerHTML = `
|
||||
<td>${tournoi.id}</td>
|
||||
<td>${tournoi.name}</td>
|
||||
<td>${tournoi.nbr_player}</td>
|
||||
<td>${tournoi.date}</td>
|
||||
<td>${tournoi.winner.name}</td>
|
||||
`;
|
||||
tournoisListBody.appendChild(row);
|
||||
});
|
||||
} else {
|
||||
row.innerHTML = `
|
||||
<td colspan="12">No matches found.</td>
|
||||
`
|
||||
tournoisListBody.appendChild(row);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////// END BURGER BUTTON ////////////////////////////////
|
||||
|
||||
@ -146,27 +146,7 @@
|
||||
</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>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@ -191,28 +171,7 @@
|
||||
</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>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@ -228,21 +187,8 @@
|
||||
<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="14">No tournois found.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
@ -5,4 +5,4 @@ channels
|
||||
daphne
|
||||
djangorestframework
|
||||
web3
|
||||
asyncpg
|
||||
python-json-logger==2.0.7
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user