Code source du projet

CODE SOURCE

L'intégralité du code de l'application SmartLocker : backend Flask, scripts des casiers Raspberry Pi, templates et frontend. Les clés secrètes ont été retirées (voir config.example.py).

Tout télécharger (ZIP)
flask_app.py 100 lignes
  1# ==============================================================================
  2#  SMARTLOCKER -- POINT D'ENTREE DE L'APPLICATION FLASK
  3# ------------------------------------------------------------------------------
  4#  Ce fichier est volontairement court : il se contente de
  5#    1) creer l'application Flask et configurer la session / les cookies ;
  6#    2) enregistrer les "blueprints" (un par domaine fonctionnel) ;
  7#    3) declarer les gestionnaires d'erreurs globaux.
  8#
  9#  Tout le code metier a ete decoupe dans des modules dedies pour faciliter la
 10#  lecture et la maintenance :
 11#
 12#    extensions.py     -> connexions partagees (Firebase, Stripe) + alias config
 13#    helpers.py        -> fonctions utilitaires + decorateurs require_login/admin
 14#    routes_main.py    -> PWA, dashboard, scan, settings, photo de profil
 15#    routes_auth.py    -> login, signup, logout, connexion Google
 16#    routes_pairing.py -> appairage / dissociation des casiers, toggle Premium
 17#    routes_sport.py   -> casier Sport (reserve Premium)
 18#    routes_school.py  -> casier Ecole (reservation payante Stripe + webhook)
 19#    routes_api.py     -> API JSON, notifications, historique + export CSV, FCM
 20#    routes_admin.py   -> console d'administration
 21#
 22#  IMPORTANT (PythonAnywhere) : le fichier WSGI importe `app` depuis ce
 23#  module (`from flask_app import app`). On garde donc bien la variable
 24#  `app` exposee ici -- ne pas la renommer.
 25# ==============================================================================
 26
 27import os
 28from datetime import timedelta
 29
 30from flask import Flask
 31
 32import config
 33
 34# Les blueprints (un module = un domaine fonctionnel)
 35from routes_main    import main_bp
 36from routes_auth    import auth_bp
 37from routes_pairing import pairing_bp
 38from routes_sport   import sport_bp
 39from routes_school  import school_bp
 40from routes_api     import api_bp
 41from routes_admin   import admin_bp
 42
 43
 44# ==============================================================================
 45#  CREATION & CONFIGURATION DE L'APPLICATION
 46# ==============================================================================
 47
 48app = Flask(__name__)
 49app.secret_key = config.SECRET_KEY
 50
 51# Securite cookies de session
 52# SESSION_COOKIE_SECURE=True en production HTTPS (PythonAnywhere)
 53# Desactive automatiquement en debug (localhost http) via FLASK_ENV
 54_is_prod = os.environ.get('FLASK_ENV', 'production') != 'development'
 55app.config.update(
 56    SESSION_COOKIE_HTTPONLY=True,
 57    SESSION_COOKIE_SAMESITE='Lax',
 58    SESSION_COOKIE_SECURE=_is_prod,
 59    PERMANENT_SESSION_LIFETIME=timedelta(days=7),
 60    MAX_CONTENT_LENGTH=8 * 1024 * 1024,  # 8MB max upload (photos profil)
 61)
 62
 63
 64# ==============================================================================
 65#  ENREGISTREMENT DES BLUEPRINTS
 66# ==============================================================================
 67
 68app.register_blueprint(main_bp)
 69app.register_blueprint(auth_bp)
 70app.register_blueprint(pairing_bp)
 71app.register_blueprint(sport_bp)
 72app.register_blueprint(school_bp)
 73app.register_blueprint(api_bp)
 74app.register_blueprint(admin_bp)
 75
 76
 77# ==============================================================================
 78#  GESTIONNAIRES D'ERREURS
 79# ==============================================================================
 80
 81@app.errorhandler(403)
 82def forbidden(e):
 83    return ("<h1>403 -- Acces refuse</h1>"
 84            "<p>Vous n'avez pas les permissions pour acceder a cette page.</p>"
 85            "<a href='/'>Retour a l'accueil</a>"), 403
 86
 87
 88@app.errorhandler(404)
 89def not_found(e):
 90    return ("<h1>404 -- Page introuvable</h1>"
 91            "<p>La page demandee n'existe pas.</p>"
 92            "<a href='/'>Retour a l'accueil</a>"), 404
 93
 94
 95@app.errorhandler(500)
 96def server_error(e):
 97    print("[500] {}".format(e))
 98    return ("<h1>500 -- Erreur serveur</h1>"
 99            "<p>Une erreur interne est survenue. Reessayez plus tard.</p>"
100            "<a href='/'>Retour a l'accueil</a>"), 500