Files
admin-edu-space/app/__init__.py
T

122 lines
4.9 KiB
Python

from flask import Flask, request, session
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_cors import CORS
from flask_babel import Babel, gettext as _
from config.config import Config
# Initialize extensions
db = SQLAlchemy()
migrate = Migrate()
login_manager = LoginManager()
cors = CORS()
babel = Babel()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# Initialize extensions with app
db.init_app(app)
migrate.init_app(app, db)
login_manager.init_app(app)
cors.init_app(app)
# Login manager configuration
login_manager.login_view = 'auth.login'
login_manager.login_message = 'Por favor inicia sesión para acceder a esta página.'
login_manager.login_message_category = 'info'
# Import models to ensure they are registered
from app.models import user
# Register blueprints
from app.routes import auth_bp, classrooms_bp, buildings_bp, main_bp, schedule_bp, genetic_bp, genetic_web_bp, admin_bp
from app.routes.api import api_auth_bp, api_classrooms_bp, api_reservations_bp
from app.security import SecurityFilterChain
app.register_blueprint(auth_bp, url_prefix="/")
app.register_blueprint(classrooms_bp, url_prefix="/classrooms")
app.register_blueprint(buildings_bp)
app.register_blueprint(main_bp, url_prefix="/")
app.register_blueprint(schedule_bp, url_prefix="/schedule")
app.register_blueprint(genetic_bp)
app.register_blueprint(genetic_web_bp)
app.register_blueprint(admin_bp)
# Register REST API (v1) Blueprints with Stateless JWT support
app.register_blueprint(api_auth_bp)
app.register_blueprint(api_classrooms_bp)
app.register_blueprint(api_reservations_bp)
# Initialize Enterprise Security Pipeline (SecurityFilterChain)
SecurityFilterChain(app)
# Language selector function
def get_locale():
# 1. Parámetro explícito en la URL (?lang=es o ?lang=en)
lang = request.args.get('lang')
if lang and lang in app.config['LANGUAGES']:
session['language'] = lang
return lang
# 2. Si el usuario está autenticado y tiene idioma configurado en su perfil, prevalece en toda la sesión
from flask_login import current_user
if current_user.is_authenticated and getattr(current_user, 'preferred_language', None):
if current_user.preferred_language in app.config['LANGUAGES']:
return current_user.preferred_language
# 3. En la pantalla de Login (usuario no autenticado):
# El idioma predeterminado del login debe ser español o respetar el idioma del navegador.
# No debe verse afectado por cookies o sesiones residuales de otros usuarios.
is_login = (request.endpoint == 'auth.login' or request.path.rstrip('/') == '/login')
if is_login:
# Solo si el usuario cambió el idioma explícitamente en el selector del login
if session.get('login_lang_explicit') in app.config['LANGUAGES']:
return session['login_lang_explicit']
# Detectar según el navegador del usuario (soporta es-419, es-AR, es-ES, etc.)
if request.accept_languages:
for accepted_lang, _quality in request.accept_languages:
primary = accepted_lang.split('-')[0].lower()
if primary in app.config['LANGUAGES']:
return primary
# Idioma predeterminado por defecto del login: Español
return 'es'
# 4. Para otras rutas: verificar si hay idioma en sesión (ej. selector manual)
if 'language' in session and session['language'] in app.config['LANGUAGES']:
return session['language']
# 5. Detección automática del navegador por defecto (soporta subtags regionales)
if request.accept_languages:
for accepted_lang, _quality in request.accept_languages:
primary = accepted_lang.split('-')[0].lower()
if primary in app.config['LANGUAGES']:
return primary
# Fallback del sistema: Español
return app.config['BABEL_DEFAULT_LOCALE']
# Babel context processor
@app.context_processor
def inject_conf_vars():
return dict(
languages=app.config['LANGUAGES'],
current_lang=str(get_locale())
)
# Configure Babel
babel.init_app(app, locale_selector=get_locale)
# Register localized date and datetime formatters for Jinja2 templates
from flask_babel import format_date, format_datetime
app.jinja_env.globals['format_date'] = format_date
app.jinja_env.globals['format_datetime'] = format_datetime
app.jinja_env.filters['format_date'] = format_date
app.jinja_env.filters['format_datetime'] = format_datetime
return app