refactor repo
This commit is contained in:
22
backend_part1/jeu-concours/app/Dockerfile
Normal file
22
backend_part1/jeu-concours/app/Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
# la ligne du dessus est la version de syntaxe du format Dockerfile
|
||||
|
||||
# Récupère l'image docker python:3.10-alpine sur DockerHub
|
||||
# AS builder permet de nommer cette image sour la référence "builder" pour la suite du fichier, à la manière d'un alias
|
||||
FROM --platform=$BUILDPLATFORM python:3.10-alpine AS builder
|
||||
|
||||
# définie le répertoire de travail, les commandes suivantes seront jouées à partir de ce répertoire
|
||||
WORKDIR /app
|
||||
|
||||
# on copie requirements.txt et app/ dans l'image
|
||||
COPY requirements.txt /app
|
||||
# installe les dépendance python à l'aide de PIP, disponible dans l'image suite au téléchargement de l'image python:3.10-alpine
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip3 install -r requirements.txt
|
||||
|
||||
# Copie l'ensemble des fichiers dans /app,
|
||||
COPY . /app
|
||||
|
||||
# Ces deux lignes permet au lancement de l'image, d'executer python3 avec comme argument app.py
|
||||
ENTRYPOINT ["python3"]
|
||||
CMD ["app.py"]
|
52
backend_part1/jeu-concours/app/app.py
Normal file
52
backend_part1/jeu-concours/app/app.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import logging
|
||||
from flask import Flask, render_template
|
||||
from redis import Redis
|
||||
from pygelf import GelfTcpHandler, GelfUdpHandler, GelfTlsHandler, GelfHttpHandler
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
visitor_count = 0
|
||||
|
||||
# CONF
|
||||
cache_port = os.getenv('CACHE_PORT')
|
||||
cache_host = os.getenv('CACHE_HOST')
|
||||
app_port = os.getenv('APP_PORT')
|
||||
|
||||
def set_logger():
|
||||
log_handler = GelfUdpHandler(host='logstash' , port=12201)
|
||||
app.logger.addHandler(log_handler)
|
||||
# app.logger.setLevel(logging.INFO)
|
||||
|
||||
# GET REDIS
|
||||
def get_redis_connection():
|
||||
return Redis(host=cache_host, port=cache_port)
|
||||
|
||||
def init_visitor_count(redis_db: Redis):
|
||||
key = 'visitor_count'
|
||||
if not redis_db.exists(key):
|
||||
redis_db.set(key, 0)
|
||||
|
||||
# MAIN ROUTE
|
||||
@app.route('/')
|
||||
def index():
|
||||
try:
|
||||
set_logger()
|
||||
except Exception as e:
|
||||
print('Error: logger not available')
|
||||
|
||||
try:
|
||||
redis_db = get_redis_connection()
|
||||
init_visitor_count(redis_db)
|
||||
visitor_count = redis_db.incr('visitor_count')
|
||||
app.logger.info("Visit page")
|
||||
except Exception as e:
|
||||
return render_template('erreur.html', message=str(e))
|
||||
|
||||
if visitor_count == 10:
|
||||
return render_template('winner.html')
|
||||
|
||||
return render_template('index.html', visitor_count=visitor_count)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=app_port)
|
1
backend_part1/jeu-concours/app/requirements.txt
Normal file
1
backend_part1/jeu-concours/app/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
flask
|
BIN
backend_part1/jeu-concours/app/static/congratulations.png
Normal file
BIN
backend_part1/jeu-concours/app/static/congratulations.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 MiB |
BIN
backend_part1/jeu-concours/app/static/jetons.png
Normal file
BIN
backend_part1/jeu-concours/app/static/jetons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 MiB |
BIN
backend_part1/jeu-concours/app/static/oh_well.png
Normal file
BIN
backend_part1/jeu-concours/app/static/oh_well.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 826 KiB |
71
backend_part1/jeu-concours/app/static/style.css
Normal file
71
backend_part1/jeu-concours/app/static/style.css
Normal file
@@ -0,0 +1,71 @@
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
text-align: center;
|
||||
padding: 50px;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: #f2f2f2;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* Conteneur de l'image */
|
||||
.img-container {
|
||||
width: 100%; /* Largeur complète */
|
||||
height: 150px; /* Hauteur fixée à 150px */
|
||||
overflow: hidden; /* Masquer tout ce qui dépasse */
|
||||
}
|
||||
|
||||
.oh-well {
|
||||
width: auto;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.congratulations {
|
||||
width: auto;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
/* Conteneur de l'image */
|
||||
.img-container-bottom {
|
||||
height: 150px;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Style pour l'image des jetons */
|
||||
.img-jetons {
|
||||
width: 100%; /* Largeur complète */
|
||||
height: auto; /* Hauteur automatique pour maintenir le ratio */
|
||||
display: block; /* Assurer que l'image s'affiche correctement */
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: #c3c3c3;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
font-size: 0.8em;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
footer p {
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
color: #000;
|
||||
}
|
69
backend_part1/jeu-concours/app/templates/10.html
Normal file
69
backend_part1/jeu-concours/app/templates/10.html
Normal file
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- saved from url=(0087)https://moodle.ynov.com/pluginfile.php/1100513/mod_resource/content/0/winner%20tpl.html -->
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Jeu Concours</title>
|
||||
<link rel="stylesheet" href="../static/style.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com/"><link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin=""><link rel="stylesheet" href="./Jeu Concours_files/css2" class="wtd-font"><link rel="stylesheet" href="./Jeu Concours_files/css2(1)" class="wtd-font"></head>
|
||||
<body>
|
||||
<div class="img-container">
|
||||
<img src="../static/jetons.png" alt="Jetons de Casino" class="img-jetons">
|
||||
</div>
|
||||
<h1>Bienvenue sur notre jeu concours !</h1>
|
||||
<p class="congrat-text">Vous êtes le 10ème visiteur ! Bravo ! Vous avez gagné votre diplôme !</p>
|
||||
<img src="../static/congratulations.png" alt="Félicitations" class="congratulations" "="">
|
||||
|
||||
<div class="img-container-bottom">
|
||||
<img src="../static/jetons.png" alt="Jetons de Casino" class="img-jetons">
|
||||
</div>
|
||||
<footer>
|
||||
<p>
|
||||
Ce jeu concours est fourni à titre de divertissement uniquement. Aucun achat nécessaire.
|
||||
Toute ressemblance avec des personnes réelles, vivantes ou décédées, ou des événements réels est purement fortuite.
|
||||
Les conditions et restrictions s'appliquent. Voir les détails complets du jeu pour plus d'informations.
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
|
||||
<script id="define-custom-element-wtd-root">
|
||||
(() => {
|
||||
window.customElements.whenDefined('wtd-root').then(() => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('customElements.defined', {
|
||||
detail: {
|
||||
name: 'wtd-root',
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
if (window.customElements.get('wtd-root')) return;
|
||||
|
||||
window.customElements.define('wtd-root', class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script><wtd-root id="cashback"><template shadowrootmode="open"><div id="root"></div><link rel="stylesheet" href="chrome-extension://emnoomldgleagdjapdeckpmebokijail/tailwind/tailwind.css"></template></wtd-root><script id="define-custom-element-wtd-div">
|
||||
(() => {
|
||||
window.customElements.whenDefined('wtd-div').then(() => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('customElements.defined', {
|
||||
detail: {
|
||||
name: 'wtd-div',
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
if (window.customElements.get('wtd-div')) return;
|
||||
|
||||
window.customElements.define('wtd-div', class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script><wtd-div id="wanteeedContainer" style="position: fixed; display: block; top: 0px; right: 0px; z-index: 2147483647;"><wtd-root id="comparator"><template shadowrootmode="open"><div id="root"><div class="pointer-events-none z-[2147483647] flex select-none flex-col items-end overflow-hidden font-sans antialiased"></div></div><link rel="stylesheet" href="chrome-extension://emnoomldgleagdjapdeckpmebokijail/tailwind/tailwind.css"></template></wtd-root><iframe id="wanteeedPanel" data-version="1.134.0" allowtransparency="true" style="background-color: rgb(255, 255, 255); border: none; border-radius: 3px; box-shadow: rgb(181, 181, 181) 1px 1px 3px 2px; clip: auto; display: none; margin-left: auto; margin-right: 12px; margin-top: 12px; position: relative; z-index: 2147483647; height: 1px; width: 1px;" src="./Jeu Concours_files/saved_resource.html"></iframe></wtd-div><iframe id="wanteeedTestMaker" data-version="1.134.0" allowtransparency="true" style="border: none; clip: auto; display: none; left: 0px; overflow: hidden; position: fixed; top: 10px; transition: all 0.2s ease-out 0s; z-index: 45739864; height: 1px; width: 1px;" src="./Jeu Concours_files/saved_resource(1).html"></iframe></body></html>
|
27
backend_part1/jeu-concours/app/templates/index.html
Normal file
27
backend_part1/jeu-concours/app/templates/index.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Jeu Concours</title>
|
||||
<link rel="stylesheet" href="../static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="img-container">
|
||||
<img src="../static/jetons.png" alt="Jetons de Casino" class="img-jetons">
|
||||
</div>
|
||||
<h1>Bienvenue sur notre jeu concours !</h1>
|
||||
<p>Vous êtes le {{ visitor_count }}ème visiteur.</p>
|
||||
<p>Retentez votre chance une autre fois !</p>
|
||||
<img src="../static/oh_well.png" alt="Désolé" class="oh-well">
|
||||
|
||||
<div class="img-container-bottom">
|
||||
<img src="../static//jetons.png" alt="Jetons de Casino" class="img-jetons">
|
||||
</div>
|
||||
<footer>
|
||||
<p>
|
||||
Ce jeu concours est fourni à titre de divertissement uniquement. Aucun achat nécessaire.
|
||||
Toute ressemblance avec des personnes réelles, vivantes ou décédées, ou des événements réels est purement fortuite.
|
||||
Les conditions et restrictions s'appliquent. Voir les détails complets du jeu pour plus d'informations.
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
20
backend_part1/jeu-concours/app/tests/test__10th_visit.py
Normal file
20
backend_part1/jeu-concours/app/tests/test__10th_visit.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import unittest
|
||||
from app import app
|
||||
|
||||
class FlaskAppTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# Crée un client de test
|
||||
self.app = app.test_client()
|
||||
self.app.testing = True
|
||||
|
||||
def test_winner_template_rendered_on_10th_visit(self):
|
||||
# Test pour vérifier si le template winner.html est rendu après le 10ème visite
|
||||
for _ in range(9):
|
||||
self.app.get('/')
|
||||
response = self.app.get('/')
|
||||
# Cette assertion dépend de la manière dont vous affichez le contenu dans 'winner.html'
|
||||
self.assertIn('Vous avez gagné votre diplôme', response.get_data(as_text=True))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
18
backend_part1/jeu-concours/app/tests/test_app.py
Normal file
18
backend_part1/jeu-concours/app/tests/test_app.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import unittest
|
||||
from app import app
|
||||
|
||||
class FlaskAppTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# Crée un client de test
|
||||
self.app = app.test_client()
|
||||
self.app.testing = True
|
||||
|
||||
def test_index_page(self):
|
||||
# Test pour s'assurer que l'index se charge correctement
|
||||
response = self.app.get('/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user