]> git.immae.eu Git - perso/Denise/bingo.git/commitdiff
création du projet... master
authorDenise sur Lya <sekhmet@lya>
Tue, 27 Jul 2021 12:37:33 +0000 (14:37 +0200)
committerDenise sur Lya <sekhmet@lya>
Tue, 27 Jul 2021 12:37:33 +0000 (14:37 +0200)
app.py [new file with mode: 0644]
config.py [new file with mode: 0644]
data_textes.py [new file with mode: 0644]
gere_erreurs.py [new file with mode: 0644]
gere_grille.py [new file with mode: 0644]
static/outilspage.js [new file with mode: 0644]
static/style.css [new file with mode: 0644]
templates/base.html [new file with mode: 0644]
templates/custom.html [new file with mode: 0644]
templates/faq.html [new file with mode: 0644]
templates/index.html [new file with mode: 0644]

diff --git a/app.py b/app.py
new file mode 100644 (file)
index 0000000..8b558ea
--- /dev/null
+++ b/app.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Jul 26 17:31:48 2021
+
+@author: sekhmet
+"""
+
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import flask
+from data_textes import liste_textes
+import gere_grille as g
+import gere_erreurs as e
+from config import DEFAUT, CONFIG
+
+
+def initialise_mode_beta():
+    global beta
+    hote = flask.request.host
+    if hote[:4] == "beta":
+        print("** Mode bêta !**")
+        return True
+    else:
+        return False
+
+
+app = flask.Flask(__name__)
+
+
+@app.route('/', methods=["GET", "POST"])
+def index():
+    liste_err = e.initialise_erreurs()
+    idg = flask.request.args.get("grille", "") # Id de grille passée en param (ou pas)
+    if idg != "": # Si on a mis un url de grille
+        conf = g.decode_grille(idg, liste_err)
+        if conf == {}: # Erreur à la génération
+             bingo = g.genere_grille(DEFAUT, liste_textes)
+             conf = DEFAUT.copy()
+             e.erreur("L'url de la grille n'est pas valide...", liste_err)
+        else:
+            bingo=conf["grille"]
+    else:
+        # On récupère les données post (et ça sera défaut si y'a rien)
+        if flask.request.method == "POST":
+            conf = g.gere_donnees_custom(flask.request.form, liste_err)
+        else:
+            conf= DEFAUT.copy()
+        bingo = g.genere_grille(conf, liste_textes) # aléatoire
+        
+    chainecode = g.encode_grille(conf, bingo, liste_err)
+    
+    return flask.render_template("index.html", bingo=bingo, chainecode=chainecode, conf=conf, e=liste_err[0]+liste_err[1]+liste_err[2])
+    
+@app.route('/custom')
+def custom():
+    liste_err = e.initialise_erreurs()
+    return flask.render_template("custom.html", DEFAUT=DEFAUT,CONFIG=CONFIG, e=liste_err[0]+liste_err[1]+liste_err[2])
+
+if __name__ == "__main__":
+ #   print("Mode debug maison : "+str(niveau_debug))
+    app.run(host='0.0.0.0',debug=True)
\ No newline at end of file
diff --git a/config.py b/config.py
new file mode 100644 (file)
index 0000000..deb461a
--- /dev/null
+++ b/config.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Configuration générale
+"""
+
+# Configuration par défaut
+DEFAUT = {}
+
+DEFAUT["titre"] = "Le bingo de l'allaitement"
+
+DEFAUT["nblignes"] = 4
+DEFAUT["nbcolonnes"] = 3
+DEFAUT["nbcasesvides"] = 0
+
+
+# Configuration
+
+CONFIG = {}
+CONFIG["lmax_titre"] = 50
+CONFIG["maxlignes"] = 20
+CONFIG["minlignes"] = 1
+CONFIG["maxcolonnes"] = 20
+CONFIG["mincolonnes"] = 1
\ No newline at end of file
diff --git a/data_textes.py b/data_textes.py
new file mode 100644 (file)
index 0000000..8082ecf
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Jul 26 22:50:08 2021
+
+@author: sekhmet
+"""
+
+liste_textes = [
+        "Tu vas pas l'allaiter jusqu'à [âge quelconque] !",
+        "Tu es sûre que tu as assez de lait ?",
+        "Quand est-ce que tu vas lui donner du lait normal ?",
+        "Il/elle fait ses nuits ?",
+        "Il/elle dort encore avec vous ?",
+        "Laisse le/la pleurer il/elle finira bien par dormir (et/ou ça lui fera les poumons).",
+        "Ton lait n'est pas/plus assez nourrissant.",
+        "Il/elle doit apprendre à se détacher de maman.",
+        "Tu as pris combien de kilos ?",
+        "Donne lui un biberon, il/elle fera ses nuits.",
+        "Tu arrêteras quand il/elle aura des dents, puisqu'il/elle va te mordre",
+        
+        ]
\ No newline at end of file
diff --git a/gere_erreurs.py b/gere_erreurs.py
new file mode 100644 (file)
index 0000000..0a12018
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Created on Tue Jul 27 11:16:54 2021
+
+@author: sekhmet
+"""
+
+## Gestion des erreurs en flask
+import sys
+
+niveau_debug = ("debug" in sys.argv)
+
+def initialise_erreurs():
+    """ retourne trois listes vides, erreurs fatales (0), warnings(1), debug(2):"""
+    return ([],[],[])
+
+
+def erreur(message,listeerreurs):
+    """ en cas d'erreur où on ne peut pas continuer
+    message est une chaîne"""
+    print("** Erreur fatale : "+message)
+    listeerreurs[0].append("** Erreur : "+message)
+
+def warning(message,listeerreurs):
+    """ En cas d'avertissement mais on peut quand même continuer """
+    print("** Warning : "+message)
+    message = "Alerte : "+message
+    if message not in listeerreurs[1]:
+        listeerreurs[1].append(message)
+    
+def debug(message,listeerreurs):
+    global niveau_debug
+    if niveau_debug:
+        print("##Debug : "+message)
+        listeerreurs[2].append("# Debug : "+message)
+              
\ No newline at end of file
diff --git a/gere_grille.py b/gere_grille.py
new file mode 100644 (file)
index 0000000..9a472ed
--- /dev/null
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Jul 26 22:58:28 2021
+
+@author: sekhmet
+"""
+import random
+import zlib, base64, json
+import gere_erreurs as e
+from config import DEFAUT, CONFIG
+
+def genere_grille(config, textes):
+    """ génère une grille avec des éléments aléatoires du tableau textes. Si y'a pas assez, on complète aléatoirement avec des 0.
+    config contient tout ce qu'on veut pour la grille"""
+    
+    nblignes, nbcol = config["nblignes"], config["nbcolonnes"]
+    
+    # Créer la grille
+    grille = [ [""]*nbcol for i in range(nblignes)]
+    
+    nbdata = nbcol*nblignes - config["nbcasesvides"] # Nombre d'entrées
+    
+    # Créer le sous-tableau
+    if len(textes)>= nbdata: # Si y'a assez de textes
+        soustab = random.sample(textes, nbdata) + ["0"]*config["nbcasesvides"]
+    else:
+        # On met tous les textes + complète avec des "0"
+        soustab = textes + ["0"]*(nbcol*nblignes - len(textes))
+    random.shuffle(soustab)
+    #print(soustab)
+    
+    # On met tout ça dans la grille
+    for i in range(nblignes):
+        for j in range(nbcol):
+            grille[i][j] = soustab[i*nbcol+j]
+            
+    return grille
+
+def encode_grille(config, grille, liste_err):
+    """ grille est un tableau double qu'on veut sauvegarder.
+    config est la configuration (on va garder le titre avec)
+    Renvoie une chaîne de caractères qui encode cette grille
+    de manière condensée. Renvoie une chaîne cheloue"""
+    # Chaîne de caractère
+    data = {"titre": config["titre"], "grille": grille}
+    chaine = json.dumps(data)
+    code = zlib.compress(chaine.encode())
+    chaineencodee = str(base64.urlsafe_b64encode(code))
+    e.debug(chaineencodee, liste_err)
+    return chaineencodee[2:-1] # Enlever le b' devant et le ' à la fin
+
+def decode_grille(chaineencodee, liste_err):
+    """ l'inverse de la fonction précédente : renvoie le dictionnaire
+    avec les params et la grille reconstituée
+    """
+    e.debug(chaineencodee, liste_err)
+    b2 = base64.urlsafe_b64decode(chaineencodee)
+    try:
+        decodee = zlib.decompress(b2)
+    except:
+        e.erreur("Impossible de décoder la chaîne : "+chaineencodee, liste_err)
+        return {}
+    # Remettre ça en python
+    data = json.loads(decodee)
+    return data
+
+###########################
+
+def gere_donnees_custom(data, liste_err):
+    """ data est le dictionnaire de requête. Gère les données reçues
+    et en fait un dictionnaire propre, en mettant les défauts là où
+    c'est pas bon"""
+    
+    conf =DEFAUT.copy()
+    
+    ## Le titre
+    t = data.get("titre", "")
+    if len(t) > 0:
+        conf["titre"] = t[0:CONFIG["lmax_titre"]]
+        
+    # Les dimensions
+    conf["nblignes"] = minimaxi(data.get("nblignes",""), CONFIG["minlignes"], CONFIG["maxlignes"], DEFAUT["nblignes"], liste_err)
+    conf["nbcolonnes"] = minimaxi(data.get("nbcolonnes",""), CONFIG["mincolonnes"], CONFIG["maxcolonnes"], DEFAUT["nbcolonnes"], liste_err)
+    
+    # Les cases vides
+    conf["nbcasesvides"] = minimaxi(data.get("nbcasesvides",""), 0, CONFIG["maxlignes"]*CONFIG["maxcolonnes"], DEFAUT["nbcasesvides"], liste_err)
+    
+    return conf
+###
+def minimaxi(donnee, mini, maxi, defaut, liste_err):
+    """ donnee est une chaine qui est censée être un nombre entier.
+    On vérifie que la donnée est valide, qu'elle est bien dans l'inter
+    valle mini, maxi et si ça foire on met le défaut"""
+    try:
+        x = int(donnee)
+    except:
+        e.warning("La donnée "+donnee+ "est invalide !", liste_err)
+        x = defaut
+    x = max(mini, min(x, maxi))
+    return x
\ No newline at end of file
diff --git a/static/outilspage.js b/static/outilspage.js
new file mode 100644 (file)
index 0000000..b8db8b3
--- /dev/null
@@ -0,0 +1,153 @@
+/* Calcul des scores */
+var points_par_case = 1 ;
+var points_par_ligne = 10 ;
+
+
+
+// Couleurs des cases
+var couleur_base = "rgb(238, 238, 238)" ;
+var couleur_valide = 'rgb(255, 136, 136)' ;
+
+
+// Valide la case et la colore en rouge
+function validecase(elem) {
+       elem.style.backgroundColor = couleur_valide ;
+       
+       detectelignes() ;
+}
+
+// efface la grille
+function effacegrille() {
+       var table=document.getElementById("grille") ;
+       var listetd = table.getElementsByTagName("td") ;
+       for (var i=0; i< listetd.length; i++){
+               listetd[i].style.backgroundColor = couleur_base ;
+       }
+       metscore(0) ;
+}
+
+// mettre à jour le score si on veut
+function metscore(score) {
+       document.getElementById("score").innerHTML = score ;
+}
+
+// Compte les lignes, colonnes et diagonales de la grille et met à jour le score
+function detectelignes(elem) {
+       var table=document.getElementById("grille") ;
+       var listelignes = table.getElementsByTagName("tr") ;
+       var nblignes = listelignes.length ;
+       var nbcolonnes = listelignes[0].children.length ;
+       var i, j ;
+       
+       // lignes
+       var nb_lignes_completes = 0 ;
+       var remplie ;
+       for(i=0; i<nblignes; i++) {
+               remplie = true ;
+               for(j=0; j<nbcolonnes; j++) {
+                       //alert(j) ;
+                       //alert(listelignes[i].children[j].style.backgroundColor) ;
+                       if(listelignes[i].children[j].style.backgroundColor != couleur_valide)  {
+                               // c'est pas une ligne, dommage
+                               remplie = false ;
+                               //alert("la ligne "+i+"n'est pas remplie, vu à la colonne "+j) ;
+                               break
+                       }
+               }
+               if(remplie) {
+                       nb_lignes_completes+=1 ;
+               }
+       }
+       
+       // Colonnes
+       var nb_colonnes_completes = 0 ;
+       for(j=0; j<nbcolonnes; j++) {
+               remplie = true ;
+               for (i=0; i<nblignes; i++) {
+                       if(listelignes[i].children[j].style.backgroundColor != couleur_valide)  {
+                               // c'est pas une colonne, dommage
+                               remplie = false ;
+                               break
+                       }
+               }
+               if (remplie) {
+                       nb_colonnes_completes+=1 ;
+               }
+       }
+
+       // Diagonales.
+       var nb_diagonales_1 = 0 ;
+       var nb_diagonales_2 = 0 ;
+       if(nblignes <= nbcolonnes) {
+               // Les diagonales se comptent horizontalement : "\\\" et "///"
+               for(i=0; i<nbcolonnes - nblignes +1; i++) {
+                       // diagonales "\"
+                       remplie=true ;
+                       for(j=0; j<nblignes; j++) {
+                               if(listelignes[j].children[i+j].style.backgroundColor != couleur_valide)        {
+                                       remplie = false
+                                       break
+                               }
+                       }
+                       if (remplie) {
+                               nb_diagonales_1+=1
+                       }
+                       
+                       // diagonales "/"
+                       remplie=true ;
+                       for(j=0; j<nblignes; j++) {
+                               if(listelignes[j].children[nbcolonnes-i-j-1].style.backgroundColor != couleur_valide)   {
+                                       remplie = false
+                                       break
+                               }
+                       }
+                       if (remplie) {
+                               nb_diagonales_2+=1
+                       }
+               }
+               
+       } else { // les diagonales vont se compter "verticalement"
+               for(i=0; i<nblignes - nbcolonnes +1; i++) {
+                       // diagonales "\"
+                       remplie=true ;
+                       for(j=0; j<nbcolonnes; j++) {
+                               if(listelignes[i+j].children[j].style.backgroundColor != couleur_valide)        {
+                                       remplie = false
+                                       break
+                               }
+                       }
+                       if (remplie) {
+                               nb_diagonales_1+=1
+                       }
+                       
+                       // diagonales "/"
+                       remplie=true ;
+                       for(j=0; j<nbcolonnes; j++) {
+                               if(listelignes[nblignes -i-j-1].children[j].style.backgroundColor != couleur_valide)    {
+                                       remplie = false
+                                       break
+                               }
+                       }
+                       if (remplie) {
+                               nb_diagonales_2+=1
+                       }
+               }
+               
+               
+       }
+       // Compter les cases utilisées
+       var nbcases = 0 ;
+       for(i=0; i<nblignes; i++) {
+               for(j=0; j<nbcolonnes; j++) {
+                       if (listelignes[i].children[j].style.backgroundColor == couleur_valide) {
+                               nbcases+=1
+                       }
+               }
+               
+       }
+       
+       
+       // Mettre le score à jour
+       score = (nb_lignes_completes + nb_colonnes_completes + nb_diagonales_1 + nb_diagonales_2) *points_par_ligne + nbcases ;
+       metscore(score) ;
+}
diff --git a/static/style.css b/static/style.css
new file mode 100644 (file)
index 0000000..fa5f191
--- /dev/null
@@ -0,0 +1,38 @@
+/* Styles divers */
+.cliquable {
+       cursor: pointer;
+       text-decoration: underline;
+}
+
+.petit {
+       font-size: 0.8em;
+}
+
+
+/* Grille du bingo */
+#grille {
+       background-color: #F8F8F8 ;
+       padding: 1px ;
+       margin: 30px ;
+       border: 1px solid black ;
+}
+
+#grille td {
+       background-color:#EEEEEE;
+       border: 1px solid black;
+       margin: 0px;
+       padding: 3px ;
+       text-align: center ;
+}
+
+#grille td.vide {
+       background-color:#999999 ;
+}
+
+/* Formulaire page custom */
+.texte {
+       width:20em
+}
+
+.data {
+       width:3em
diff --git a/templates/base.html b/templates/base.html
new file mode 100644 (file)
index 0000000..028aaa9
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+
+<html lang="fr">
+    <head>
+        <meta charset="UTF-8" >
+        <title>Le bingo de l'allaitement</title>
+               <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"  type="text/css">
+        <!--<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">-->
+
+        <script src="static/outilspage.js"></script>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+    </head>
+
+    <body>
+               
+               {% block contenu %}{% endblock %}
+               
+       <hr>
+<div id="basdepage">
+               <nav>
+               <a href="/">Grille aléatoire</a> |
+               <a href="/custom">Créer une grille personnalisée</a> |
+<!--           <a href="/apropos">À propos</a> |-->
+
+               </nav> 
+</div>
+       
+               
+       </body>
+</html>
diff --git a/templates/custom.html b/templates/custom.html
new file mode 100644 (file)
index 0000000..cc5521c
--- /dev/null
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+{% block contenu %}
+<h1>Créer une grille personnalisée</h1>
+
+{% if e | length >0 %}
+<div id="erreurs">
+       <h2>Log d'erreurs</h2>
+       <ul>
+               {% for err in e %}
+               <li>{{ err }}</li>
+               {% endfor %}
+       </ul>
+</div>
+{% endif %}
+
+<div id="contenu">
+
+<form action="/" method="POST">
+
+<ul>
+       <li>Titre de la page : <input class="texte" type="text" name="titre" value="{{ DEFAUT.titre }}"></li>
+       <li>Nombre de lignes : <input class="data" type="number" min="{{ CONFIG.minlignes }}" max="{{ CONFIG.maxlignes}}" name="nblignes" value="{{ DEFAUT.nblignes }}"></li>
+       <li>Nombre de colonnes : <input class="data" type="number" min="{{ CONFIG.mincolonnes }}" max="{{ CONFIG.maxcolonnes }}" name="nbcolonnes" value="{{ DEFAUT.nbcolonnes }}"></li>
+       <li>Nombre de cases vides : <input class="data" type="number" min="0" name="nbcasesvides" value="{{ DEFAUT.nbcasesvides }}"> <span class="petit">Remarque : s'il n'y a pas assez de données, la grille sera automatiquement complétée par des cass vides.</span></li>
+
+
+</ul>
+<input type="submit" name="zou" value="Je veux une grille !">
+
+</form>
+
+</div>
+
+
+{% endblock %}
diff --git a/templates/faq.html b/templates/faq.html
new file mode 100644 (file)
index 0000000..162f68d
--- /dev/null
@@ -0,0 +1,30 @@
+{% extends "base.html" %}
+{% block contenu %}
+<h2>Foire Aux Questions (FAQ)</h2>
+
+<div id="sommaire">
+<ul>{% for cat in lcateg %}
+<li><a href="#{{ cat }}">{{ cat }}</a></li>
+{% endfor %}
+</ul>
+</div>
+
+<div id="questionsreponses">
+{% for i in range(lcateg|length) %}
+{% set qr = tableqr[i] %}
+
+<h3 id="{{ lcateg[i] }}">{{ lcateg[i] }}</h3>
+<ul>
+       {% for (q,r) in qr %}
+       <li><p><strong>Q : </strong>{{ q|safe }}</p>
+       <p><strong>R : </strong>{{ r|safe }}</p>
+       </li>
+       {% endfor %}
+</ul>
+
+
+{% endfor %}
+</div>
+
+
+{% endblock %}
diff --git a/templates/index.html b/templates/index.html
new file mode 100644 (file)
index 0000000..852fdd7
--- /dev/null
@@ -0,0 +1,42 @@
+{% extends "base.html" %}
+{% block contenu %}
+<h1>{{ conf.titre }}</h1>
+
+{% if e | length >0 %}
+<div id="erreurs">
+       <h2>Log d'erreurs</h2>
+       <ul>
+               {% for err in e %}
+               <li>{{ err }}</li>
+               {% endfor %}
+       </ul>
+</div>
+{% endif %}
+
+<div id="contenu">
+
+<p>Cochez la case dès que vous entendez une réplique idiote !</p>
+<table id="grille">
+{% for ligne in bingo %}
+<tr>{% for elt in ligne %}
+       {% if elt == "0" %}
+       <td class="vide"></td>
+       {% else %}
+       <td onclick='validecase(this)'>{{ elt }}</td>
+       {% endif %}
+       {% endfor %}
+</tr>
+{% endfor %}
+</table>
+
+<p>Score : <span id="score">0</span></p>
+
+<p onclick="effacegrille()" class="cliquable">Effacer la grille</p>
+
+<hr>
+<a href="/?grille={{ chainecode }}">Lien permanent vers cette grille</a>
+
+</div>
+
+
+{% endblock %}