import os from datetime import datetime from flask import Flask, render_template from flask_login import LoginManager from flask_bcrypt import Bcrypt from flask_session import Session from flask_caching import Cache from flask_wtf.csrf import CSRFProtect from config import config # Inicialización de extensiones login_manager = LoginManager() login_manager.login_view = "auth.login" login_manager.login_message = "Por favor inicie sesión para acceder a esta página." login_manager.login_message_category = "warning" bcrypt = Bcrypt() csrf = CSRFProtect() session = Session() cache = Cache() def create_app(config_name=None): """Fábrica de aplicación Flask.""" if config_name is None: config_name = os.environ.get("FLASK_ENV", "default") app = Flask(__name__) app.config.from_object(config[config_name]) config[config_name].init_app(app) # Inicializar extensiones login_manager.init_app(app) bcrypt.init_app(app) csrf.init_app(app) session.init_app(app) cache.init_app(app) # Importar y registrar blueprints from routes.main_routes import main_bp from routes.auth_routes import auth_bp from routes.user_routes import users_bp from routes.project_routes import projects_bp from routes.document_routes import documents_bp from routes.schema_routes import schemas_bp from routes.admin_routes import admin_bp app.register_blueprint(main_bp) app.register_blueprint(auth_bp) app.register_blueprint(users_bp) app.register_blueprint(projects_bp) app.register_blueprint(documents_bp) app.register_blueprint(schemas_bp) app.register_blueprint(admin_bp) # Configurar cargador de usuario para Flask-Login from services.user_service import get_user_by_id @login_manager.user_loader def load_user(user_id): return get_user_by_id(user_id) # Registrar handlers para errores register_error_handlers(app) # Context processor para variables globales en templates @app.context_processor def inject_globals(): return {"now": datetime.now()} # Asegurar que existen los directorios de almacenamiento initialize_storage_structure(app) # Configurar sistema de logging from utils.logger import setup_logger setup_logger(app) # Inicializar datos por defecto with app.app_context(): # Inicializar usuario administrador si no existe from services.auth_service import initialize_admin_user initialize_admin_user() # Inicializar esquemas predeterminados si no existen from services.schema_service import initialize_default_schemas initialize_default_schemas() return app def register_error_handlers(app): """Registrar manejadores de errores para la aplicación.""" @app.errorhandler(404) def page_not_found(e): return ( render_template( "error.html", error_code=404, error_message="Página no encontrada" ), 404, ) @app.errorhandler(403) def forbidden(e): return ( render_template( "error.html", error_code=403, error_message="Acceso denegado" ), 403, ) @app.errorhandler(500) def internal_error(e): return ( render_template( "error.html", error_code=500, error_message="Error interno del servidor" ), 500, ) def initialize_storage_structure(app): """Crear estructura de almacenamiento si no existe.""" storage_path = app.config["STORAGE_PATH"] # Crear directorios principales os.makedirs(os.path.join(storage_path, "logs"), exist_ok=True) os.makedirs(os.path.join(storage_path, "schemas"), exist_ok=True) os.makedirs(os.path.join(storage_path, "users"), exist_ok=True) os.makedirs(os.path.join(storage_path, "filetypes"), exist_ok=True) os.makedirs(os.path.join(storage_path, "projects"), exist_ok=True) os.makedirs(os.path.join(storage_path, "exports"), exist_ok=True) # Inicializar archivos JSON si no existen init_json_file(os.path.join(storage_path, "schemas", "schema.json"), {}) init_json_file(os.path.join(storage_path, "users", "users.json"), {}) init_json_file(os.path.join(storage_path, "filetypes", "filetypes.json"), {}) init_json_file( os.path.join(storage_path, "indices.json"), {"max_project_id": 0, "max_document_id": 0}, ) def init_json_file(file_path, default_content): """Inicializar un archivo JSON si no existe.""" if not os.path.exists(file_path): import json with open(file_path, "w", encoding="utf-8") as f: json.dump(default_content, f, ensure_ascii=False, indent=2) if __name__ == "__main__": app = create_app() app.run(debug=True)