From 31df03f5877c0778289a54413bcebc6bd752bf7d Mon Sep 17 00:00:00 2001 From: lautarostuve Date: Mon, 9 Feb 2026 13:09:40 -0300 Subject: [PATCH 1/3] cambio para enviar el estado de la publicacion al front, y arreglar bug de archivado en mi perfil --- components/publicaciones/services.py | 1 + 1 file changed, 1 insertion(+) diff --git a/components/publicaciones/services.py b/components/publicaciones/services.py index 8f9b2ab..009cb1f 100644 --- a/components/publicaciones/services.py +++ b/components/publicaciones/services.py @@ -37,6 +37,7 @@ def serializar_publicacion_lista(pub): "etiquetas": [et.nombre for et in pub.etiquetas], "fecha_creacion": pub.fecha_creacion.astimezone(zona_arg).isoformat() if pub.fecha_creacion else None, "coordenadas": pub.coordenadas, + "estado": pub.estado, # No enviamos descripción completa para ahorrar datos en listas } From ac6e9fe3b0ec8c86e0a0e80844d24540e2ad5846 Mon Sep 17 00:00:00 2001 From: lautarostuve Date: Thu, 12 Feb 2026 16:56:18 -0300 Subject: [PATCH 2/3] Cambio para ejecutar diariamente a las 3am un proceso para archivar publicaciones con mas de 6 meses de antiguedad. Se le envia una notificacion al usuario. --- app.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++- requirements.txt | Bin 3950 -> 4206 bytes 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index 07cf717..4ba3ec0 100644 --- a/app.py +++ b/app.py @@ -15,6 +15,9 @@ # 1. IMPORTANTE: Importar ProxyFix para Google Cloud Run/Render from werkzeug.middleware.proxy_fix import ProxyFix +from flask_apscheduler import APScheduler +from sqlalchemy import text + # Imports de modelos y rutas from core.models import db, Usuario from auth.routes import auth_bp @@ -33,6 +36,8 @@ from components.funcionesAdmin.routes import admin_bp from components.categorias.routes import categorias_bp from components.contactos.routes import contactos_bp +from core.models import db, Usuario, Notificacion +from datetime import datetime, timezone from dotenv import load_dotenv import firebase_admin @@ -51,6 +56,11 @@ x_prefix=1 ) + +app.config['SCHEDULER_API_ENABLED'] = True +scheduler = APScheduler() + + def cerrar_sesion(): """ Cierra la sesión de base de datos de forma segura. @@ -145,6 +155,62 @@ def handle_options(): headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, PATCH, DELETE, OPTIONS" return resp -# MAIN: Usamos app.run estándar (Flask puro) en lugar de socketio.run +def tarea_archivar_publicaciones(): + with app.app_context(): + try: + print(f"[{datetime.now()}] Iniciando proceso de archivado...") + sql_query = text(""" + UPDATE publicaciones + SET estado = 1 + WHERE estado = 0 + AND fecha_creacion < NOW() - INTERVAL '6 months' + RETURNING id, id_usuario, titulo + """) + + result = db.session.execute(sql_query) + archivos_procesados = result.fetchall() + if archivos_procesados: + print(f"Se encontraron {len(archivos_procesados)} publicaciones para archivar.") + + for pub in archivos_procesados: + p_id = pub.id + p_usuario = pub.id_usuario + p_titulo = pub.titulo + + nueva_noti = Notificacion( + id_usuario=p_usuario, + titulo='Publicación Archivada', + descripcion=f'Tu publicación "{p_titulo}" ha sido archivada automáticamente por inactividad (6 meses). Puedes desarchivarla desde tu perfil.', + tipo='sistema', + fecha_creacion=datetime.now(timezone.utc), + leido=False, + id_publicacion=p_id, + id_referencia=None + ) + db.session.add(nueva_noti) + + db.session.commit() + print(f"ÉXITO: {len(archivos_procesados)} publicaciones archivadas y usuarios notificados.") + + else: + # Si no hay nada que archivar, hacemos commit igual para cerrar la transacción limpia + db.session.commit() + print("Sin cambios: No hay publicaciones antiguas pendientes.") + + except Exception as e: + print(f"ERROR CRÍTICO en tarea programada: {e}") + db.session.rollback() # Deshace todo si algo falla + + if __name__ == '__main__': + scheduler.init_app(app) + scheduler.start() + scheduler.add_job( + id='archivar_job', + func=tarea_archivar_publicaciones, + trigger='cron', + hour=3, + minute=0 + ) + app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 4b438d3ea754bd2b926272d3a835d681408a8a0f..e5db4a1dfc1f8bcd3ddf9325cd7c4a710b717709 100644 GIT binary patch delta 243 zcmaDS_fBC#k*Xs@07EcCGD8MKDnklGDMJpBE@H3+LSqI!216j!V=&s7yPIk93T7Tf z+^Rw93>l0!%QI&(OQ!=3%45g`8k-L^EDvm)5!gV3&Gl>-S=195N`Us10?ACEjUd~M zfch7K&MTf%6Ah0ElMqW delta 35 rcmaE-@J?<*(Z)I3m^ODXCopg3VL!pLS%AlZnbnj*kHKK_RQ{U)`s@r3 From 72ff7a41d885b6e8a520aa57ca40629c13a5a5eb Mon Sep 17 00:00:00 2001 From: lautarostuve Date: Thu, 12 Feb 2026 17:14:53 -0300 Subject: [PATCH 3/3] ahora el archivador automatico controla la fecha de modificacion y no la de creacion. --- app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.py b/app.py index 4ba3ec0..40ab09a 100644 --- a/app.py +++ b/app.py @@ -163,7 +163,7 @@ def tarea_archivar_publicaciones(): UPDATE publicaciones SET estado = 1 WHERE estado = 0 - AND fecha_creacion < NOW() - INTERVAL '6 months' + AND COALESCE(fecha_modificacion, fecha_creacion) < NOW() - INTERVAL '6 months' RETURNING id, id_usuario, titulo """)