from flask import Flask, render_template, request, redirect, url_for, flash, session from src.models import db, User, Paste from src.routes import init_routes from src.auth import jwt_required from config import SQLALCHEMY_DATABASE_URI, SQLALCHEMY_ENGINE_OPTIONS from werkzeug.security import generate_password_hash from sqlalchemy.exc import IntegrityError import os from flask_login import LoginManager, login_user, current_user, logout_user, login_required from werkzeug.middleware.proxy_fix import ProxyFix import logging from config import UPLOAD_FOLDER from flask_migrate import Migrate from flask_apscheduler import APScheduler from src.routes import delete_expired_pastes from elasticsearch import Elasticsearch # Inicializa la aplicación Flask app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_ENGINE_OPTIONS'] = SQLALCHEMY_ENGINE_OPTIONS app.secret_key = 'admin_console_secret_key' app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # Inicializa la base de datos db.init_app(app) migrate = Migrate(app, db) # Inicializa Flask-Login login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'login' login_manager.login_message_category = 'info' # Cargador de usuario para Flask-Login @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) # Asegúrate de que la ruta de importación sea correcta # Conexión con Elasticsearch es = Elasticsearch(["http://elasticsearch:9200"]) def create_paste_index(): """ Crea el índice 'pastes' en Elasticsearch si no existe. """ index_name = "pastes" mappings = { "mappings": { "properties": { "id": { "type": "keyword" }, "title": { "type": "text" }, "content": { "type": "text" }, "owner_id": { "type": "keyword" }, "language": { "type": "keyword" }, "content_type": { "type": "keyword" }, "created_at": { "type": "date" }, "private": { "type": "boolean" }, "shared_with": { "type": "keyword" } # ✅ Se deja sin `ignore_above` para múltiples valores } } } # Eliminar índice si ya existe (para evitar conflictos) if es.indices.exists(index=index_name): es.indices.delete(index=index_name) print(f"[INFO] Índice '{index_name}' eliminado antes de la recreación.") # Crear el índice con la nueva estructura es.indices.create(index=index_name, body=mappings) print(f"[INFO] Índice '{index_name}' creado correctamente en Elasticsearch.") # Ejecuta la creación del índice en el contexto de la app with app.app_context(): db.create_all() create_paste_index() # 📌 Aquí se crea el índice antes de inicializar las rutas default_username = os.getenv("VALID_USER", "admin") default_password = os.getenv("VALID_PASS", "password123") try: if not User.query.filter_by(username=default_username).first(): user = User(username=default_username) user.set_password(default_password) db.session.add(user) db.session.commit() print(f"Usuario por defecto creado: {default_username}") else: print(f"Usuario por defecto ya existe: {default_username}") except IntegrityError: db.session.rollback() print("Usuario admin ya existía. Continuando...") # Inicializar rutas init_routes(app) scheduler = APScheduler() def delete_expired_pastes_task(): """Ejecuta la limpieza de pastes expirados dentro del contexto de Flask""" with app.app_context(): delete_expired_pastes() def setup_scheduler(app): """Configura y arranca el scheduler""" scheduler.init_app(app) scheduler.start() scheduler.add_job(id='delete_expired_pastes', func=delete_expired_pastes_task, trigger='interval', hours=1) setup_scheduler(app) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000)