from bottle import route, run, template, static_file, get, request, response, redirect from os.path import dirname, join from sessions import get_or_create_session, save_session, delete_session import hashlib # Page d'accueil @route('/') def index(): return template('index.html') # Bonjour personnalisé @route('/hello/') def hello_user(name): return template('hello_user.html', name=name) # Calcul @route('/calcul///') def calcul(op, a, b): match op: case 'add': return f"resultat = {a + b}" case 'sub': return f"resultat = {a - b}" case 'mul': return f"resultat = {a * b}" case 'div': return f"resultat = {a / b}" case _: return "opérateur inconnu" # Table de multiplication @route('/tabmul/') def tabmul(nb): return template('tabmul.html', nb=nb) # Fichiers statiques @route('/static/') def server_static(filename): return static_file(filename, root=join(dirname(__file__), "static")) # Calculatrice @get('/calculatrice') def calculatrice(): # Protection de la page _, session, _ = get_or_create_session() if "user" not in session: return redirect("/login?next=/calculatrice") a = request.query.get('a', default=None) b = request.query.get('b', default=None) op = request.query.get('op', default=None) if a is None and b is None and op is None: # Aucune valeur saisie, on affiche le formulaire vide return template("calculatrice.html") try: a = float(a) b = float(b) except ValueError: # Erreur de conversion, on affiche le formulaire avec un message d'erreur return template("calculatrice.html", erreur="Les valeurs saisies ne sont pas des nombres.", a=a, b=b, op=op) match op: case "add": resultat = a + b case "sub": resultat = a - b case "mul": resultat = a * b case "div": if b == 0: return template("calculatrice.html", erreur="Division par zéro.", a=a, b=b, op=op) resultat = a / b case _: return template("calculatrice.html", erreur="Opération inconnue.", a=a, b=b, op=op) # Affichage du résultat return template("calculatrice.html", a=a, b=b, op=op, resultat=resultat) # Choix d'options pour une voiture OPTIONS = { "pmetal": { "titre": "Peinture métallisée", "prix": 500 }, "gps": { "titre": "GPS", "prix": 1000 }, "sieges": { "titre": "Sièges cuir", "prix": 1500 }, "toit": { "titre": "Toit ouvrant panoramique", "prix": 2000 }, "jantes": { "titre": "Jantes alliage", "prix": 400 } } @route('/mavoiture', method=['GET', 'POST']) def mavoiture(): if request.method == 'POST': # Récupération des options options = request.POST.getall('options') prix = 18000 for option in options: prix += OPTIONS[option]['prix'] return template("mavoiture.html", options=OPTIONS, selected=options, prix=prix) else: return template("mavoiture.html", options=OPTIONS, selected=[], prix=18000) # Compteur de visites @route('/compteur') def compteur(): # on récupère le cookie "compteur" (s'il existe) compteur = request.get_cookie("compteur") if compteur is None: # si le cookie n'existe pas, on l'initialise à 1 compteur = 1 else: # sinon, on l'incrémente de 1 compteur = int(compteur) + 1 # on crée ou met à jour le cookie "compteur" response.set_cookie("compteur", str(compteur), path="/compteur", httponly=True, max_age=None, expires=None) return f"Vous avez visité cette page {compteur} fois." # Enregistrement de messages dans une session @route('/messages', method=['GET', 'POST']) def messages(): # on récupère la session session_id, session, created = get_or_create_session() if request.method=="POST": # on récupère le message du formulaire message = request.forms.get('message') if message: # on ajoute le message à la session if "messages" not in session: session["messages"] = [] session["messages"].append(message) # on enregistre la session save_session(session_id, session) # on affiche les messages return template("messages.html", messages=session.get("messages", [])) # Authentification : page de login, gestion des utilisateurs et mots de passe def hash_password(password: str) -> str: """ Renvoie le hash sha256 du mot de passe. """ return hashlib.sha256(password.encode()).hexdigest() USERS = { "alice": { "nom": "Alice", "prenom": "Dupont", # évidement aucun intérêt ici d'avoir le hash si le mdp est dans le code # c'est juste pour l'exemple :) "password_hash": hash_password("password") }, "bob": { "nom": "Bob", "prenom": "Martin", # idem ! "password_hash": hash_password("supersecret") } } @route("/login", method=["GET", "POST"]) def login(): """ Authentifie l'utilisateur et crée une session. Reçoit le nom d'utilisateur et le mot de passe en POST. La page de redirection est spécifiée dans le paramètre "next" de l'URL. Rajouter un template et une logique pour afficher les erreurs. """ if request.method == "POST": # on récupère le nom d'utilisateur et le mot de passe username = request.forms.get("username") password = request.forms.get("password") next = request.query.get("next", "/") # on vérifie si l'utilisateur existe et si le mot de passe est correct if (username in USERS and USERS[username]["password_hash"] == hash_password(password)): # on crée une session pour l'utilisateur session_id, session_data, created = get_or_create_session() session_data["user"] = username session_data["nom"] = USERS[username]["nom"] session_data["prenom"] = USERS[username]["prenom"] save_session(session_id, session_data) return redirect(next) else: return template("login.html", username=username, password=password, erreur="Nom d'utilisateur ou mot de passe incorrect.") return template("login.html") @route("/logout", method=["GET", "POST"]) def logout(): """ Déconnecte l'utilisateur et détruit la session. """ if request.method == "POST": delete_session() return redirect("/") return template("logout.html") if __name__ == '__main__': run(host='localhost', port=38083, debug=True, reloader=True)